Odzyskiwanie z Git Reset - twardy?

457

Czy istnieje sposób na odzyskanie niezatwierdzonych zmian w katalogu roboczym z katalogu git reset --hard HEAD?

Jacob Lyles
źródło
49
Poleciłbym oduczenie git reset. Nie potrzebujesz tego polecenia i jest niebezpieczne, więc nie używaj go. Aby przywrócić gałąź do poprzedniego zatwierdzenia albo git rebase -iupuścić niepotrzebne zmiany lub git checkout(odłącza głowę), a następnie git branch -Mprzenieść końcówkę gałęzi. Pierwszy odmówi uruchomienia z lokalnymi zmianami, a później będzie działał tylko, jeśli lokalnie zmodyfikowane pliki nie różnią się między wersjami.
Jan Hudec
11
@ Jan Nie wierzę w to. Istnieją całkowicie uzasadnione powody, aby użyć resetowania.
spaaarky21
4
@ spaaarky21: Tak, są. Ale git reset --hard somewherejest jednym z niewielu naprawdę niebezpiecznych poleceń git.
Jan Hudec
5
@Jan Zgadzam się, ale to, że jest niebezpieczne, nie oznacza, że ​​nie powinieneś go używać. Po prostu wiedz, co robisz i bądź ostrożny. :)
spaaarky21
3
Nie związane z Cofaniem resetu gita - twarda GŁOWA ~ 1 , ponieważ tutaj oryginalny plakat próbuje odzyskać niezaangażowane zmiany.

Odpowiedzi:

474

Państwo nie może wrócić niezatwierdzone zmiany w ogóle.

Wcześniej ustawione zmiany ( git add) powinny być możliwe do odzyskania z obiektów indeksu, więc jeśli tak, użyj git fsck --lost-founddo zlokalizowania powiązanych z nimi obiektów. (Spowoduje to zapisanie obiektów w .git/lost-found/katalogu; stamtąd można użyć git show <filename>do wyświetlenia zawartości każdego pliku.)

Jeśli nie, odpowiedź brzmi: spójrz na swoją kopię zapasową. Być może twój edytor / IDE przechowuje kopie tymczasowe pod / tmp lub C: \ TEMP i tym podobne. [1]

git reset HEAD@{1}

Spowoduje to przywrócenie poprzedniej HEAD

[1] vim np. Opcjonalnie przechowuje trwałe cofanie, Eclipse IDE przechowuje lokalną historię ; takie funkcje mogą zaoszczędzić **

sehe
źródło
18
Lokalna historia Eclipse - a ponadto, ponieważ niektóre zmiany były starsze niż 6 dni, moja kopia zapasowa mojej lokalnej maszyny Eclipse w Time Machine! Z jakiegoś powodu kopia zapasowa Time Machine folderu zarządzanego przez git nie zawierała moich poprzednich zmian.
christianbrodbeck
2
Na poważnie ratujesz życie podpowiedzi! TextWrangler miał kopię zapasową plików. Dziękuję
Vivek Sampara,
6
IDE (IntelliJ) zapisał zmiany lokalnie, które uratowały dzień. Dzięki za wskazówkę!
progonkpa
1
WOW, to jest niesamowite. Działa, nawet jeśli nigdy nie dokonałeś zatwierdzenia.
Boudewijn Aasman,
2
Rzeczywiście lokalna historia w Eclipse (w moim przypadku Intellij) oszczędza mi czasu na przywracaniu zmian bezstratnych, doc tutaj dla Intellij: blog.jetbrains.com/idea/2008/01/…
Richard
448

odpowiedź z tego SO

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Wróciłeś dzień! :)

