Co dzieje się z zatwierdzeniami git utworzonymi w odłączonym stanie HEAD?

137

To jest to, co się stało:

Mam gałąź A. W oddziale AI wprowadził szereg zmian. Nie byłem zadowolony z kodu, więc sprawdziłem poprzedni commit w gałęzi A. Następnie wprowadziłem kilka zmian i zatwierdziłem je w gałęzi A. Teraz nie mogę nigdzie znaleźć tego zatwierdzenia. Czy zgubiłem ten kod?

Mausimo
źródło
Kiedy mówisz „Sprawdziłem poprzedni commit w gałęzi A”, czy masz na myśli „Zresetowałem gałąź A do poprzedniego zatwierdzenia”? tj. czy git resetraczej wolałeś niż git checkout?
CB Bailey
Nie, użyłem kasy. reflog działał.
Mausimo
Jeśli użyłeś checkout, będziesz na odłączonym, HEADa gałąź A pozostałaby na poprzednim zatwierdzeniu. Jakie dokładnie polecenia wykonałeś?
CB Bailey
1
Używałem GUI SourceTree GIT na OSX Lion. Byłem w gałęzi A i sprawdziłem poprzednie zatwierdzenie w gałęzi A. Następnie dokonałem kilku zmian w kodzie i zatwierdziłem (gałąź A). Wydaje mi się, że miałem odłączoną GŁOWĘ.
Mausimo
OK, myślę, że był zmieszany, gdy powiedział, że popełnił grono więcej zmian na gałęzi .
CB Bailey

Odpowiedzi:

185

Stary commit jest nadal w reflogu.

git reflog

Spowoduje to wyświetlenie listy zatwierdzeń i powinno tam znajdować się „utracone” zatwierdzenie. Możesz zrobić to w nowej gałęzi. Na przykład, jeśli SHA-1 to ba5a739, możesz utworzyć nową gałąź o nazwie „nowa-gałąź” w starym zatwierdzeniu za pomocą:

git branch new-branch ba5a739

Zauważ, że „utracone” zatwierdzenia zostaną usunięte po wyczyszczeniu bazy danych.

Dietrich Epp
źródło
3
Zrobiłem to samo i prawie miałem zawał serca, myśląc, że zginął. Dzięki za informację!
Chase
14
Użyj, git cherry-pick [SHA]aby przenieść zatwierdzenie na istniejący oddział na wypadek, gdybyś przypadkowo popełnił błąd w stanie odłączonej głowy
Jan Aagaard Meier
3
Alternatywnie możesz przełączyć się na istniejącą gałąź i wykonać „git merge HEAD @ {n}” n odpowiadające „utraconemu” zatwierdzeniu wymienionemu w reflogu.
eaykin
Czy wiesz, czy pruneusunąłoby również odłączone zatwierdzenia, do których odwołują się komunikaty o zatwierdzeniach? Czy to sprawia, że ​​są osiągalne ?
Kamafeather
@Kamafeather: Nie sądzę, że to czyni je osiągalnymi.
Dietrich Epp
63

Twoje zatwierdzenia są nadal dostępne w reflogu, jak już wspomniano. Oprócz innych odpowiedzi, oto sposób na przejęcie odłączonych zatwierdzeń HEAD bezpośrednio do bieżącej gałęzi , bez tworzenia i scalania nowej gałęzi:

  1. Wyszukaj skróty SHA-1 zatwierdzeń, które wykonałeś w odłączonym stanie HEAD

    git reflog
    
  2. Następnie wykonaj, ze wszystkimi skrótami zatwierdzeń uporządkowanymi od najstarszego do najnowszego:

    git cherry-pick <hash1> <hash2> <hash3> ...
    

    Na przykład gdybym miał tylko jeden, podany w formacie skrótu „pierwszych 7 znaków”:

    git cherry-pick a21d053
    

