Próbuję odzyskać swoją pracę. Głupio to zrobiłem git reset --hard
, ale wcześniej robiłem tylko get add .
i nie robiłem git commit
. Proszę pomóż! Oto mój dziennik:
MacBookPro:api user$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# modified: .gitignore
...
MacBookPro:api user$ git reset --hard
HEAD is now at ff546fa added new strucuture for api
Czy git reset --hard
w tej sytuacji można cofnąć ?
Odpowiedzi:
Powinieneś być w stanie odzyskać wszystkie pliki, które dodałeś do indeksu (np. Tak jak w twojej sytuacji
git add .
), chociaż może to wymagać trochę pracy. Aby dodać plik do indeksu, git dodaje go do bazy danych obiektów, co oznacza, że można go odzyskać, o ile jeszcze nie nastąpiło czyszczenie pamięci. Oto przykład, jak to zrobić, podany w odpowiedzi Jakuba Narębskiego :Jednak wypróbowałem to w repozytorium testowym i było kilka problemów -
--cached
powinno być--cache
i stwierdziłem, że w rzeczywistości nie utworzyło.git/lost-found
katalogu. Jednak następujące kroki zadziałały dla mnie:Powinno to wyprowadzić wszystkie obiekty w bazie danych obiektów, które nie są osiągalne przez żaden ref, w indeksie ani przez reflog. Wynik będzie wyglądał mniej więcej tak:
... i dla każdego z tych plamek możesz:
Aby wyświetlić zawartość pliku.
Za dużo produkcji?
Aktualizacja w odpowiedzi na sehe „s komentarz poniżej:
Jeśli zauważysz, że masz wiele zatwierdzeń i drzew wyświetlonych w danych wyjściowych tego polecenia, możesz chcieć usunąć z wyniku wszelkie obiekty, do których istnieją odniesienia z zatwierdzeń bez odniesienia. (Zazwyczaj i tak możesz wrócić do tych zatwierdzeń przez reflog - interesują nas tylko obiekty, które zostały dodane do indeksu, ale nigdy nie można ich znaleźć za pomocą zatwierdzenia).
Najpierw zapisz dane wyjściowe polecenia, używając:
Teraz nazwy obiektów tych nieosiągalnych zatwierdzeń można znaleźć za pomocą:
Możesz więc znaleźć tylko drzewa i obiekty, które zostały dodane do indeksu, ale w żadnym momencie nie zostały zatwierdzone, za pomocą:
To ogromnie zmniejsza liczbę obiektów, które musisz wziąć pod uwagę.
Aktualizacja: Philip Oakley poniżej sugeruje inny sposób ograniczenia liczby obiektów do rozważenia, czyli po prostu uwzględnienie ostatnio zmodyfikowanych plików w ramach
.git/objects
. Możesz je znaleźć za pomocą:(Znalazłem to
find
wywołanie tutaj .) Koniec tej listy może wyglądać następująco:W takim przypadku możesz zobaczyć te obiekty za pomocą:
(Zauważ, że musisz usunąć
/
na końcu ścieżki, aby uzyskać nazwę obiektu.)źródło
Właśnie zrobiłem
git reset --hard
i straciłem jedno zatwierdzenie. Ale znałem wartość skrótu zatwierdzenia, więc mogłemgit cherry-pick COMMIT_HASH
go przywrócić.Zrobiłem to w ciągu kilku minut od utraty zatwierdzenia, więc może to zadziałać dla niektórych z was.
źródło
git reflog
np.git reset --hard
->git reflog
(patrząc na hash HEAD @ {1}) i wreszciegit cherry-pick COMMIT_HASH
git reset --hard
(zakładając, że nie mają niczego innego po tej komendzie zrobione) jestgit reset --hard @{1}
Dzięki Markowi Longairowi odzyskałem swoje rzeczy!
Najpierw zapisałem wszystkie skróty do pliku:
następnie umieszczam je wszystkie (usuwając `` nieosiągalny blob '') na liście i umieszczam wszystkie dane w nowych plikach ... musisz wybrać swoje pliki i zmienić ich nazwy, których potrzebujesz ... ale potrzebowałem tylko kilku pliki ... mam nadzieję, że to komuś pomoże ...
źródło
mkdir lost; git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") | grep -Po '\s\S{40}$' | xargs -i echo "git show {} > lost/{}.blob" | sh
. Pliki skończą się nalost/*.blob
Rozwiązanie @ Ajedi32 w komentarzach działało dla mnie dokładnie w tej sytuacji.
Zauważ, że wszystkie te rozwiązania polegają na tym, że nie ma git gc, a niektóre z nich mogą powodować jeden z nich, więc spakowałbym zawartość twojego katalogu .git przed wypróbowaniem czegokolwiek, abyś miał migawkę, do której możesz wrócić, jeśli nie. nie działa dla ciebie.
źródło
git reset --hard
, co zepsuło moje repozytorium w nieznany sposób. @Duncan, co robi @ {1}? i do którego komentarza się odnosisz? Czy to resetujegit reset
?Wpadłem na ten sam problem, ale nie dodałem zmian do indeksu. Więc wszystkie powyższe polecenia nie przywróciły pożądanych zmian.
Po wszystkich powyższych wyszukanych odpowiedziach jest to naiwna wskazówka, ale może uratuje kogoś, kto nie pomyślał o tym pierwszy, tak jak ja.
Zrozpaczony, próbowałem nacisnąć CTRL-Z w moim edytorze (LightTable), raz w każdej otwartej karcie - to na szczęście przywróciło plik na tej karcie do jego najnowszego stanu przed
git reset --hard
. HTH.źródło
Jest to prawdopodobnie oczywiste dla specjalistów od gitów, ale chciałem to wyjaśnić, ponieważ w moich gorączkowych poszukiwaniach nie widziałem tego.
Wystawiłem kilka plików i
git reset --hard
trochę się wystraszyłem, a potem zauważyłem, że mój status pokazał, że wszystkie moje pliki są nadal w fazie przejściowej, a wszystkie ich usunięcia nie znajdują się na etapie.W tym momencie możesz zatwierdzić te etapowe zmiany, o ile nie przygotujesz ich usuwania. Po tym musisz tylko zebrać się na odwagę
git reset --hard
jeden raz, co spowoduje powrót do tych zmian, które zainscenizowałeś, a teraz właśnie dokonałeś.Ponownie, prawdopodobnie dla większości nie jest to nic nowego, ale mam nadzieję, że skoro mi pomogło i nie znalazłem nic, co by to sugerowało, może pomóc komuś innemu.
źródło
Boże, szarpałem się za włosy, dopóki nie natrafiłem na to pytanie i odpowiedzi. Uważam, że poprawna i zwięzła odpowiedź na zadane pytanie jest dostępna tylko wtedy, gdy połączysz dwa z powyższych komentarzy, więc tutaj wszystko jest w jednym miejscu:
Jak wspomniano w chilicuil, uruchom tam,
git reflog
aby zidentyfikować skrót zatwierdzenia, do którego chcesz wrócićJak wspomniał akimsko, prawdopodobnie NIE będziesz chciał wybierać wiśni, chyba że straciłeś tylko jedno zatwierdzenie, więc powinieneś wtedy uciekać
git reset --hard <hash-commit-you-want>
Uwaga dla użytkowników egit Eclipse: nie mogłem znaleźć sposobu na wykonanie tych kroków w Eclipse z egit. Zamknięcie Eclipse, uruchomienie powyższych poleceń z okna terminala, a następnie ponowne otwarcie Eclipse działało dobrze dla mnie.
źródło
Powyższe rozwiązania mogą działać, jednak istnieją prostsze sposoby na naprawienie tego problemu zamiast przechodzenia przez
git
złożone cofanie. Domyślam się, że większość resetów git ma miejsce na niewielkiej liczbie plików, a jeśli już używasz VIM, może to być najbardziej efektywne czasowo rozwiązanie. Zastrzeżenie polega na tym, że już musisz używaćViM's
trwałego cofania, którego powinieneś używać w obu przypadkach, ponieważ zapewnia to możliwość cofnięcia nieograniczonej liczby zmian.Oto kroki:
W vimie naciśnij
:
i wpisz polecenieset undodir
. Jeślipersistent undo
włączyłeś w swoim.vimrc
, pokaże wynik podobny doundodir=~/.vim_runtime/temp_dirs/undodir
.W swoim repozytorium użyj,
git log
aby znaleźć datę / godzinę ostatniego zatwierdzeniaW swojej powłoce przejdź do
undodir
usingcd ~/.vim_runtime/temp_dirs/undodir
.W tym katalogu użyj tego polecenia, aby znaleźć wszystkie pliki, które zmieniłeś od ostatniego zatwierdzenia
find . -newermt "2018-03-20 11:24:44" \! -newermt "2018-03-23" \( -type f -regextype posix-extended -regex '.*' \) \-not -path "*/env/*" -not -path "*/.git/*"
Tutaj „2018-03-20 11:24:44” to data i godzina ostatniego zatwierdzenia. Jeśli data wykonania
git reset --hard
to „2018-03-22”, użyj „2018-03-22”, a następnie „2018-03-23”. Dzieje się tak z powodu dziwactwa znalezienia, w którym dolna granica jest włącznie, a górna jest wyłączna. https://unix.stackexchange.com/a/70404/242983Następnie przejdź do każdego z plików, otwórz je w vimie i zrób „wcześniej 20m”. Więcej informacji na temat „wcześniej” można znaleźć, używając „h wcześniej”. Tutaj
earlier 20m
oznacza powrót do stanu pliku 20 minut wstecz, zakładając, że zrobiłeśgit hard --reset
, 20 minut wstecz. Powtórz to dla wszystkich plików, które zostały wyplute zfind
polecenia. Jestem pewien, że ktoś może napisać skrypt, który będzie łączył te rzeczy.źródło
Używam IntelliJ i mogłem po prostu przejść przez każdy plik i wykonać:
Edit -> reload from disk
Na szczęście zrobiłem to
git status
tuż przed wymazaniem zmian roboczych, więc wiedziałem dokładnie, co muszę ponownie załadować.źródło
Zapamiętanie hierarchii plików i użycie techniki Marka Longaira z modyfikacją Phila Oakleya daje dramatyczne rezultaty.
Zasadniczo, jeśli przynajmniej dodałeś pliki do repozytorium, ale go nie zatwierdziłeś, możesz je przywrócić, używając interaktywnego
git show
dziennika, przejrzyj dziennik i użyj przekierowania powłoki, aby utworzyć każdy plik (zapamiętując ścieżkę zainteresowania).HTH!
źródło
Jeśli niedawno przeglądałeś,
git diff
to istnieje inny sposób na odzyskanie po takich incydentach, nawet jeśli jeszcze nie wprowadziłeś zmian: jeśli dane wyjściowegit diff
nadal znajdują się w buforze konsoli, możesz po prostu przewinąć w górę, skopiować i wkleić diff do pliku i użyćpatch
narzędzia do stosowania diff do drzewa:patch -p0 < file
. Takie podejście kilka razy mnie uratowało.źródło