Jak cofnąć ostatnie zatwierdzenia lokalne w Git?

21046

Przypadkowo przesłałem niewłaściwe pliki do Git , ale jeszcze nie wysłałem zatwierdzenia na serwer.

Jak mogę cofnąć te zatwierdzenia z lokalnego repozytorium?

Peter Mortensen
źródło
137
Zanim opublikujesz nową odpowiedź, zastanów się, czy istnieje już ponad 65 odpowiedzi na to pytanie. Upewnij się, że twoja odpowiedź przyczynia się do tego, czego nie ma wśród odpowiedzi istniejących.
Sazzad Hissain Khan
89
Wiesz czego potrzebuje git? git undo, Otóż to. Wtedy git ma reputację za radzenie sobie z błędami popełnianymi przez nas, zwykli śmiertelnicy znika. Zaimplementuj, wypychając bieżący stan na stos git przed wykonaniem jakiegokolwiek gitpolecenia. Wpłynęłoby to na wydajność, więc najlepiej byłoby dodać flagę config, aby włączyć.
Yimin Rong,
11
@YiminRong Można tego dokonać za pomocą aliasfunkcji Gita : git-scm.com/book/en/v2/Git-Basics-Git-Aliases
Edric
3
@RainainValeri - Ta sama metoda cofania działa wszędzie indziej.
Yimin Rong
1
@YiminRong Nie kupuję tego. Ludzie wciąż się grzebią i rozwiązują rzeczy, których nie można cofnąć. Ale co ważniejsze, git reflogjest już blisko tego, co opisujesz, ale daje użytkownikowi większą kontrolę nad tym, co należy (nie) zrobić. Ale proszę, nie, „cofnij” nie działa wszędzie tak samo, a ludzie oczekiwaliby wielu różnych rzeczy do osiągnięcia przez tę funkcję. Cofnąć ostatnie zatwierdzenie? Cofnąć ostatnią akcję? Jeśli ostatnią czynnością było push, cofnij jak dokładnie (reset i push) lub (cofnij i push)?
RomainValeri

Odpowiedzi:

22848

Cofnij zatwierdzenie i ponów

$ git commit -m "Something terribly misguided"             # (1)
$ git reset HEAD~                                          # (2)
<< edit files as necessary >>                              # (3)
$ git add ...                                              # (4)
$ git commit -c ORIG_HEAD                                  # (5)
  1. To chcesz cofnąć.
  2. Nie robi to nic w twoim drzewie roboczym (stanie twoich plików na dysku), ale cofa zatwierdzenie i pozostawia zmiany, które popełniłeś bez zmian (więc pojawią się one jako „Zmiany, które nie zostały wprowadzone do zatwierdzenia” git status, więc musisz dodaj je ponownie przed zatwierdzeniem). Jeśli tylko chcesz dodać więcej zmian do poprzedniego popełnić, lub zmienić popełnić wiadomość 1 , można użyć git reset --soft HEAD~zamiast tego, który jest jak git reset HEAD~2 , ale pozostawia istniejące zmiany wystawił.
  3. Wprowadź poprawki do działających plików drzewa.
  4. git add wszystko, co chcesz dołączyć do nowego zatwierdzenia.
  5. Zatwierdź zmiany, ponownie wykorzystując stary komunikat zatwierdzenia. resetskopiował starą głowę .git/ORIG_HEAD; commitza pomocą -c ORIG_HEADotworzy edytor, który początkowo zawiera komunikat dziennika ze starego zatwierdzenia i pozwala go edytować. Jeśli nie musisz edytować wiadomości, możesz skorzystać z tej -Copcji.

Pamiętaj jednak, że jeśli dodałeś jakieś nowe zmiany do indeksu, użycie commit --amendspowoduje dodanie ich do poprzedniego zatwierdzenia.

Jeśli kod został już przesłany na Twój serwer i masz uprawnienia do zastąpienia historii (rebase), to:

git push origin master --force

Możesz także spojrzeć na tę odpowiedź:

Jak mogę przenieść HEAD z powrotem do poprzedniej lokalizacji? (Odłączona głowa) i Cofnij zatwierdza

Powyższa odpowiedź pokaże, git reflog,który służy do ustalenia, czym jest SHA-1, który chcesz cofnąć. Po znalezieniu punktu, do którego chcesz cofnąć, użyj sekwencji poleceń, jak wyjaśniono powyżej.


1 Pamiętaj jednak, że nie musisz resetować do wcześniejszego zatwierdzenia, jeśli popełniłeś błąd w komunikacie zatwierdzenia . git resetNajłatwiejszą opcją jest (aby odetrzeć wszelkie zmiany, które wprowadziłeś od tego czasu), a następnie git commit --amend, który otworzy domyślny edytor komunikatów zatwierdzania wypełniony ostatnią wiadomością zatwierdzenia.

