Cofnij git pull, jak przywrócić repo do starego stanu

1006

Czy jest jakiś sposób na przywrócenie lub cofnięcie git pull, aby moje źródła / repozytoria powróciły do ​​starego stanu, który był przed wykonaniem git pull? Chcę to zrobić, ponieważ połączył niektóre pliki, których nie chciałem, ale scalam tylko pozostałe pliki. Chcę odzyskać te pliki, czy to możliwe?

EDYCJA: Chcę cofnąć połączenie w celu wyjaśnienia. Po obejrzeniu kilku odpowiedzi zrobiłem to

git reflog
bb3139b... HEAD@{0}: pull : Fast forward
01b34fa... HEAD@{1}: clone: from ...name...

Co mam teraz zrobić? Czy wszystko git reset --hard jest w porządku? Nie chcę tego ponownie pieprzyć, więc pytasz o szczegółowe kroki?

seg.server.fault
źródło
23
Wygląda na to, że masz tylko dwie rzeczy w swojej historii: klon i pobranie. Po prostu zresetuj do klonowania: git reset --hard 01b34faw tym przypadku mogłeś zrobić, git reset --hard HEAD^który resetuje się do jednego zatwierdzenia przed HEAD.
jkp
2
- twardy jest konieczny, jeśli chcesz zmodyfikować pliki w swoim reż.
William Pursell,
3
@ seg.server.fault: jeśli zadziałało, zawsze możesz zaakceptować odpowiedź;)
jkp
7
git reset --hard HEAD ^
funroll 16.09.13
7
git reflogpokaże wszystko, co zostało zrobione z git. Istnieje obawa, że git reset --hard [sha1 of something from reflog]cofnie wszystko, co jest pokazane reflog, co czasami nie jest celem, np. chcesz cofnąć scalanie na gałęzi master pobranej z pochodzenia ze złymi danymi (zdarza się), a po tym scaleniu pracowałeś nad innymi gałęziami. reflogpokaże każdą szansę na innych gałęziach. Ale git checkout masteri git reset --hard [SH1 of commit on master branch just before merge]zresetuje tylko bieżącą gałąź master usuwając scalenie z miejsca pochodzenia.
Vladimir Vukanac

Odpowiedzi:

1427

Uruchomienie git pullwykonuje następujące zadania w kolejności:

  1. git fetch
  2. git merge

Krok scalania łączy gałęzie, które zostały skonfigurowane do scalenia w konfiguracji. Chcesz cofnąć krok scalania , ale prawdopodobnie nie pobieranie (nie ma większego sensu i nie powinno być konieczne).

Aby cofnąć scalenie , użyj, git reset --hardaby zresetować lokalne repozytorium do poprzedniego stanu; użyj git-reflog, aby znaleźć SHA-1 poprzedniego stanu, a następnie zresetuj go.

Ostrzeżenie

Polecenia wymienione w tej sekcji usuwają wszystkie niezatwierdzone zmiany, potencjalnie prowadząc do utraty pracy:

git reset --hard

Możesz też zresetować do określonego momentu w czasie, takiego jak:

git reset --hard master@{"10 minutes ago"}
jkp
źródło
325
Doskonałym sposobem, aby wybrać poprzedni stan, zamiast używać git-reflog i kopiowanie skrótów, jest użycie skrótu niczym master@{1}, co jest poprzednia pozycja master, master@{"5 minutes ago"}lub master@{14:30}. Szczegółowe informacje na temat określania wersji w ten sposób można znaleźć w man git-rev-parsesekcji o nazwie „określanie wersji”.
Cascabel,
38
W takim przypadku ORIG_HEAD powinien również działać („git reset --hard ORIG_HEAD”)
Jakub Narębski,
@Jelfromi: dzięki za tę wskazówkę, nie wiedziałem, że możesz być tak gadatliwy na temat poprawek. Wiedziałem o wybieraniu poprawek w stosunku do HEAD, ale kiedy postawiono pytanie, nie wiedziałem, jak daleko w przeszłości chciał iść.
jkp
Kiedy ciągnąłem, mówi Updating d2c90a3..035ac4d. Tutaj możesz również użyć d2c90a3jako parametru do zresetowania.
Thai
Nie musisz wpisywać skrótów, gdy używasz reflog. Możesz także użyć HEAD @ {1} lub jakikolwiek poprzedni numer zdefiniowany w rejestrze.
Simon The Cat
338

To samo co odpowiedź jkp, ale oto pełne polecenie:

git reset --hard a0d3fe6

gdzie a0d3fe6 zostanie znalezione przez wykonanie

git reflog

i patrząc na punkt, w którym chcesz cofnąć.

Jeffrey Sun
źródło
Dlaczego git reset HEAD --hardna przykład nie mogę tego zrobić ?
Sung Cho
9
@MikeC To podejście pozwala cofnąć się o kilka
ciągnięć
2
I nie był w stanie wykorzystać identyfikatory lewe boczne ale git reset --hard HEAD@{n}pracował
E. Sundin
1
Powinieneś był zasugerować edycję odpowiedzi jkp zamiast prawie replikować ją tutaj po tylu latach.
Abhishek Anand
Jeśli mam to na git reflog: dab04ec HEAD @ {0}, aaaaaaa HEAD @ {1} i bbbbbbb HEAD @ {2}. Jeśli to zrobię git reset --hard bbbbbbb, stracę HEAD 0 i 1?
pmiranda
115

