Jak cofnąć ostatnie dodawanie git?

193

Czy można cofnąć scenę ostatniej zmiany (bez zatwierdzenia) w git ? Załóżmy, że w bieżącej gałęzi było dużo plików, niektóre z nich zostały ustawione, inne nie. W pewnym momencie jakiś głupi programista przypadkowo wykonał:

git add -- .

...zamiast:

git checkout -- .

Czy ten programista może teraz wprowadzić swoje ostatnie zmiany za pomocą jakiegoś magicznego polecenia git ? A może powinien był popełnić to przed eksperymentowaniem?

Septagram
źródło
Heh Otrzymaliśmy z tego użyteczne pytanie i odpowiedź.
steveha
2
możliwy duplikat cofnięcia „git add” przed zatwierdzeniem
Jim Fell
Wierzę, że to nie jest duplikat. OP w drugim pytaniu prosi o sposób, aby to cofnąć lub usunąć te pliki z zatwierdzenia. Chcę (ed) dokładnie i tylko cofnąć zmiany, które zostały dodane za pomocą ostatniego git addpolecenia, szczególnie dla plików, które już miały zmiany etapowe i miały pewne zmiany, które miały zostać cofnięte, a nie etapowe. Nie mogę powiedzieć, że drugie pytanie nie jest powiązane.
Septagram
1
Być może powinien był / był / popełniony przed eksperymentowaniem.
android.weasel
@ android.weasel tak, to było wiele lat temu ...
Septagram

Odpowiedzi:

299

Możesz użyć git reset. Spowoduje to „wycofanie ze sceny” wszystkich plików dodanych po ostatnim zatwierdzeniu.

Jeśli chcesz cofnąć scenę tylko z niektórych plików, użyj git reset -- <file 1> <file 2> <file n>.

Możliwe jest również wycofanie niektórych zmian w plikach za pomocą git reset -p.

Thameera
źródło
3
Jak smutno. Wydaje mi się jednak, że w moich praktykach popełniania błędów dzieje się coś złego. Zaakceptowanie tej odpowiedzi, ponieważ wspomniałeś o -pprzełączniku. Dzięki! :)
Septagram
Generuje (dla mnie) błąd: krytyczny: nie można rozpoznać „HEAD” jako prawidłowego numeru referencyjnego. Nie popełniłem jeszcze niczego (nowe repo) właśnie zrobiłem git add. i żałowałem tego. Nie chcę resetować całego dodania, tylko jeden katalog. git reset - katalog /*.* generuje powyższy błąd.
Francis Davey
... Ach, widzę, co się dla mnie dzieje. Nie miałem jeszcze nic, na co mógłby wskazywać HEAD, więc reset git nie powiódł się (ponieważ działa na HEAD).
Francis Davey
42

Nie możesz cofnąć ostatniego dodania git, ale możesz cofnąć wszystkie adds od ostatniego zatwierdzenia. git resetbez argumentu zatwierdzenia resetuje indeks (zmiany etapowe etapowe):

git reset
knittl
źródło
2
„Nie można cofnąć ostatniego dodania git”: Wow, to zaskakujące i potencjalnie bolesne. Czy jest na to ostateczne źródło? Czy jest też dobry powód, aby tak być? Dzięki!
Andrew Moylan,
@AndrewMoylan: cóż, nie ma na to automatycznego sposobu. Zawsze możesz resetużyć pojedynczego pliku lub użyć reset -pdo cofnięcia sceny określonego przystojniaka.
knittl
15

Tak więc prawdziwa odpowiedź na

Czy ten programista może teraz wprowadzić swoje ostatnie zmiany za pomocą jakiegoś magicznego polecenia git?

jest w rzeczywistości: Nie, nie można oderwać się od ostatniego git add.

To znaczy, jeśli interpretujemy to pytanie w następujący sposób:

Plik początkowy:

void foo() {

}

main() {
    foo();
}

Pierwsza zmiana, po której następuje git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Druga zmiana, po której następuje git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

W tym przypadku git reset -pnie pomoże, ponieważ jego najmniejszą ziarnistością są linie. gitnie wie tego o stanie pośrednim:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

już więcej.

stanm
źródło
Podobało mi się, ponieważ jako nowy użytkownik git jest to bardzo ważne rozróżnienie, które podkreśla to, co moi przyjaciele opisują jako „dobrą higienę podczas meldowania się” ... moje osobiste doświadczenie - zostało to określone jako „carpooling” (źle!).
benc
6

Możesz użyć git reset(zobacz dokumenty )

Dawidowie
źródło
3

W dniu git wyświetla się monit:

  1. use "git rm --cached <file>..." to unstagejeśli pliki nie były w repozytorium. Odsłania pliki, zatrzymując je tam.
  2. use "git reset HEAD <file>..." to unstagejeśli pliki były w repozytorium i dodajesz je jako zmodyfikowane. Utrzymuje pliki takimi, jakie są i rozplanowuje je.

O ile mi wiadomo, nie można cofnąć, git add --ale można wycofać listę plików, jak wspomniano powyżej.

theGiallo
źródło
2
  • Usuń plik z indeksu, ale zachowaj jego wersję i pozostaw niezatwierdzone zmiany w kopii roboczej:

    git reset head <file>
    
  • Zresetuj plik do ostatniego stanu z poziomu HEAD, cofając zmiany i usuwając je z indeksu:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Jest to potrzebne, ponieważ git reset --hard HEADnie działa z pojedynczymi plikami.

  • Usuń <file>z indeksu i wersji, zachowując niewersjonowany plik ze zmianami w kopii roboczej:

    git rm --cached <file>
    
  • <file>Całkowicie usuń z kopii roboczej i wersji:

    git rm <file>
    
Faisal
źródło
2

Jeśli chcesz usunąć wszystkie dodane pliki z git do zatwierdzenia

git reset

Jeśli chcesz usunąć pojedynczy plik

git rm <file>
BSB
źródło
1

Możesz użyć

git reset

aby cofnąć ostatnio dodane pliki lokalne

 git reset file_name

aby cofnąć zmiany dla określonego pliku

ireshika piyumalie
źródło
0

W zależności od wielkości i skali trudno, możesz utworzyć gałąź scratch (tymczasową) i tam wykonać bieżącą pracę.

Następnie przejdź do oryginalnej gałęzi i sprawdź ją, a następnie wybierz odpowiednie pliki z zatwierdzenia scratch.

Przynajmniej miałbyś stały zapis aktualnych i poprzednich stanów do pracy (do momentu usunięcia tej gałęzi scratch).

Philip Oakley
źródło