Holen Sie sich eine Liste aller Git-Commits, einschließlich der "verlorenen"

139

Nehmen wir an, ich habe eine Grafik wie diese:

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

Wenn ich das tue git log --all --oneline, bekomme ich alle sechs meiner Commits.

Aber wenn der Graph ist

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

Ich werde E und F nicht sehen. Kann ich git dazu bringen, mir alle Commits zu sagen, einschließlich derer in Zweigen, die nicht benannt sind?

Vielen Dank

Amadan
quelle

Antworten:

63

Nicht besonders einfach - wenn Sie den Zeiger auf die Spitze eines Astes verloren haben, ist es eher so, als würden Sie eine Nadel im Heuhaufen finden. Sie können alle Commits finden, auf die anscheinend nicht mehr verwiesen git fsck --unreachablewird - dies wird für Sie erledigt -, aber dies schließt Commits ein, die Sie nach einem git commit --amendalten Commit für Zweige, die Sie neu gegründet haben, usw. usw. weggeworfen haben. Sehen Sie sich also alle diese Commits an Sofort ist es wahrscheinlich viel zu viel Information, um durchzuwaten.

Die flippige Antwort lautet also: Verlieren Sie nicht den Überblick über die Dinge, an denen Sie interessiert sind. Im Ernst, die Reflogs enthalten standardmäßig Verweise auf alle Commits, die Sie in den letzten 60 Tagen verwendet haben. Noch wichtiger ist, dass sie einen Kontext darüber geben, was diese Commits sind .

araqnid
quelle
7
+1: Es gibt absolut keinen Unterschied zwischen einem Commit, das absichtlich von commit --amendoder verwaist ist, rebaseund einem Commit, das versehentlich durch die Arbeit mit einem abgetrennten HEAD verwaist ist.
Cascabel
3
tatsächlich. Der wahrscheinlich einfachste Weg, sich von dieser Situation zu erholen, besteht darin, sich das Reflog für HEAD selbst anzusehen.
Araqnid
@Jefromi: Großartiger Hinweis auf git commit --amendusw., der Sackgassen hinterlässt, verlorene Commits. Ich machte einige Umbasierungen und so weiter und endete mit einigen Commits, die von keinem Zweig aus erreichbar waren, und fühlte mich ein bisschen schmutzig, als ich sie im Repo zurückließ. Jetzt ist der Gedanke nicht mehr ganz so beunruhigend. :)
Emil Lundberg
2
@araqnid Ich habe mich in die gleiche Essiggurke wie das Originalplakat gebracht und Ihr Vorschlag, sich das Reflog anzusehen, war genau das Richtige.
Ignazio
7
Ich stimme dieser Antwort zu, aber für den Fall, dass jemand alle Commits sehen muss, einschließlich verwaister, ob absichtlich oder versehentlich, git fsck --unreachablebietet dies nicht. Ich habe es gerade versucht. Der bessere Ansatz ist die --reflogOption für git log, wie Kenorb antwortete . Das Schöne daran ist, dass Sie in Kombination mit --grapheinen leicht zu analysierenden visuellen Kontext erhalten, ähnlich dem in der ursprünglichen Frage dargestellten. Versuchen Sie zum Beispiel:git log --graph --all --oneline --reflog
Inigo
111

Versuchen:

git log --reflog

Hier werden alle Git-Commits aufgelistet, indem vorgetäuscht wird, dass alle von reflogs ( git reflog) erwähnten Objekte in der Befehlszeile als aufgeführt sind <commit>.

Kenorb
quelle
1
Dies ist, wonach ich gesucht habe - die Funktionalität des --reflog-Arguments.
Anomalie
3
Übrigens unterstützt gitk auch Folgendes: gitk --reflog.
ald.li
50

Wenn ich dieses Problem behebe, verwende ich den folgenden Befehl:

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

Auf diese Weise kann ich die jüngsten Commits visualisieren, die kopflos geworden sind.

Ich habe dies in einen Skript-Helfer namens eingepackt ~/bin/git-reflog-gitk.

Kieran
quelle
1
Das hat mich gerade gerettet ... DANKE!
Bret Royster
das ist fantastisch! Danke! Es visualisiert wirklich die wichtigen Teile des Baumes.
Mladen B.
Nur ein Tipp: Dies funktioniert nur für Ihre lokale Arbeit als Reflog-Datensatz when the tips of branches and other references were updated in the *local repository*. Sie können verwenden, git log --reflogwenn Sie dies für nicht-lokale Ref-Änderungen tun möchten
Krishna Gupta
29

Was mein Leben gerettet hat, war der folgende Befehl:

git reflog

Dort finden Sie einen Bildschirm mit Verlaufs-Commits, die für Git wie diesen ausgeführt wurden:

Geben Sie hier die Bildbeschreibung ein

Zu diesem Zeitpunkt müssen Sie nur das finden HEAD@{X}, was Sie benötigen, einen temporären Zweig erstellen und wie folgt dorthin wechseln:

git checkout -b temp_branch HEAD@{X}

Auf diese Weise haben Sie einen temporären Zweig mit Ihrem verlorenen Commit, ohne Ihr Git-Repository neu zu gründen oder zu beschädigen.

Hoffe das hilft...

Sonhja
quelle
26