rozpoznać
źródło
24
Dodanie do tej odpowiedzi pomogłoby osobom, które faktycznie popełniły zmiany, które zostały odrzucone przez twardy reset.
murki
9
Świetnie - ale w moim przypadku pliki zniknęły całkowicie. Użycie git checkout HEAD@{19}pozwoliło mi sprawdzić utracone pliki w stanie odłączonym. Następnie używane git checkout -b new-branch-namedo dodawania ich z powrotem do repozytorium w stanie „załączonym”.
NightOwl888
@ NightOwl888: Otrzymaj nowicjusza tutaj i miałem ten sam problem, że moje pliki nadal nie było. Czy możesz wyjaśnić bardziej szczegółowo, w jaki sposób odzyskałeś swoje pliki do stanu „dołączonego” (lub czy możesz wyjaśnić, co to właściwie oznacza)? Dziękuję bardzo!
OhDaeSu,
3
@ user3385759 - W Git, gdy użyjesz polecenia kasowania na czymkolwiek, co nie jest gałęzią, przejdzie w specjalny tryb „odłączonej głowy”. Oznacza to, że tak naprawdę nie wskazujesz gałęzi, ale możesz zobaczyć, co zostało zameldowane w stanie jednostki (w tym przypadku pozycja ponownego logowania). Z tego stanu możesz zmienić go w „prawdziwą” gałąź, do której możesz wrócić ponownie, używając git checkout -b new-branch-name. Książka Pragmatic Version Control Korzystanie z Git dobrze objaśnia Git w prostych słowach.
NightOwl888
2
Tak, co powiedzieli NomNomCameron i Jesse Adelman. Myślałem, że reset zresetuje się do mojego ostatniego zatwierdzenia. Nie. Wymazał wszystko. Ta odpowiedź uratowała mnie przed dniem lub dwoma odtwarzaniem mojej pracy.
VeteranCoder,
308

Przypadkowo uruchomiłem git reset --harddziś moje repozytorium, jednocześnie wprowadzając nieproszone zmiany. Aby go odzyskać, pobiegłem git fsck --lost-found, do którego zapisałem wszystkie niepowiązane obiekty BLOB <path to repo>/.git/lost-found/. Ponieważ pliki nie zostały zatwierdzone, znalazłem je w otherkatalogu w katalogu <path to repo>/.git/lost-found/. Stamtąd mogę zobaczyć nieprzypisane pliki za pomocą git show <filename>, skopiować obiekty BLOB i zmienić ich nazwy.

Uwaga: Działa to tylko wtedy, gdy dodałeś pliki, które chcesz zapisać do indeksu (używając git add .). Jeśli pliki nie były w indeksie, zostały utracone.

Justin
źródło
4
Mam tylko pliki z referencjami zatwierdzania lost-found. Ale wtedy mógłbym zrobić, git showaby uzyskać zawartość.
Mitar
6
Aby zaoszczędzić każdemu czas#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst
209

Tak, MOŻESZ ODZYSKAĆ ​​od twardego resetu w git.

Posługiwać się:

git reflog

aby uzyskać identyfikator swojego zatwierdzenia. Następnie użyj:

git reset --hard <commit-id-retrieved-using-reflog>

Ta sztuczka uratowała mi życie kilka razy.

Dokumentację reflogu można znaleźć TUTAJ .

Gabe
źródło
9
Jak dotąd uważam, że jest to najlepsza i najbardziej zwięzła odpowiedź. Odzyskiwanie po git reset --hardużyciu innego może wydawać się sprzeczne z intuicją, git reset --hardale jeśli nie użyjesz --hardprzełącznika, pozostaną Ci pozycje w obszarze roboczym, które skutecznie przywróciłyby właśnie odzyskaną pracę.
Ryan H.
2
Działa jak marzenie! Poprzednia odpowiedź ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) nie działała dla mnie.
codemax
3
Ta odpowiedź jest nieprawidłowa. To podejście przywraca tylko wcześniej zatwierdzone zmiany. Nie będzie w stanie przywrócić niezatwierdzonych zmian (o to chodzi w tym pytaniu).
Alderath,
2
To rozwiązanie działa dla mnie. Zrobiłem twardy reset, a potem przy użyciu git lognie widziałem identyfikatora zatwierdzenia. Z git reflogWidziałem identyfikator zatwierdzenia
dboscanv
2
to działa dla mnie. dzięki!!!!!!
RedEyed
60