2 HEAD~ to to samo co HEAD~1. Zobacz także Co to jest HEAD w git? . Jest to przydatne, jeśli chcesz anulować wiele zatwierdzeń.

Mark Amery
źródło
472
A jeśli zatwierdzenie było w niewłaściwej gałęzi, możesz git checkout theRightBranchze wszystkimi etapami zmian. Tak jak musiałem to zrobić.
Frank Shearar,
489
Jeśli pracujesz w systemie DOS, zamiast tego git reset --soft HEAD^musisz użyć git reset --soft HEAD~1. ^ To znak kontynuacji w DOS, więc nie będzie działał poprawnie. Ponadto, --softjest domyślne, dzięki czemu można go pominąć, jeśli chcesz i po prostu powiedzieć git reset HEAD~1.
Ryan Lundy
119
Użytkownicy zsh mogą otrzymać: zsh: no matches found: HEAD^- musisz uciec ^ iegit reset --soft HEAD\^
tnajdek
7
Odpowiedź jest nieprawidłowa, jeśli powiedzmy przypadkowo, git commit -agdy -azostała pominięta. W takim przypadku lepiej nie pomijać --soft(co spowoduje, że będzie --mixedto ustawienie domyślne), a następnie możesz zrezygnować ze zmian, które chciałeś zatwierdzić.
dmansfield
6
@IcyBrk git add to polecenie. git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--chmod=(+|-)x] [--] [<pathspec>…​]
Ashraf.Shk786,
10729

Cofanie zatwierdzenia jest trochę przerażające, jeśli nie wiesz, jak to działa. Ale to naprawdę niezwykle proste, jeśli rozumiesz.

Powiedzmy, że masz to, gdzie C to HEAD, a (F) to stan twoich plików.

   (F)
A-B-C
    ↑
  master

Chcesz nuke zatwierdzić C i nigdy więcej go nie widzieć i stracić wszystkie zmiany w lokalnie zmodyfikowanych plikach . Robisz to:

git reset --hard HEAD~1

Wynik to:

 (F)
A-B
  ↑
master

Teraz B jest GŁOWĄ. Ponieważ użyłeś --hard, twoje pliki są resetowane do stanu w zatwierdzeniu B.

Ach, ale załóżmy, że popełnienie C nie było katastrofą, ale tylko odrobiną. Chcesz cofnąć zatwierdzenie, ale zachowaj zmiany w celu trochę edycji przed wykonaniem lepszego zatwierdzenia. Zaczynając odtąd od nowa, z C jako GŁOWĄ:

   (F)
A-B-C
    ↑
  master

Możesz to zrobić, pomijając --hard:

git reset HEAD~1

W takim przypadku wynikiem jest:

   (F)
A-B-C
  ↑
master

W obu przypadkach HEAD jest tylko wskaźnikiem do ostatniego zatwierdzenia. Kiedy zrobisz a git reset HEAD~1, każesz Gitowi przesunąć wskaźnik HEAD do tyłu o jeden zatwierdzenie. Ale (chyba że używasz --hard) pozostawiasz swoje pliki takie, jakie były. Teraz git statuspokazuje zmiany, które zameldowałeś w C. Nic nie straciłeś!

Dla najlżejszego dotyku możesz nawet cofnąć zatwierdzenie, ale zostawić swoje pliki i indeks :

git reset --soft HEAD~1

To nie tylko pozostawia pliki w spokoju, ale nawet sam indeks . Gdy to zrobisz git status, zobaczysz, że te same pliki znajdują się w indeksie jak poprzednio. W rzeczywistości, zaraz po tym poleceniu, możesz to zrobić git commiti będziesz powtarzać to samo zatwierdzenie, które właśnie wykonałeś.

Jeszcze jedno: Załóżmy, że niszczysz zatwierdzenie jak w pierwszym przykładzie, ale potem odkryłeś, że w końcu go potrzebujesz ? Pech, prawda?

Nie, wciąż istnieje sposób na odzyskanie go. Wpisz, git refloga zobaczysz listę (częściowych) zatwierdzeń shas (czyli skrótów ), w których się przeprowadzałeś. Znajdź zniszczone zatwierdzenie i zrób to:

git checkout -b someNewBranchName shaYouDestroyed

Wskrzesiłeś to zatwierdzenie. Zobowiązania w rzeczywistości nie są niszczone w Git przez około 90 dni, więc zazwyczaj możesz wrócić i uratować jeden, którego nie chciałeś się pozbyć.

