Uzyskaj listę wszystkich zatwierdzeń git, w tym „utraconych”

139

Powiedzmy, że mam taki wykres:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Jeśli to zrobię git log --all --oneline, otrzymam wszystkie sześć zatwierdzeń.

Ale jeśli wykres jest

A---B---C---D (master, HEAD)
     \
      \-E---F

Nie zobaczę E i F. Czy mogę poprosić gita, aby powiedział mi o wszystkich zatwierdzeniach, łącznie z tymi w gałęziach, które nie są nazwane?

Dzięki

Amadan
źródło

Odpowiedzi:

63

Niezbyt łatwo - jeśli zgubiłeś wskazówkę na czubku gałęzi, to raczej jak znalezienie igły w stogu siana. Możesz znaleźć wszystkie zatwierdzenia, które nie wydają się już być przywoływane - git fsck --unreachablezrobią to za ciebie - ale będą to obejmować zatwierdzenia, które wyrzuciłeś po a git commit --amend, stare zatwierdzenia na gałęziach, które zmieniłeś itp. Itd. Więc zobacz wszystkie te zatwierdzenia naraz jest o wiele za dużo informacji, aby je przebrnąć.

Tak więc lekceważąca odpowiedź brzmi: nie trać z oczu rzeczy, które Cię interesują. Mówiąc poważnie, reflogs domyślnie zawiera odniesienia do wszystkich zatwierdzeń, których używałeś przez ostatnie 60 dni. Co ważniejsze, dadzą pewien kontekst o co te rewizje .

araqnid
źródło
7
+1: Nie ma absolutnie żadnej różnicy między zatwierdzeniem celowo osieroconym przez commit --amendlub rebase, powiedzmy, przypadkowo osieroconym przez pracę z odłączoną GŁOWĄ.
Cascabel
3
w rzeczy samej. prawdopodobnie najłatwiejszym sposobem wyjścia z tej sytuacji będzie spojrzenie na reflog dla samego HEAD.
araqnid
@Jefromi: Świetna uwaga na temat git commit --amenditp. Opuszczania ślepej uliczki , utraconych zatwierdzeń. Zrobiłem trochę ponownego bazowania i tak dalej, a skończyło się na niektórych zatwierdzeniach nieosiągalnych z żadnych gałęzi i poczułem się trochę brudny, zostawiając je w repozytorium. Teraz ta myśl nie jest już tak niepokojąca. :)
Emil Lundberg
2
@araqnid Dostałem się w tę samą marynatę, co oryginalny plakat, a twoja sugestia, aby spojrzeć na reflog, była właśnie rzeczą do zrobienia.
Ignazio
7
Zgadzam się z tą odpowiedzią, ale w przypadku, gdy ktoś musi zobaczyć wszystkie zatwierdzenia, w tym osierocone, celowe lub przypadkowe, git fsck --unreachablenie zapewnia tego. Właśnie tego spróbowałem. Lepszym podejściem jest --reflogopcja git log, jak odpowiedział kenorb . Szczególnie miłe w tym jest to, że w połączeniu z --graph, otrzymujesz łatwy do przeanalizowania kontekst wizualny, podobny do tego zilustrowanego w oryginalnym pytaniu. Na przykład spróbuj:git log --graph --all --oneline --reflog
Inigo
111

Próbować:

git log --reflog

która wyświetla listę wszystkich zatwierdzeń gita, udając, że wszystkie obiekty wymienione przez reflogs ( git reflog) są wymienione w wierszu poleceń jako <commit>.

kenorb
źródło
1
Właśnie tego szukałem - funkcjonalności argumentu --reflog.
Anomalia
3
Btw, gitk również to obsługuje: gitk --reflog.
ald.li
50

Kiedy rozwiązuję ten problem, używam następującego polecenia:

git reflog |  awk '{ print $1 }' | xargs gitk

To pozwala mi wizualizować ostatnie zatwierdzenia, które stały się bezgłowe.

Mam to zapakowane w pomocnika skryptu o nazwie ~/bin/git-reflog-gitk.

Kieran
źródło
1
To właśnie OSZCZĘDZAŁO dużo czasu ... DZIĘKUJEMY!
Bret Royster
to jest niesamowite! Dziękuję Ci! naprawdę wizualizuje ważne części drzewa.
Mladen B.
Wskazówka: będzie to działać tylko w Twojej lokalnej pracy jako rekordy reflog when the tips of branches and other references were updated in the *local repository*. Możesz użyć, git log --reflogjeśli chcesz to zrobić dla nielokalnych zmian referencyjnych
Krishna Gupta
29

To, co uratowało mi życie, to polecenie:

git reflog

Znajdziesz tam ekran z zatwierdzeniami historii wykonanymi do gita, jak ten:

wprowadź opis obrazu tutaj

W tym momencie musisz tylko znaleźć to HEAD@{X}, czego potrzebujesz, utworzyć tymczasową gałąź i przejść do niej w następujący sposób:

git checkout -b temp_branch HEAD@{X}

W ten sposób będziesz mieć tymczasową gałąź z utraconym zatwierdzeniem bez ponownego bazowania lub niszczenia jeszcze bardziej repozytorium git.

Mam nadzieję że to pomoże...

Sonhja
źródło
26