Podczas pracy nad projektem lokalnym chciałem przenieść go do GitHub, a następnie utworzyć nowe repozytorium. Kiedy próbowałem dodać wszystkie te pliki do nowego repozytorium za pomocą .gitignore, przypadkowo dodałem niewłaściwy plik, a następnie próbowałem go wyczyścić.

Uruchomiłem git reset --hard origin/master: P

Następnie wszystkie moje lokalne pliki zostały usunięte, ponieważ repo było puste. Myślałem, że wszystko zniknęło.

To uratowało mi życie:

git reflog show
git reset HEAD@{1} 
git push 

Mam nadzieję, że ocali kolejne życie.

Orcun
źródło
Dla mnie było to: git reset HEAD@\{27\} Dziękuję!
4oby
1
Mam 7 zatwierdzeń do zresetowania, używam git reflog showdo sprawdzania i od pierwszego zatwierdzenia używamgit reset HEAD@{number}
Vishwas Nahar
38

Jeśli używasz czegoś takiego jak IntelliJ:

W menu kontekstowym wybierz Historia lokalna i kliknij Pokaż historię w podmenu:

Widok lokalnej historii projektu lub folderu pokazuje wszystko, co zrobiłeś w ciągu ostatnich kilku dni. W kolumnie Akcja w dolnej części okna dialogowego wybierz akcję, którą chcesz wycofać. [...] W ten sposób górna część okna dialogowego pokazuje widok drzewa zmienionych plików. Jeśli chcesz przywrócić tylko usunięty plik, niezależnie od innych zmian, które zostały wprowadzone od tego czasu, możesz wybrać plik Lost.txt w widoku drzewa i kliknąć przycisk Cofnij.

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

To właśnie wyciągnęło mój tyłek z ognia!

JonathanTien
źródło
To zdecydowanie najlepsza odpowiedź dla użytkowników IntelliJ! Dziękuję bardzo, to działało idealnie. Wypróbowałem każde inne rozwiązanie i żadne z nich nie działało dobrze. git reflognie działało, ponieważ nie zatwierdziłem zmian. git fsck --lost-foundpracował dla plików etapowych, ale nie wszystkie zostały zainscenizowane. Historia lokalna IntelliJ doskonale odzyskała moje niezapisane pliki, jestem bardzo wdzięczna za tę funkcję
Denes Papp
30

Właśnie zrobiłem git reset --hardi straciłem wszystkie moje niezaangażowane zmiany. Na szczęście korzystam z edytora (IntelliJ) i udało mi się odzyskać zmiany z Historii lokalnej. Zaćmienie powinno pozwolić ci zrobić to samo.

użytkownik1147827
źródło
19

Z definicji git reset --hardwyrzuci niezatwierdzone zmiany bez możliwości ich odzyskania przez Git (system kopii zapasowej może pomóc, ale nie Git).

W rzeczywistości jest bardzo niewiele przypadków, w których git reset --hardjest to dobry pomysł. W większości przypadków istnieje bezpieczniejsze polecenie, aby zrobić to samo:

  • Jeśli chcesz wyrzucić niezatwierdzone zmiany, użyj git stash. Będzie przechowywać kopię zapasową tych zmian, które wygasną po pewnym czasie, jeśli uruchomisz git gc. Jeśli masz 99,9% pewności, że nigdy nie będziesz potrzebować tych zmian, git stashto nadal jesteś przyjacielem w przypadku 0,1%. Jeśli masz 100% pewności, git stashto nadal jest twoim przyjacielem, ponieważ te 100% ma błąd pomiaru ;-).

  • Jeśli chcesz przenieść swoją HEADi czubek bieżącej gałęzi w historii, git reset --keepto twój przyjaciel. Zrobi to samo git reset --hard, ale nie odrzuci twoich lokalnych zmian.

  • Jeśli chcesz zrobić jedno i drugie, git stash && git reset --keepto twój przyjaciel.

Naucz palce, aby nie używać git reset --hard, to spłaci jeden dzień.