Ryan Lundy
źródło
15
STRZEC SIĘ! Może to nie zrobić tego, czego oczekujesz, jeśli twoje błędne zatwierdzenie było połączeniem (szybkie przewijanie do przodu)! Jeśli twoja głowa jest na zatwierdzeniu scalania (np. Scalona gałąź w master), git reset --hard~1skieruje gałąź master do ostatniego zatwierdzenia w gałęzi feature. W takim przypadku zamiast polecenia względnego należy użyć konkretnego identyfikatora zatwierdzenia.
Chris Kerekes
90
Brak kluczowego punktu: jeśli wspomniane zatwierdzenie zostało wcześniej „wypchnięte” do pilota, każda operacja „cofnij”, bez względu na to, jak prosta, spowoduje ogromny ból i cierpienie dla reszty użytkowników, którzy mają to zatwierdzenie w swojej lokalnej kopii, kiedy zrobią „git pull” w przyszłości. Więc jeśli zatwierdzenie zostało już „wypchnięte”, zrób to zamiast tego: git revert <bad-commit-sha1-id> git push origin:
FractalSpace
12
@FractalSpace, nie spowoduje „ogromnego bólu i cierpienia”. Wykonałem kilka nacisków siły, używając Git z zespołem. Wystarczy komunikacja.
Ryan Lundy,
14
@ Kyralessa W moim miejscu pracy zepsucie pracy całego zespołu, a następnie powiedzenie im, jak naprawić sh * t, nie nazywa się „komunikacją”. Ponowne zapisywanie historii git jest destrukcyjną operacją, która powoduje zniszczenie części repo. Naleganie na jego użycie, podczas gdy dostępne są jasne i bezpieczne alternatywy, jest po prostu nieodpowiedzialne.
FractalSpace
14
Chciałem zniszczyć zatwierdzenie i nigdy więcej go nie zobaczę. Użyłem twojego przykładu, --hardale nie zdawałem sobie sprawy, że wszystkie moje nieustawione zmiany w moim drzewie roboczym również zostały zniszczone! Zamierzałem zatwierdzić te pliki w ramach późniejszego zatwierdzenia. Teraz odzyskanie tych plików wydaje się niemożliwe - próbowałem nawet rozwiązania, o którym napisałeś, reflogale nie przywróciło to wcześniej nieustawionych zmian.
Adam Burley
2129

Istnieją dwa sposoby „cofnięcia” ostatniego zatwierdzenia, w zależności od tego, czy opublikowałeś już swoje zatwierdzenie (przekazane do zdalnego repozytorium):

Jak cofnąć zatwierdzenie lokalne

Powiedzmy, że popełniłem lokalnie, ale teraz chcę usunąć to zatwierdzenie.

git log
    commit 101: bad commit    # Latest commit. This would be called 'HEAD'.
    commit 100: good commit   # Second to last commit. This is the one we want.

Aby przywrócić wszystko do stanu sprzed ostatniego zatwierdzenia, musimy resetwykonać zatwierdzenie przed HEAD:

git reset --soft HEAD^     # Use --soft if you want to keep your changes
git reset --hard HEAD^     # Use --hard if you don't care about keeping the changes you made

Teraz git logpokaże, że nasze ostatnie zatwierdzenie zostało usunięte.

Jak cofnąć publiczne zatwierdzenie

Jeśli już opublikowałeś swoje zatwierdzenia, będziesz chciał utworzyć nowe zatwierdzenie, które „cofnie” zmiany, które wprowadziłeś w poprzednim zatwierdzeniu (bieżący HEAD).

git revert HEAD

Twoje zmiany zostaną teraz przywrócone i będą gotowe do zatwierdzenia:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

Aby uzyskać więcej informacji, zobacz Git Basics - Undoing Things .

Andrzej
źródło
101
Uznałem tę odpowiedź za najbardziej zrozumiałą. git revert HEAD^nie jest poprzedni, jest poprzedni z poprzednich. Zrobiłem: git revert HEADa potem ponownie
nacisnąłem
Jeśli Git zapyta „Więcej?” kiedy wypróbujesz te polecenia, użyj alternatywnej składni tej odpowiedzi: stackoverflow.com/a/14204318/823470
tar
1745

Dodaj / usuń pliki, aby uzyskać pożądany efekt:

git rm classdir
git add sourcedir

Następnie zmień zatwierdzenie:

git commit --amend

Poprzednie, błędne zatwierdzenie zostanie edytowane w celu odzwierciedlenia nowego stanu indeksu - innymi słowy, będzie tak, jakbyś nigdy nie popełnił błędu.

Pamiętaj, że powinieneś to zrobić tylko wtedy, gdy jeszcze nie naciskałeś. Jeśli nacisnąłeś, musisz po prostu naprawić normalnie.

bdonlan
źródło
2
FYI: To usuwa wszystkie moje pliki i straciłem zmiany.
egorlitvinenko
UPD: Jednak przywróciłem go za pomocą reflog. Ale pokwitowanie nie zadziałało przy pierwszym zatwierdzeniu.
egorlitvinenko
1
Służy git rm --cacheddo przechowywania plików w systemie plików i usuwania ich tylko z indeksu git!
xuiqzy
1015
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

lub

git reset --hard HEAD~1