Wie @Kierans Antwort, aber für die Konsole: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Florian Fida
quelle
Müssen Sie den letzten Teil einfügen: $ (git reflog | awk '{print $ 1}')? Was macht das? Nachdem Sie Ihre Lösung ausprobiert haben, scheint sie auch ohne diesen letzten Teil dieselbe Ausgabe zu erzeugen.
wmock
Wenn Sie Ihren Verzweigungszeiger bewegen und einige Commits ohne Referenz belassen (wie dies bei OP der Fall war), werden sie nicht mehr angezeigt git log --all. Ein kurzes Beispiel: Nach einem git reset --hard @^HEAD @ {0} -Commit befindet es sich nur noch im Reflog. Da git reflogdies nicht unterstützt wird --graph, müssen Sie die Commits übergeben git log --graph, um eine visuelle Darstellung zu erhalten.
Florian Fida
5
Sie können --refloganstelle von $(git reflog | awk '{print $1}')
Sild
Im Vergleich git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')dazu git log --oneline --all --graph --decorate --reflogsind sie fast identisch, außer dass --reflog Details wie WIP-Einträge enthielt.
Skript Wolf
@FlorianFida, anstatt reflogwarum nicht log --reflogstattdessen verwenden?
Pacerier
9

Wie löse ich dieses Problem? Verwenden git fsckund protokollieren!

Erstellen Sie zunächst eine Datei mit verlorenen (nicht erreichbaren) Commits und Blobs. (HINWEIS: Wenn Sie so etwas getan haben git gc, werden alle festgeschriebenen Commits im Müll gesammelt und Sie werden sie hier nicht finden!)

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

Das gibt Ihnen eine Datei wie diese:

baumelnden begehen dec2c5e72a81ef06963397a49c4b068540fc0dc3
baumelnden blob f8c2579e6cbfe022f08345fa7553feb08d60a975
baumelnden blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
baumelnden blob 11cbd8eba79e01f4fd7f496b1750953146a09502
baumelnden begehen 18733e44097d2c7a800650cea442febc5344f9b3
baumelnden blob 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Sie können diese Datei dann mit Ihrem bevorzugten Texteditor öffnen, um die Commit- / Blog-Hashes von dort zu kopieren. (* Husten * Vim-Makros eignen sich hervorragend für diesen * Husten *)

Jetzt können Sie sich mit so etwas wie von diesem Commit zurückmelden git log --oneline <commit hash>. Alternativ sollte gitk, tig oder ein anderer git-Viewer funktionieren.

In Ihrem Fall, wenn Sie den Hash für Commit F finden, zeigt Ihnen das Protokoll ungefähr Folgendes:

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

Schnell und einfach! Jetzt können Sie den Kontext hinter all diesen baumelnden Commits finden.

PS Ja, ich weiß, später Beitrag, aber na ja, jemand könnte ihn hier finden und nützlich finden. (Höchstwahrscheinlich ich in 6 Monaten, wenn ich dies wieder google)

bsimmons
quelle
5

Ich hatte Glück, das Commit wiederherzustellen, indem ich mir das Reflog ansah, das sich bei befand .git/logs/HEAD

Ich musste dann bis zum Ende der Datei scrollen und fand das Commit, das ich gerade verloren hatte.

GameScripting
quelle
Das ist es, was ich gerade getan habe, als ich etwas vermasselt habe. Versuchte, sich zum Meister zu verpflichten, und Stash schreckte zurück, als ich drückte. Ich habe --hard zurückgesetzt und dann meinen Fehler erkannt. Das Commit war im Reflog, also habe ich es ausgecheckt, einen Zweig daraus gemacht und das dann verschoben. Am Ende hat alles geklappt.
David
5

Wir werden git logmanchmal nicht gut sein, um alle Commits-Details zu erhalten, also sehen Sie sich das an ...

Für Mac: Steigen Sie in Ihr Git-Projekt ein und geben Sie Folgendes ein:

$ nano .git/logs/HEAD

um Ihnen alle Commits darin anzuzeigen, oder:

$ gedit .git/logs/HEAD

um Ihnen alle Commits darin anzuzeigen,

Dann können Sie in jedem Ihrer Lieblingsbrowser bearbeiten.

Vinod Joshi
quelle
3

@bsimmons

git fsck --lost-found | grep commit

Erstellen Sie dann für jeden einen Zweig:

$ 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

Jetzt zeigen Ihnen viele Tools eine grafische Visualisierung dieser verlorenen Commits.

Yakoda
quelle
2

Wenn Sie die GUI von Git Extensions verwenden, können Sie eine grafische Visualisierung der baumelnden Commits anzeigen, wenn Sie "Ansicht -> Reflog-Referenzen anzeigen" aktivieren. Dies zeigt baumelnde Commits im Baum, genau wie alle anderen, auf die verwiesen wird. Auf diese Weise ist es viel einfacher zu finden, wonach Sie suchen.

Sehen Sie sich dieses Bild zur Demonstration an. Die Commits C2, C3, C4 und C5 im Bild baumeln, sind aber weiterhin sichtbar.

Zdovc
quelle
2
git log --reflog

rettete mich! Ich habe meine beim Zusammenführen von HEAD verloren und konnte nicht feststellen, dass meine Lates sich verpflichten! Wird nicht im Quellbaum angezeigt, git log --reflogzeigt jedoch alle meine lokalen Commits an

Sultanmyrza Kasymbekov
quelle