Cofnij do starego zatwierdzenia Git w publicznym repozytorium


802

Jak mogę cofnąć się do konkretnego zatwierdzenia w git ?

Najlepszą odpowiedzią, git revertjaką ktoś mógł mi dać, było użycie X razy, aż dotrę do pożądanego zatwierdzenia.

Powiedzmy więc, że chcę wrócić do zatwierdzenia, które ma 20 starych zatwierdzeń, musiałbym uruchomić go 20 razy.

Czy jest na to łatwiejszy sposób?

Nie mogę użyć resetowania, ponieważ to repozytorium jest publiczne.


1
git revert <commit> nie działa?
miku

8
Jak stwierdzono w moim pytaniu, to naprawdę nie pomaga mi, jeśli chcę wrócić do czegoś, co sprzed 20 lat.
David

7
Odpowiedź na to pytanie jest dość dobra tutaj stackoverflow.com/questions/4114095/…
user7610

4
Nie jest jasne, co rozumiesz przez „wycofywanie”. Czy to oznacza, że ​​chcesz tymczasowo przełączyć kopię roboczą na określoną wersję? A może chcesz na stałe przywrócić historię swojego repozytorium z powrotem do określonej wersji?

1
Powinieneś zaakceptować odpowiedź i ewentualnie głosować na inne odpowiedzi, które ci się podobają.
Nabil Kadimi,

Odpowiedzi:


1193

Spróbuj tego:

git checkout [revision] .

gdzie [revision]jest skrót zatwierdzenia (na przykład:) 12345678901234567890123456789012345678ab.

Nie zapomnij .na końcu, bardzo ważne. Spowoduje to zastosowanie zmian do całego drzewa. Powinieneś wykonać to polecenie w katalogu głównym projektu git. Jeśli znajdujesz się w dowolnym podkatalogu, to polecenie zmienia tylko pliki w bieżącym katalogu. Następnie popełnij i powinieneś być dobry.

Możesz to cofnąć przez

git reset --hard 

spowoduje to usunięcie wszystkich modyfikacji z katalogu roboczego i obszaru przejściowego.


7
@AlexReisner Ten okres w punktach końcowych w katalogu, w którym aktualnie się znajdujesz, co niekoniecznie jest całym projektem git, prawda? Jeśli chcesz zastosować zmiany do całego projektu, czy zamiast tego użyłbyś ': /' jak w 'git add: /', gdybyś nie był w katalogu głównym projektu git?
MSpreij

10
Uwaga: jeśli do tego czasu dodałeś nowe pliki do projektu, nie zostaną one usunięte. Więc kiedy idziesz na kompilację (w zależności od platformy), możesz nadal otrzymywać błędy. Usuń nowe pliki i gotowe.
TheWestIsThe ...

6
@MSpreij Powinieneś wykonać to polecenie w katalogu głównym projektu git. Jeśli znajdujesz się w dowolnym podkatalogu, to polecenie zmienia tylko pliki w bieżącym katalogu.
volatilevar

3
Świetnie, gdy możesz sklonować projekt w innym katalogu i użyć git checkout [wersja]. aby wrócić do konkretnej wersji, a następnie porównać z tym samym projektem w innym katalogu. Oszczędza dużo czasu.
Donato,

4
Cholera, zapomniałem „.” jakie szkody wyrządziłem mojemu repozytorium?
Sowa,

196

Aby przywrócić do określonego zatwierdzenia:

git reset --hard commit_sha

Aby wycofać 10, zatwierdza wycofanie:

git reset --hard HEAD~10

Możesz użyć „git revert” jak w poniższym poście, jeśli nie chcesz przepisać historii

Jak przywrócić repozytorium Git do poprzedniego zatwierdzenia?


4
jedyna różnica między tym podejściem a „git checkout [wersja]”. jest to, że ta ostatnia zachowuje poprawki.
deeshank

53
Ta odpowiedź jest NIEPRAWIDŁOWA, ponieważ OP wyraźnie stwierdza: „Nie mogę użyć resetowania, ponieważ to repozytorium jest publiczne”
Yarin

4
Jeśli repo jest publiczne, myślę, że nie ma możliwości wycofania zatwierdzenia w publicznym repozytorium bez użycia wymuszonego wypychania (git push-f), ponieważ wpłynie to na osoby, które wprowadziły zmiany przed wycofaniem. Dlatego resetu można użyć również w lokalnym obszarze izolowanym publicznego repozytorium.
Naga Kiran