Matthieu Moy
źródło
więc jeśli ktoś to git stash && git reset --hardusunie wszelkie ukryte treści, to prawda?
jxramos
1
Nie, git reset --hardnie odrzuca skrytki. git stashjest zamiennikiem git reset --hardw tym sensie, że usuwa nieprzewidziane zmiany z twojego środowiska roboczego, z tym wyjątkiem, że zapewnia im bezpieczeństwo, a nie odrzuca je na stałe.
Matthieu Moy,
lub po prostu zatwierdź swoje zmiany, zanim zresetujesz je mocno, a będą one nadal w lokalnym repozytorium
ThaJay
11

jeśli przypadkowo mocno zresetujesz zatwierdzenie, zrób to,

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

zakładając, że HEAD@{2}jest to stan, do którego chcesz wrócić

Edwin Ikechukwu Okonkwo
źródło
to działało idealnie dla mnie, jeśli robisz to w PowerShell, pamiętaj, aby napisać to tak, jak ten reset git 'HEAD @ {2}' w przeciwnym razie nie będzie działać w PowerShell
VectorX
10

Tak zwykle robię, jeśli stracę jakieś zmiany.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

aby przesunąć wskaźnik z powrotem do poprzednich zatwierdzeń, ale zachowując zmiany, które wprowadziłeś do tej pory w ostatniej kasie zatwierdzeń git reset --soft dadada

Smoczy rycerz
źródło
8

Informacje zostały utracone.

Ponieważ nie zrobiłeś tego, Twój .git nigdy nie przechowywał tych informacji. Zasadniczo gitnie można go odzyskać.

Ale jeśli właśnie to zrobiłeś git diff, istnieje sposób na odzyskanie danych za pomocą danych wyjściowych terminala za pomocą 3 prostych kroków.

  1. przewiń terminal i poszukaj o / p git diff. Zapisz o / p w pliku o nazwie diff.patch
  2. Wyszukaj i zamień wszystkie 7 spacji i 8 spacji znakiem tab (\ t) i zapisz zmiany.
  3. Przejdź do swojego repozytorium git. Zastosuj diff.patch ( patch -p1 < diff.patch)

Jesteś uratowany! :)

Uwaga: Podczas kopiowania danych z terminala do pliku należy zachować ostrożność i wyraźnie zobaczyć, że dane są ciągłym wyjściem i nie zawierają żadnych zbędnych danych (z powodu naciskania strzałek w górę i w dół). W przeciwnym razie możesz to zepsuć.

mk ..
źródło
7

Natknąłem się na ten sam problem i prawie oszalałem ... początkowo popełniłem projekt i połączyłem się. Później, kiedy próbowałem uruchomić, git push --set-upstream origin master otrzymywałem ten błąd

  fatal: refusing to merge unrelated histories

więc pobiegłem git reset --hard HEADi usunąłem 3-tygodniowy projekt, ale kilka poniższych poleceń oszczędza dzień:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

mam nadzieję że to pomoże

Slycreator
źródło
6

Możesz odzyskać zatwierdzenie po wykonaniu reset --hard HEAD.

Skorzystaj z „ git reflog”, aby sprawdzić historię HEADoddziału.

Zobaczysz tutaj swoje zatwierdzenie i jego identyfikator.

Zrób

git reset {commit Id of the commit you want to bring back}
rachana acharya
źródło
5

Jeśli na szczęście te same pliki zostały otwarte w innym edytorze (np. Sublime Text), spróbuj na nich ctrl-z. Właśnie mnie uratowało ...

Gabe
źródło
3

Dowiedziałem się na własnej skórze, że wszelkie niezaangażowane pliki przed git reset --hard <commit>usunięciem z historii git. Miałem jednak szczęście, że utrzymałem sesję edytora kodu otwartą przez cały czas, gdy wyciągałem włosy, i odkryłem, że prosty control + zw każdym z dotkniętych plików przywrócił stan pliku do wersji sprzed Gita, więc uprzejmie zresetować wszystko, o co konkretnie nie prosiłem.Hooray!!