Bardziej nowoczesnym sposobem cofnięcia scalenia jest:

git merge --abort

I nieco starszy sposób:

git reset --merge

Oldschoolowy sposób opisany w poprzednich odpowiedziach (ostrzeżenie: odrzuci wszystkie lokalne zmiany):

git reset --hard

Ale tak naprawdę warto zauważyć, że git merge --abortjest to odpowiednik tylko git reset --mergetego, co MERGE_HEADjest obecne. Można to odczytać w pomocy git dla polecenia scalania.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

Po nieudanym scaleniu, gdy nie ma MERGE_HEAD, nieudanego scalenia można cofnąć, git reset --mergeale niekoniecznie za pomocą git merge --abort, więc są one nie tylko starą i nową składnią tego samego . Dlatego uważam, że jestem git reset --mergeo wiele bardziej przydatny w codziennej pracy.

Martin G.
źródło
20
git merge --abortdziała W TRAKCIE scalania, a nie po git pullzakończeniu. Ta odpowiedź wydaje się więc nie mieć znaczenia dla pytania.
Abhishek Anand
1
git reset --mergeusuwa wszystkie zmiany, które nie zostały wprowadzone do zatwierdzenia. Odkryłem to na własnej skórze.
theadriangreen
62

to działa po raz pierwszy: git reflog

znajdź swój SHA swojego poprzedniego stanu i wykonaj (HEAD @ {1} jest przykładem)

git reset --hard HEAD@{1}
Ezequiel García
źródło
40

Jeśli masz gitk (spróbuj uruchomić „gitk --all z linii poleceń git”), to proste. Po prostu uruchom go, wybierz zatwierdzenie, do którego chcesz przywrócić (kliknij prawym przyciskiem myszy), i wybierz „Zresetuj gałąź główną tutaj”. Jeśli nie masz żadnych nieprzewidzianych zmian, wybierz opcję „trudną”.

Samuel Carrijo
źródło
8
Warto uruchomić, jeśli go nie widziałeś. Wyskakuje zwariowany GUI.
Evan Moran
35

Załóżmy, że $COMMITbył to ostatni identyfikator zatwierdzenia przed wykonaniem git pull. To, czego potrzebujesz, aby cofnąć ostatnie ściągnięcie, to

git reset --hard $COMMIT

.

Premia:

Mówiąc o pullu, chciałbym podzielić się ciekawą sztuczką,

git pull --rebase

To powyższe polecenie jest najbardziej użytecznym poleceniem w moim życiu git, które zaoszczędziło wiele czasu.

Przed wypchnięciem nowego zatwierdzenia na serwer, spróbuj tego polecenia, a ono automatycznie zsynchronizuje najnowsze zmiany na serwerze (z pobieraniem + scalaniem) i umieści twoje zatwierdzenie na górze w dzienniku git. Nie musisz martwić się o ręczne wyciąganie / scalanie.

Znajdź szczegóły na: http://gitolite.com/git-pull--rebase

Sazzad Hissain Khan
źródło
17

Jest to najprostszy sposób na przywrócenie zmian.

** Warning **

Wykonaj kopię zapasową zmienionych plików, ponieważ spowoduje to usunięcie nowo utworzonych plików i folderów .

git reset --hard 9573e3e0

Gdzie 9573e3e0jest Twój {Commit id}

Manish Goswami
źródło
ta odpowiedź jest bardzo przydatna, ponieważ jeśli zrobimy gałąź pochodzenia git pull, dostaniemy coś takiego Updating ffce65bd..e929e884, dogit reset --hard ffce65bd
Ernesto Alfonso
15

możesz to zrobić git reset --hard ORIG_HEAD

ponieważ „pull” lub „merge” ustaw ORIG_HEAD na bieżący stan przed wykonaniem tych akcji.

Orlando
źródło
5

git pull wykonaj poniżej operacji.

ja. git fetch

ii. git merge

Aby cofnąć wyciągnięcie, wykonaj dowolną operację:

ja. git reset --hard --- przywraca również wszystkie lokalne zmiany

lub

ii. git reset --hard master@{5.days.ago} (jak 10.minutes.ago, 1.hours.ago, 1.days.ago..), aby uzyskać lokalne zmiany.

lub

iii. git reset --hard commitid

Poprawa:

Następnym razem użyj git pull --rebasezamiast git pull... zmienić jego serwer synchronizacji, wykonując (pobierz i scal).

GolamMazid Sajib
źródło
4

Jeśli wystąpi nieudane scalenie, które jest najczęstszym powodem cofnięcia git pull, uruchamianie git reset --mergedziała dokładnie tak, jak można się spodziewać: zachowaj pobrane pliki, ale cofnij scalanie, które git pullpróbowało scalić. Następnie można zdecydować, co zrobić bez bałaganu, który git mergeczasami generuje. I nie trzeba nikogo szukać dokładnego identyfikatora zatwierdzenia, który jest --hardwymagany w każdej innej odpowiedzi.

Davide
źródło