Ostrzeżenie: powyższe polecenie spowoduje trwałe usunięcie modyfikacji .javaplików (i wszelkich innych plików), które chcesz zatwierdzić.

hard resetAby HEAD-1ustawi swoją kopię roboczą do stanu popełnić zanim źle popełnić.

Lennart Koopmann
źródło
19
git commit -a -m ""lub git commit -am ""naturalnie! :]
trejder
Kolejne „skrótowe” użycie skrytki; jeśli chcesz unstage wszystkiego (Cofnij git ADD), po prostu git stash, a następniegit stash pop
seanriordan08
778

Aby zmienić ostatnie zatwierdzenie

Zamień pliki w indeksie:

git rm --cached *.class
git add *.java

Następnie, jeśli jest to oddział prywatny, zmień zatwierdzenie:

git commit --amend

Lub, jeśli jest to gałąź współdzielona, ​​dokonaj nowego zatwierdzenia:

git commit -m 'Replace .class files with .java files'


( Aby zmienić poprzednie zatwierdzenie , użyj niesamowitej interaktywnej bazy .)


ProTip ™: Dodaj *.classdo gitignore, aby przestało się to powtarzać.


Aby cofnąć zatwierdzenie

Zmiana zatwierdzenia jest idealnym rozwiązaniem, jeśli chcesz zmienić ostatnie zatwierdzenie, ale bardziej ogólne jest rozwiązanie reset.

Możesz zresetować Git do dowolnego zatwierdzenia za pomocą:

git reset @~N

Gdzie Njest liczba wcześniejszych zatwierdzeń HEADi @~resetuje się do poprzedniego zatwierdzenia.

Zamiast zmiany zatwierdzenia możesz użyć:

git reset @~
git add *.java
git commit -m "Add .java files"

Sprawdź git help reset, w szczególności sekcje --soft --mixedi --hard, aby lepiej zrozumieć, co to robi.

Zarejestruj się

Jeśli się zepsujesz, zawsze możesz użyć dziennika, aby znaleźć odrzucone zatwierdzenia:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started


Zaz
źródło
2
Dla osób czytających w przyszłości - należy pamiętać, że git revertjest to osobne polecenie - które w zasadzie „resetuje” pojedyncze polecenie.
BKSpurgeon
680

Zastosowanie git revert <commit-id>.

Aby uzyskać identyfikator zatwierdzenia, po prostu użyj git log.

Jaco Pretorius
źródło
15
Co to znaczy, wiśnia wybrać zatwierdzenie? W moim przypadku podczas edycji pliku byłem w niewłaściwej gałęzi. Popełniłem to, a potem zdałem sobie sprawę, że jestem w złym oddziale. Użycie „git reset --soft HEAD ~ 1” sprawiło, że wróciłem tuż przed zatwierdzeniem, ale teraz, jeśli sprawdzę poprawną gałąź, w jaki sposób mogę cofnąć zmiany w pliku w niewłaściwej gałęzi, ale zamiast tego zrobić je (w tej samej nazwie plik) we właściwej gałęzi?
astronomerdave
Właśnie wykorzystałem git revert commit-iddziałał jak urok. Oczywiście wtedy będziesz musiał wprowadzić zmiany.
Casey Robinson
8
Wierzę, że byłby to git cherry-pick <<erroneous-commit-sha>>@astronomerdave. Od pana prawie 2 lata spóźnionego na przyjęcie.
Tom Howard,
@Kris: Zamiast Cherry-Pick użyj rebase. Ponieważ jest to zaawansowana komisjonowanie
Eugen Konkov
Użyłbym przywróć tylko wtedy, gdy już wypchnąłem moje zatwierdzenie. W przeciwnym razie resetowanie jest lepszą opcją. Nie zapominaj, że revert tworzy nowe zatwierdzenie i zwykle nie jest to celem.
Hola Soy Edu Feliz Navidad
532

Jeśli planujesz całkowicie cofnąć zatwierdzenie lokalne, cokolwiek zmieniłeś, zrobiłeś to, a jeśli nie martwisz się tym, po prostu wykonaj następujące polecenie.

git reset --hard HEAD^1

(To polecenie zignoruje całe zatwierdzenie, a zmiany zostaną całkowicie utracone z lokalnego drzewa roboczego). Jeśli chcesz cofnąć zatwierdzenie, ale chcesz zmiany w obszarze testowym (przed zatwierdzeniem, podobnie jak po git add), wykonaj następujące polecenie.

git reset --soft HEAD^1

Teraz zatwierdzone pliki trafiają do obszaru przejściowego. Załóżmy, że chcesz zmodyfikować pliki, ponieważ musisz edytować niewłaściwą zawartość, a następnie wykonaj następujące polecenie

git reset HEAD

Teraz zatwierdzono pliki, które mają pochodzić z obszaru przejściowego do obszaru niestopowego. Teraz pliki są gotowe do edycji, więc bez względu na to, co zmienisz, chcesz edytować i dodać go i dokonać nowego / nowego zatwierdzenia.