Friendly-Robot
źródło
3

Jeśli próbujesz użyć kodu poniżej:

git reflog show
# head to recover to
git reset HEAD@{1} 

i z jakiegoś powodu otrzymujesz:

błąd: nieznany przełącznik `e '

następnie spróbuj zawinąć HEAD@{1}w cytaty

git reset 'HEAD@{1}'
Rdza
źródło
3
 git reset HEAD@{4}

4 to zmiany sprzed 4 kroków. jeśli wybierzesz prawidłowy krok, powinien wyświetlić listę plików, które zostały usunięte z dysku twardego. następnie wykonaj:

$ git reflog show

pokaże Ci historię lokalnych zatwierdzeń, którą już stworzyliśmy. teraz wykonaj:

$ git reset --hard 8c4d112

8c4d112 to kod, który chcesz tam zresetować. spójrzmy na https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history, aby uzyskać więcej informacji.

mohammad
źródło
Wielkie dzięki @mohammad, uratowało mnie to. Nie widziałem wcześniej moich plików źródłowych, ale wykonując powyższe kroki udało mi się odzyskać wszystkie moje pliki źródłowe.
Gaurav Bansal
2

Poprawne odpowiedzi. OK, teraz lubię gita. :-) Oto prostszy przepis.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Gdzie „2” oznacza liczbę wstecz do miejsca, w którym dokonałeś zmian. W moim przypadku przerwany przez kolegę i szefa, aby pomóc w debugowaniu jakiegoś problemu z kompilacją; więc zrobił reset - twardy dwa razy; więc HEAD i HEAD @ {1} zostały nadpisane. Uff, straciłby naszą ciężką pracę.

TimJowers2
źródło
2

git reset --hardPrzez pomyłkę zrobiłem niewłaściwy projekt (wiem ...). Właśnie pracowałem nad jednym plikiem i nadal był otwarty podczas i po uruchomieniu polecenia.

Mimo że się nie popełniłem, udało mi się odzyskać stary plik za pomocą prostego COMMAND + Z.

Daniel Segura
źródło
0

Referencyjna odpowiedź z tego SO,

Po uruchomieniu git reflog show powiedz, że chcesz przejść do zatwierdzenia 9300f9d

po uruchomieniu git reset 9300f9d

możesz zrobić status git, a następnie może być konieczne wyewidencjonowanie plików, aby przywrócić zmiany

git checkout - ścieżka / nazwa pliku

Daniel
źródło
0

Jeśli tworzysz w Netbeans, spójrz między zakładkami plików i obszarem edycji pliku. Istnieje „Źródło” i „Historia”. W „Historii” zobaczysz zmiany wprowadzone przy użyciu kontroli wersji (git / other), ale także zmiany wprowadzone lokalnie. W takim przypadku zmiany lokalne mogą Cię uratować.

Pedro Alvares
źródło
0

( odpowiedź odpowiednia dla podzbioru użytkowników )

Jeśli korzystasz z (dowolnego) systemu macOS i nawet jeśli nie masz dostępu do dysku Time Machine, system operacyjny będzie zapisywał cogodzinne kopie zapasowe, zwane lokalnymi migawkami .

Wejdź do Time Machine i przejdź do utraconego pliku. System operacyjny zapyta Cię:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Powinieneś być w stanie odzyskać utracone pliki.

Calaf
źródło
0

Jeśli masz otwarte IDE z tym samym kodem, spróbuj ctrl + z dla każdego pliku, w którym dokonałeś zmian. Pomógł mi odzyskać moje niezaangażowane zmiany po resecie git - hard.

dwarakesh tp
źródło
-3

Kiedy wykonujemy reset git - twardy i wszystkie lokalne niezaangażowane zmiany są usuwane. Aby przywrócić zmiany - w IDE kliknij plik, porównaj plik z Historią lokalną, która wyświetli zmiany według daty i możemy odzyskać dane. Twój dzień jest uratowany!

Roopa
źródło
1
Ta odpowiedź powtarza dwa wcześniejsze.
isherwood,