Spowoduje to utworzenie nowych zatwierdzeń do Twojej bieżącej gałęzi, po jednym zatwierdzeniu na odłączony skrót-HEAD-commit, który wymienisz w poleceniu. Przejmuje również oryginalne komunikaty o zatwierdzeniach.

taniusz
źródło
11

Możesz znaleźć zagubione (wiszące) zatwierdzenia za pomocą następującego polecenia:

git fsck --lost-found

Zauważ, że jeśli twoja obecna głowa jest zwisającym zatwierdzeniem, nie jest wymieniona jako utracona.

Możesz znaleźć więcej informacji na stronie podręcznika git-fsck (1)

Następnie możesz utworzyć gałąź na tym utraconym zatwierdzeniu:

git branch new-branch ba5a739
sergtk
źródło
Najpierw użyłem polecenia „git reflog”, a następnie „git branch new-branch ba5a739” dla podmodułu, zadziałało.
ondermerol
7

Terminem Gita określającym stan katalogu roboczego jest „ odłączony HEAD ”. Oto kolejne miejsce, git reflogw którym oszczędzasz.

$ git reflog
0b40dd6 HEAD@{0}: commit: my commit on detached HEAD
...

Jeśli spróbuję wyewidencjonować inną gałąź, git-1.7.5.1 daje pomocną sugestię.

Mistrz kasy $ git
Ostrzeżenie: zostawiasz 1 zatwierdzenie za, bez połączenia
którykolwiek z Twoich oddziałów:

  0b40dd6 moje zatwierdzenie na odłączonym HEAD

Jeśli chcesz je zachować, tworząc nową gałąź, może to być dobry moment
aby to zrobić z:

 oddział git nazwa_nowy_branch 0b40dd65c06bb215327863c2ca10fdb4f904215b

Przełączono na „master” gałęzi
Greg Bacon
źródło
Dzięki za informację i link. Link pomógł mi zrozumieć, co się dzieje.
Mausimo
6

Nie zgubiłeś tego, Git nadal zachowuje kopię (ale obecnie jest nieosiągalna dla żadnej gałęzi). Możesz znaleźć brakujące zatwierdzenie za pomocą git reflogpolecenia. Reflog śledzi historyczne pozycje główki gałęzi i możesz go użyć do znalezienia rzeczy, na które główka gałęzi wskazywała wcześniej.

Greg Hewgill
źródło
4

Wykonaj następujące kroki, aby połączyć odłączoną głowicę z powrotem z repozytorium git

  1. git checkout "your branch with path but without remote name"

np. jeśli zdalna nazwa jest źródłem, a nazwa gałęzi jest bugfix/somebranchużywanagit checkout bugfix/somebranch

  1. git reflog pobierz listę zmian SHA zatwierdzeń z listy zmian w odłączonej gałęzi.

  2. git cherry-pick "commit hash1" "commit hash2" "commit hash3"

  3. git push

WSZYSTKO GOTOWE!!

user1520615
źródło
2

W Sourcetree odkryłem, że git reflog nie działa, więc wymyśliłem, jak to zrobić, używając GUI.

Najpierw spróbuj znaleźć „utracone” zatwierdzenie, szukając komunikatu w historii poleceń (widok: Pokaż dane wyjściowe polecenia). Miejmy nadzieję, że znajdzie się on w poleceniu „Switching Branch” po zatwierdzeniu, które utraciłeś, a zobaczysz komentarz dotyczący zatwierdzenia z identyfikatorem zatwierdzenia 1234567.

Przejdź do następnego kroku w tym dokumencie.

Wciśnij przycisk „Rozgałęzienie” na górnym pasku narzędzi, a powinieneś otrzymać okno dialogowe „Nowa gałąź”, w którym możesz określić pewne zatwierdzenie. Umieść tam ten identyfikator zatwierdzenia, podaj nazwę nowej gałęzi, naciśnij Utwórz gałąź, a powinieneś otrzymać nową gałąź z utraconym zatwierdzeniem!

To przyniosło mi trochę straconej pracy!

blalond
źródło