Więcej

Madhan Ayyasamy
źródło
13
@SMR, w twoim przykładzie wszyscy wskazują tylko bieżącą HEAD. HEAD ^ = HEAD ^ 1. Jak HEAD ^ 1 = HEAD ~ 1. Kiedy używasz HEAD ~ 2, istnieje różnica między symbolami ~ i ^. Jeśli użyjesz ~ 2, oznacza „pierwszy rodzic pierwszego rodzica” lub „dziadek”.
Madhan Ayyasamy,
501

Jeśli masz zainstalowane Git Extras , możesz uruchomić, git undoaby cofnąć ostatnie zatwierdzenie. git undo 3cofnie ostatnie trzy zmiany.

pseudonim
źródło
470

Chciałem cofnąć ostatnie pięć zatwierdzeń w naszym wspólnym repozytorium. Odszukałem identyfikator wersji, do której chciałem przywrócić. Następnie wpisałem następujące.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To [email protected]:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>
neoneye
źródło
25
Przepisywanie historii we współdzielonym repozytorium jest generalnie bardzo złym pomysłem. Zakładam, że wiesz, co robisz, mam tylko nadzieję, że przyszli czytelnicy też to zrobią.
Brad Koch,
Tak wycofanie jest niebezpieczne. Upewnij się, że kopia robocza jest w pożądanym stanie przed pchnięciem. Po wypchnięciu niechciane zatwierdzenia zostają trwale usunięte.
neoneye
6
„Podobnie jak w prawdziwym świecie, jeśli chcesz przepisać historię, potrzebujesz spisku: każdy musi brać udział w spisku (przynajmniej każdy, kto wie o historii, tj. Każdy, kto kiedykolwiek wycofał się z gałęzi) . ” Źródło: stackoverflow.com/a/2046748/334451
Mikko Rantalainen,
440

Wolę używać git rebase -ido tego zadania, ponieważ pojawia się ładna lista, w której mogę wybrać zatwierdzenia do pozbycia się. To może nie być tak bezpośrednie jak niektóre inne odpowiedzi tutaj, ale wydaje się właściwe .

Wybierz, ile zatwierdzeń chcesz wyświetlić, a następnie wywołaj w ten sposób (aby zapisać ostatnie trzy)

git rebase -i HEAD~3

Przykładowa lista

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

Następnie Git usunie zatwierdzenia dla każdej linii, którą usuniesz.

Steven Penny
źródło
422

Jak naprawić poprzedni lokalny zatwierdzenie

Użyj git-gui (lub podobnego), aby wykonać git commit --amend. Z GUI można dodawać lub usuwać pojedyncze pliki z zatwierdzenia. Możesz także zmodyfikować komunikat zatwierdzenia.

Jak cofnąć poprzednie zatwierdzenie lokalne

Po prostu zresetuj swój oddział do poprzedniej lokalizacji (na przykład za pomocą gitklub git rebase). Następnie ponownie zastosuj zmiany z zapisanej kopii. Po wyrzuceniu elementów bezużytecznych w lokalnym repozytorium będzie tak, jakby niechciane zatwierdzenie nigdy się nie wydarzyło. Aby zrobić to wszystko w jednym poleceniu, użyj git reset HEAD~1.

Słowo ostrzeżenia : Nieostrożne użycie git resetjest dobrym sposobem na wprowadzenie w błąd kopii roboczej. Zalecam, aby nowicjusze Git unikali tego, jeśli mogą.

Jak cofnąć publiczne zatwierdzenie

Wykonaj odwrotne wybieranie cherry ( git-revert ), aby cofnąć zmiany.

Jeśli nie wprowadziłeś jeszcze innych zmian w swoim oddziale, możesz po prostu zrobić ...

git revert --no-edit HEAD

Następnie przekaż zaktualizowaną gałąź do wspólnego repozytorium.

Historia zatwierdzeń pokaże oba zatwierdzenia, osobno .


Zaawansowane: Korekta oddziału prywatnego w publicznym repozytorium

Może to być niebezpieczne - upewnij się, że masz lokalną kopię oddziału, aby ją obsadzić.

Uwaga: nie chcesz tego robić, jeśli ktoś inny może pracować nad oddziałem.

git push --delete (branch_name) ## remove public version of branch

Oczyść swój oddział lokalnie, a następnie powtórz ...

git push origin (branch_name)

W normalnym przypadku prawdopodobnie nie musisz się martwić, że historia zatwierdzeń w prywatnym oddziale jest nieskazitelna. Po prostu wciśnij uzupełniające zatwierdzenie (patrz „Jak cofnąć publiczne zatwierdzenie” powyżej), a następnie wykonaj scalanie squash, aby ukryć historię.