4
To wspaniałe, że pozwala to uniknąć odłączonej GŁOWY! Właśnie tego szukałem.
cyber-mnich

1
W moim przypadku to zadziałało, a następnie użyj „git pull”, aby szybko przejść do przodu po przetestowaniu regresji itp.
Peter Quiring

86

Myślę, że pytanie brzmi: co rozumiesz przez „wycofanie”? Jeśli nie możesz, resetponieważ jest to publiczne i chcesz zachować nienaruszoną historię zatwierdzeń, czy masz na myśli, że chcesz, aby kopia robocza odzwierciedlała konkretne zatwierdzenie? Użyj git checkouti skrótu zatwierdzenia.

Edycja: Jak wskazano w komentarzach, użycie git checkoutbez określenia gałęzi pozostawi cię w stanie „bez rozgałęzienia”. Użyj git checkout <commit> -b <branchname>do kasy do oddziału lub git checkout <commit> .do kasy do bieżącej gałęzi.


Czy to nie wpędza cię w dziwny stan „Obecnie nie ma żadnego oddziału”? Jak zatwierdzasz zmiany, aby dokończyć wycofywanie?
Alex Reisner,

Cóż, ja tylko sugeruję użycie git checkout- może sprawdzić w dowolnym oddziale (obecnym lub nowym), który sobie życzy. Zaktualizuję moją odpowiedź, aby nie była dwuznaczna.
Ben

2
Próbowałem tego, ale nie sądzę, że jest to właściwy sposób, ponieważ powoduje stagnację plików. To nie usuwa plików, których nie było w ostatnim zatwierdzeniu.
David

3
Jeśli znajdujesz się w katalogu roboczym i pozostajesz w trybie głównym, musisz git resetusunąć te pliki, o których mówisz, że nie chcesz tego robić. Spróbuj zrobić to w osobnej gałęzi: w tej gałęzigit checkout <commit> -b <branchname> nie będzie plików stojących .
Ben

2
Problem z używaniem checkoutpolega na tym, że nie usuwa plików, które zostały dodane w poprzednim zatwierdzeniu.

42

Oryginalny plakat stwierdza:

Najlepszą odpowiedzią, git revertjaką ktoś mógł mi dać, było użycie X razy, aż dotrę do pożądanego zatwierdzenia.

Powiedzmy więc, że chcę wrócić do zatwierdzenia, które ma 20 starych zatwierdzeń, musiałbym uruchomić go 20 razy.

Czy jest na to łatwiejszy sposób?

Nie mogę użyć resetowania, ponieważ to repozytorium jest publiczne.

Używanie git revertX razy nie jest konieczne . git revertmoże zaakceptować zakres zatwierdzeń jako argument, więc wystarczy go użyć tylko raz, aby cofnąć zakres zatwierdzeń. Na przykład, jeśli chcesz cofnąć ostatnie 20 zatwierdzeń:

git revert --no-edit HEAD~20..

Commit zakres HEAD~20..jest skrótem HEAD~20..HEADi oznacza „rozpocznie się od 20 th rodzic główki popełnił, i przywrócić wszystkie rewizje po to do głowy”.

Spowoduje to cofnięcie ostatnich 20 zatwierdzeń, przy założeniu, że żadne z nich nie jest zatwierdzone przez scalenie. Jeśli istnieją zatwierdzenia scalania, nie możesz cofnąć ich wszystkich za pomocą jednego polecenia, musisz cofnąć je indywidualnie za pomocą

git revert -m 1 <merge-commit>

Zauważ też, że testowałem przy użyciu zakresu z git revertużyciem gita w wersji 1.9.0. Jeśli używasz starszej wersji git, użycie zakresu z git revertmoże, ale nie musi, działać.

W takim przypadku git revertjest preferowany git checkout.

Zauważ, że w przeciwieństwie do tej odpowiedzi, która mówi, aby użyćgit checkout , git revert faktycznie usunie wszystkie pliki, które zostały dodane w jednym z przywracanych zatwierdzeń , co sprawia, że ​​jest to właściwy sposób na przywrócenie szeregu wersji.

Dokumentacja


Uwaga : tworzy to nowe zatwierdzenie z cofniętymi zmianami. Idealny na pytanie OP. Ale upewnij się, że tego właśnie chcesz. (Przykłady w dokumencie git-revert powiązanym z powyższym są doskonałe.) Jeśli zamiast tego chcesz zbadać wcześniejsze zatwierdzenia (tj. Przed wybraniem, do którego zobowiązują się przywrócić), skorzystaj z opcji kasy wymienionej w innych odpowiedziach, pamiętając o komentarzach innych wykonane o usuniętych plikach.
SherylHohman