Podobnie jak odpowiedź @Kieran, ale dla konsoli: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Florian Fida
źródło
Czy musisz dołączyć ostatnią część: $ (git reflog | awk '{print $ 1}')? Co to robi? Po wypróbowaniu twojego rozwiązania wydaje się, że daje te same wyniki nawet bez tej ostatniej części.
wmock
Jeśli przesuniesz wskaźnik gałęzi i zostawisz niektóre zatwierdzenia bez odniesienia (tak jak zrobił to OP), nie będą się już pojawiać git log --all. Szybki przykład: po git reset --hard @^twoim HEAD @ {0} commit będzie tylko w reflogu, a ponieważ git reflognie obsługuje --graph, musisz przekazać commits do, git log --graphaby uzyskać wizualną reprezentację.
Florian Fida,
5
możesz użyć --reflogzamiast $(git reflog | awk '{print $1}')
Sild
W porównaniu git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')z git log --oneline --all --graph --decorate --reflognimi są prawie identyczne, z wyjątkiem --reflog zawiera szczegóły, takie jak wpisy WIP.
Script Wolf
@FlorianFida, zamiast reflogdlaczego nie użyć log --reflogzamiast tego?
Pacerier
9

Jak rozwiązać ten problem? Używaj git fscki loguj!

Najpierw utwórz plik zawierający utracone (nieosiągalne) zatwierdzenia i obiekty blob. (UWAGA: jeśli zrobiłeś coś takiego, git gcto zbierze wszystkie zatwierdzone przez nich zatwierdzenia i nie znajdziesz ich tutaj!)

$git fsck --lost-found > lost_found.commits

To daje taki plik:

zwisające popełnić dec2c5e72a81ef06963397a49c4b068540fc0dc3
zwisające blob f8c2579e6cbfe022f08345fa7553feb08d60a975
zwisające blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
zwisające blob 11cbd8eba79e01f4fd7f496b1750953146a09502
zwisające popełnić 18733e44097d2c7a800650cea442febc5344f9b3
zwisające blob 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Następnie możesz otworzyć ten plik w swoim ulubionym edytorze tekstu, aby skopiować stamtąd skróty zatwierdzenia / blogu. (* kaszel * makra Vima działają świetnie na ten * kaszel *)

Teraz możesz zalogować się ponownie z tego zatwierdzenia za pomocą czegoś takiego jak git log --oneline <commit hash>. Alternatywnie powinien działać gitk, tig lub inna przeglądarka git.

W twoim przypadku, jeśli znajdziesz hash dla zatwierdzenia F, dziennik pokaże ci coś takiego:

A---B---E---F

Szybko i łatwo! Teraz możesz znaleźć kontekst wszystkich tych wiszących zatwierdzeń.

PS Tak, wiem, późny post, ale cóż, ktoś może go tutaj znaleźć i uznać za przydatny. (Najprawdopodobniej ja za 6 miesięcy, kiedy ponownie to wygoogluję)

bsimmons
źródło
5

Miałem szczęście odzyskać zatwierdzenie, patrząc na reflog, który znajdował się pod adresem .git/logs/HEAD

Następnie musiałem przewinąć do końca pliku i znalazłem zatwierdzenie, które właśnie straciłem.

GameScripting
źródło
To właśnie skończyło się, kiedy coś schrzaniłem. Próbowałem zostać mistrzem, a Stash wzdragał się, kiedy naciskałem. Zresetowałem - twardo, po czym zdałem sobie sprawę, że popełniłem błąd. Zatwierdzenie znajdowało się w reflogu, więc sprawdziłem to, zrobiłem z niego gałąź, a następnie nacisnąłem. W końcu wszystko się udało.
David
5

Będziemy git logczasami nie jest dobry, aby dostać wszystko, popełnia szczegół, tak aby ten ...

Mac: przejdź do projektu git i wpisz:

$ nano .git/logs/HEAD

aby zobaczyć wszystkie twoje zatwierdzenia w tym lub:

$ gedit .git/logs/HEAD

aby zobaczyć wszystkie zobowiązania w tym,

możesz edytować w dowolnej ulubionej przeglądarce.

Vinod Joshi
źródło
3

@bsimmons

git fsck --lost-found | grep commit

Następnie utwórz gałąź dla każdego z nich:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Teraz wiele narzędzi pokaże graficzną wizualizację tych utraconych zatwierdzeń.

yakoda
źródło
2

Jeśli używasz GUI Git Extensions, może on pokazać graficzną wizualizację wiszących zatwierdzeń, jeśli zaznaczysz "Widok -> Pokaż odniesienia do reflogów". To pokaże wiszące zatwierdzenia w drzewie, tak jak wszystkie inne odniesienia. W ten sposób łatwiej jest znaleźć to, czego szukasz.

Zobacz ten obraz do demonstracji. Zatwierdzenia C2, C3, C4 i C5 na obrazie wiszą, ale są nadal widoczne.

Zdovc
źródło
2
git log --reflog

uratował mnie! Straciłem podczas łączenia HEAD i nie mogłem znaleźć mojego ostatniego zatwierdzenia! Nie jest wyświetlane w drzewie źródłowym, ale wcześniej git log --reflogpokazałem wszystkie moje lokalne zatwierdzenia

Sultanmyrza Kasymbekov
źródło