nobar
źródło
8
gitk --all $(git reflog | cut -c1-7)&może być pomocny w znalezieniu poprzedniej wersji, jeśli chcesz cofnąć zatwierdzenie „--amend”.
nobar
4
Należy zauważyć, że jeśli próbujesz usunąć tajne informacje przed wypchnięciem do wspólnego repozytorium, przywrócenie nie pomoże ci, ponieważ informacje będą nadal w historii w poprzednim zatwierdzeniu. Jeśli chcesz mieć pewność, że zmiana nigdy nie będzie widoczna dla innych, musisz użyćgit reset
Jherico
Myślę, że „prywatny” / „publiczny” bardziej poprawnie byłby „lokalny” / „zdalny”.
nobar
Poprawienie gałęzi prywatnej w zdalnym repozytorium można również zrobić po prostugit push origin (branch_name) --force
nobar
335

Jeśli chcesz go trwale cofnąć i sklonowałeś pewne repozytorium

Identyfikator zatwierdzenia może być widoczny przez

git log 

Następnie możesz zrobić -

git reset --hard <commit_id>

git push origin <branch_name> -f
poorva
źródło
Co jeśli nie użyjesz „<commit_id>” i po prostu użyjesz „git reset --hard”? Zazwyczaj chcę po prostu pozbyć się moich najnowszych aktualizacji, których jeszcze nie zatwierdziłem i wróciłem do ostatniego zatwierdzenia, które zrobiłem i zawsze używam „git reset --hard”.
Jaime Montoya
3
@JaimeMontoya Aby cofnąć ostatnie zmiany, których możesz użyć git reset --hard, ale jeśli musisz mocno usunąć ostatnie „n” zobowiązania, określ SHA
poorva
334

Jeśli popełniłeś śmieci, ale nie wypchnąłeś ich,

git reset --soft HEAD~1

HEAD ~ 1 jest skrótem dla zatwierdzenia przed głową. Alternatywnie możesz odwołać się do SHA-1 skrótu, jeśli chcesz zresetować. Opcja --soft usunie zatwierdzenie, ale pozostawi wszystkie zmienione pliki „Zmiany do zatwierdzenia”, tak jak ująłby to status git.

Jeśli chcesz pozbyć się jakichkolwiek zmian w śledzonych plikach w działającym drzewie od czasu zatwierdzenia przed nagłówkiem, użyj zamiast tego opcji „ --hard ”.

LUB

Jeśli już nacisnąłeś i ktoś pociągnął, co zwykle jest moim przypadkiem, nie możesz użyć git reset . Możesz jednak przywrócić git ,

git revert HEAD

Spowoduje to utworzenie nowego zatwierdzenia, które odwraca wszystko wprowadzone przez przypadkowe zatwierdzenie.

santos_mgr
źródło
Jestem w drugim przypadku, ale kiedy wykonuję polecenie „git revert HEAD”, pojawia się komunikat „error: Commit [ID] to scalenie, ale nie podano opcji -m. Fatal: recvert failed. Jakieś sugestie?
metaforge
2
Prawdopodobnie warto wspomnieć, że zamiast HEAD~1ciebie możesz użyć rzeczywistego skrótu wyświetlanego przez git log --statlub przez git reflog- przydatne, gdy musisz „cofnąć” więcej niż jeden zatwierdzenie.
ccpizza,
284

W SourceTree (GUI dla GitHub) możesz kliknąć zatwierdzenie prawym przyciskiem myszy i wykonać polecenie „Odwróć zatwierdzenie”. To powinno cofnąć twoje zmiany.

Na terminalu:

Możesz alternatywnie użyć:

git revert

Lub:

git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.
Varun Parakh
źródło
263

Jedno polecenie:

git reset --soft 'HEAD^' 

Świetnie działa cofnięcie ostatniego zatwierdzenia lokalnego!

Manish Shrivastava
źródło
11
Musiałem napisać git reset --soft „HEAD ^” z podwójnymi cudzysłowami, ponieważ piszę to z wiersza polecenia systemu Windows.
Włącz
253

Po prostu zresetuj go wykonując poniższe polecenie, używając git:

git reset --soft HEAD~1

Wyjaśnij: co git resetrobi, to w zasadzie resetdo każdego zatwierdzenia, do którego chcesz wrócić, a następnie, jeśli połączysz go z --softkluczem, wróci, ale zachowaj zmiany w swoich plikach, abyś wrócił na scenę który właśnie został dodany plik, HEADjest głową gałęzi, a jeśli połączysz się z ~1(w tym przypadku również użyjesz HEAD^), cofnie tylko jedno zatwierdzenie, które chcesz ...

Kroki na obrazku poniżej tworzę bardziej szczegółowo, w tym wszystkie kroki, które mogą się zdarzyć w rzeczywistych sytuacjach i zatwierdzenie kodu:

Jak cofnąć ostatnie zatwierdzenia w Git?