@ SherylHohman Przywrócenie poprzedniego zatwierdzenia nie powoduje utworzenia nowego zatwierdzenia. Nie mogę sobie wyobrazić, co masz na myśli.

27

Krok 1: Pobierz listę zatwierdzeń:

git log

Otrzymasz listę jak w tym przykładzie:

[Comp:Folder User$ git log
commit 54b11d42e12dc6e9f070a8b5095a4492216d5320
Author: author <author@gmail.com>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <author@gmail.com>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <author@gmail.com>
Date:   Thu Jun 23 00:41:55 2016 +0300

This is previous previous commit message
...

Krok 2: Skopiuj potrzebny skrót zatwierdzenia i wklej go do kasy:

git checkout fd6cb176297acca4dbc69d15d6b7f78a2463482f

To wszystko.


11
git read-tree -um @ $commit_to_revert_to

zrobię to. Jest to „git checkout”, ale bez aktualizacji HEAD.

Możesz osiągnąć ten sam efekt za pomocą

git checkout $commit_to_revert_to
git reset --soft @{1}

jeśli wolisz łączenie poleceń wygody razem.

To pozostawia z twoim drzewem pracy i indeksem w pożądanym stanie, możesz po prostu git commitzakończyć.


To jedyne proste podejście, które działało jak urok! Wyrejestrowałem się z głowy, uruchomiłem to polecenie i pomyślnie usunąłem dodane pliki, które wprowadziliśmy i cofnęliśmy wszystkie zmiany. Świetny.
kamranicus

6

Chcesz odłączony HEAD?

Jeśli chcesz cofnąć czas X do określonego zatwierdzenia z ODŁĄCZONĄ GŁOWĄ (co oznacza, że ​​nie możesz niczego zepsuć), to we wszystkich przypadkach skorzystaj z następujących opcji:

(zamień X na liczbę zatwierdzeń, które chcesz cofnąć)

git checkout HEAD~X

IE, aby wrócić o jedno zatwierdzenie:

git checkout HEAD~1

1
Chciałbym usunąć tę część z ... trudno w to uwierzyć ... Wydaje się to osobiste, a także ktoś wspomniał o tym w komentarzu powyżej, a także w @ken w swojej odpowiedzi.
meJustAndrew

@meJustAndrew Jest tak wiele odpowiedzi na temat SO, które po prostu dezorientują ludzi, jest to dość denerwujące.
Karl Morrison,

Cóż za prosta i bezpośrednia odpowiedź.
Ammad

2

Powiedzmy, że pracujesz nad projektem i po około dniu. Zauważ, że jedna funkcja nadal powoduje błędy. Ale nie wiesz, jaką zmianę wprowadziłeś, co spowodowało błąd. Więc musisz wyłowić poprzednie robocze zobowiązania. Aby powrócić do konkretnego zatwierdzenia:

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 .

Ok, więc zatwierdzenie działa dla ciebie. Nigdy więcej błędu. Wskazałeś problem. Teraz możesz wrócić do ostatniego zatwierdzenia:

git checkout 792d9294f652d753514dc2033a04d742decb82a5 .

I sprawdź konkretny plik, zanim spowodował błąd (w moim przypadku korzystam z przykładu Gemfile.lock):

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 -- /projects/myproject/Gemfile.lock

Jest to jeden ze sposobów radzenia sobie z błędami, które stworzyłeś w commits, bez uświadomienia sobie błędów do późniejszego momentu.


2

Identyfikator zatwierdzenia powiązany z każdym zatwierdzeniem znajduje się w sekcji zatwierdzeń GitHub / BitBucket / Gitlab. To bardzo proste, załóżmy, że twój identyfikator zatwierdzenia to 5889575, a jeśli chcesz wrócić do tej części kodu, po prostu musisz wpisać

git checkout 5889575 .

Spowoduje to przejście do tego momentu w kodzie.


1

Nie jestem pewien, co się zmieniło, ale nie jestem w stanie sprawdzić konkretnego zatwierdzenia bez opcji --detach. Pełne polecenie, które działało dla mnie, to: git checkout --detach [commit hash]

Aby wrócić z odłączonego stanu, musiałem sprawdzić mój lokalny oddział: git checkout master


Wyewidencjonowanie masterrozwiązuje problem pozostawania odłączonym, podczas pracy git reset --hardlub git checkout -- .działał, ale pozostał odłączony
DarkCygnus

0

Oto przykład, aby to zrobić

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.