Alireza
źródło
239

Jak cofnąć ostatnie zatwierdzenie Git?

Aby przywrócić wszystko do stanu sprzed ostatniego zatwierdzenia, musimy zresetować do zatwierdzenia przed HEAD.

  1. Jeśli nie chcesz zachować wprowadzonych zmian:

    git reset --hard HEAD^
    
  2. Jeśli chcesz zachować zmiany:

    git reset --soft HEAD^
    

Teraz sprawdź swój dziennik git. Pokaże, że nasze ostatnie zatwierdzenie zostało usunięte.

Ranjithkumar Ravi
źródło
192

„Zresetuj działające drzewo do ostatniego zatwierdzenia”

git reset --hard HEAD^ 

„Wyczyść nieznane pliki z działającego drzewa”

git clean    

patrz - Git Quick Reference

UWAGA: To polecenie spowoduje usunięcie poprzedniego zatwierdzenia, więc używaj go ostrożnie! git reset --hardjest bezpieczniejszy.

Ravi_Parmar
źródło
190

Użyj reflog, aby znaleźć poprawny stan

git reflog

zaloguj się wcześniej REFLOG PRZED RESETOWANIEM

Wybierz prawidłowy dziennik rejestrowania (w moim przypadku f3cb6e2) i wpisz

git reset --hard f3cb6e2

Po tym GŁOWICA repo zostanie zresetowana do REJESTRATORA PO ZERECIE zresetować efekt

Wreszcie dziennik wygląda jak na poniższym obrazku

zaloguj się ponownie po OSTATECZNY REFLOG

Shubham Chaudhary
źródło
164

Pierwszy bieg:

git reflog

Wyświetli wszystkie możliwe działania, które wykonałeś w swoim repozytorium, na przykład zatwierdzenie, scalenie, ściągnięcie itp.

Następnie wykonaj:

git reset --hard ActionIdFromRefLog
U. Ali
źródło
155

Cofnij ostatnie zatwierdzenie:

git reset --soft HEAD^ lub git reset --soft HEAD~

Spowoduje to cofnięcie ostatniego zatwierdzenia.

Tutaj --softoznacza reset do inscenizacji.

HEAD~lub HEAD^oznacza przejście do zatwierdzenia przed HEAD.


Zamień ostatnie zatwierdzenie na nowe zatwierdzenie:

git commit --amend -m "message"

Zastąpi ostatnie zatwierdzenie nowym zatwierdzeniem.

akshay_rahar
źródło
153

Inny sposób:

Przejdź do gałęzi, którą chcesz przywrócić, a następnie zresetuj lokalną kopię roboczą z powrotem do zatwierdzenia, które chcesz być najnowszym na zdalnym serwerze (wszystko po nim przejdzie do widzenia). Aby to zrobić, w SourceTree kliknąłem prawym przyciskiem myszy i wybrałem „Resetuj BRANCHNAME do tego zatwierdzenia”.

Następnie przejdź do lokalnego katalogu swojego repozytorium i uruchom następującą komendę:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

Spowoduje to usunięcie wszystkich zatwierdzeń po bieżącym w lokalnym repozytorium, ale tylko dla tego jednego oddziału.

CommaToast
źródło
144

Wpisz git logi znajdź kod skrótu ostatniego zatwierdzenia, a następnie wprowadź:

git reset <the previous co>
Peter Mortensen
źródło
139

W moim przypadku przypadkowo popełniłem niektóre pliki, których nie chciałem. Więc zrobiłem następujące i zadziałało:

git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD

Sprawdź wyniki za pomocą gitk lub git log --stat

egridasov
źródło
133

Proste, uruchom to w linii poleceń:

git reset --soft HEAD~ 
ihue
źródło
126

Można to zrobić na wiele sposobów:

Polecenie Git, aby cofnąć ostatnie zatwierdzenie / poprzednie zatwierdzenie:

Ostrzeżenie: Nie używaj - twarde, jeśli nie wiesz, co robisz. --hard jest zbyt niebezpieczny i może usunąć twoje pliki.

Podstawowe polecenie przywrócenia zatwierdzenia w Git to:

$ git reset --hard <COMMIT -ID>

lub

$ git reset --hard HEAD~<n>

COMMIT-ID : identyfikator zatwierdzenia

n: jest liczbą ostatnich zatwierdzeń, które chcesz przywrócić

Możesz uzyskać identyfikator zatwierdzenia, jak pokazano poniżej:

$ **git log --oneline**

d81d3f1 function to subtract two numbers

be20eb8 function to add two numbers

bedgfgg function to mulitply two numbers

gdzie d81d3f1 i be20eb8 są identyfikatorami zatwierdzeń.

Zobaczmy teraz kilka przypadków:

Załóżmy, że chcesz cofnąć ostatnie zatwierdzenie „d81d3f1”. Oto dwie opcje:

$ git reset --hard d81d3f1

lub

$ git reset --hard HEAD~1

Załóżmy, że chcesz cofnąć zatwierdzenie „be20eb8”:

$ git reset --hard be20eb8

Aby uzyskać bardziej szczegółowe informacje, możesz odwołać się i wypróbować również inne polecenia do resetowania głowicy do określonego stanu:

$ git reset --help
3799762
źródło
5
git reset --hard HEAD~1jest zbyt niebezpieczne ! To nie tylko „anuluje ostatnie zatwierdzenie”, ale całkowicie przywróci repo z powrotem do poprzedniego zatwierdzenia. W ten sposób utracisz wszystkie zmiany wprowadzone w ostatnim zatwierdzeniu!
Arnis Juraga
Masz rację, aby cofnąć to, możesz użyćgit push -f <remote> HEAD@{1}:<branch>
Benny
Niestety używam --hard, a moje pliki są usuwane! Najpierw nie sprawdziłem komentarza, ponieważ jest zwinięty. Nie używaj - twarde, jeśli nie wiesz, co robisz!
anonimowy
125

Do zatwierdzenia lokalnego

git reset --soft HEAD~1

lub jeśli nie pamiętasz dokładnie, w jakim to jest zatwierdzeniu, możesz użyć

git rm --cached <file>

Dla wciśniętego zatwierdzenia

Stosuje się właściwy sposób usuwania plików z historii repozytorium git filter-branch. To jest,

git filter-branch --index-filter 'git rm --cached <file>' HEAD

Ale zalecam ostrożne używanie tego polecenia. Czytaj więcej na stronie podręcznika git-filter-branch (1) .

geoom
źródło
125

Istnieją dwa główne scenariusze

Nie nacisnąłeś jeszcze zatwierdzenia

Jeśli problemem były dodatkowe pliki, które zatwierdziłeś (i nie chcesz ich w repozytorium), możesz je usunąć za pomocą, git rma następnie zatwierdzić za pomocą--amend

git rm <pathToFile>

Możesz także usuwać całe katalogi -r, a nawet łączyć się z innymi poleceniami Bash

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

Po usunięciu plików możesz zatwierdzić, używając opcji --amend

git commit --amend -C HEAD # the -C option is to use the same commit message

Spowoduje to przepisanie ostatniego lokalnego zatwierdzenia usunięcia dodatkowych plików, więc pliki te nigdy nie będą wysyłane w trybie wypychania, a także zostaną usunięte z lokalnego repozytorium .git przez GC.

Przesunąłeś już zatwierdzenie

Możesz zastosować to samo rozwiązanie z drugiego scenariusza, a następnie zrobić to git pushz -fopcją, ale nie jest to zalecane, ponieważ zastępuje ono zdalną historię rozbieżną zmianą (może zepsuć repozytorium).

Zamiast tego musisz wykonać zatwierdzenie bez --amend(pamiętaj o tym -amend`: Ta opcja przepisuje historię ostatniego zatwierdzenia).

dseminara
źródło
125

Aby przywrócić poprzednią wersję, trwale usuwając wszystkie niezatwierdzone zmiany:

git reset --hard HEAD~1
gwiazdka
źródło
23
Być może mógłbyś otrzymać notatkę / ostrzeżenie, że jego polecenie wyrzuci zatwierdzenie i zmiany w katalogu roboczym bez pytania.
cr7pt0gr4ph7
6
Jeśli zdarzy ci się to zrobić przez przypadek, nie wszystko zostanie stracone. Zobacz stackoverflow.com/questions/10099258/… , stackoverflow.com/questions/15479501/... i stackoverflow.com/questions/7374069/undo-git-reset-hard/7376959 .
cr7pt0gr4ph7
13
Użyj, --softaby zachować zmiany jako uncommitted changes, --hardaby całkowicie anulować zatwierdzenie i cofnąć się o jedną. Pamiętaj, aby wykonywać takie operacje tylko na zmianach, które nie zostały jeszcze wprowadzone.
Yunus Nedim Mehel
@Zaz: Masz rację; może powinienem to wyjaśnić. Można odzyskać tylko pliki / zmiany, które zostały dodane do indeksu (/ przemieszczone) lub zostały zatwierdzone. Niezatwierdzone, nieustawione zmiany , jak powiedziałeś, całkowicie wyrzucone przez git reset --hard.
cr7pt0gr4ph7
1
Na marginesie: za każdym razem, gdy plik jest przemieszczany, gitzapisuje jego zawartość w swojej bazie danych obiektów. Zapisana zawartość jest usuwana tylko wtedy, gdy wykonywane jest czyszczenie pamięci. Dlatego możliwe jest odzyskanie ostatniej wersji pliku, który nie był aktualnie przemieszczany w momencie git reset --hardwykonania (więcej informacji znajduje się w linkach powyżej).
cr7pt0gr4ph7