2516 Stimmen

Wie kann man einen verlorenen Stash in Git wiederherstellen?

Ich verwende häufig git stash y git stash pop um Änderungen in meinem Arbeitsbaum zu speichern und wiederherzustellen. Gestern hatte ich einige Änderungen in meinem Arbeitsbaum, die ich zwischengespeichert und wiederhergestellt habe, und dann habe ich weitere Änderungen an meinem Arbeitsbaum vorgenommen. Ich würde gerne zurückgehen und die gestern gespeicherten Änderungen überprüfen, aber git stash pop scheint alle Verweise auf die zugehörige Übertragung zu entfernen.

Ich weiß, dass ich, wenn ich die git stash dann .git/refs/stash enthält die Referenz der Übergabe, die zur Erstellung des Stash verwendet wurde. Und .git/logs/refs/stash enthält den gesamten Vorrat. Aber diese Referenzen sind verschwunden, nachdem git stash pop . Ich weiß, dass der Commit noch irgendwo in meinem Repository ist, aber ich weiß nicht, was er war.

Gibt es eine einfache Möglichkeit, die gestrige Stash-Commit-Referenz wiederherzustellen?

Für mich ist das heute nicht so wichtig, weil ich tägliche Backups habe und auf den Arbeitsbaum von gestern zurückgreifen kann, um meine Änderungen zu erhalten. Ich frage, weil es einen einfacheren Weg geben muss!

14voto

Phil Punkte 3163

Ich möchte der akzeptierten Lösung eine weitere gute Möglichkeit hinzufügen, um alle Änderungen durchzugehen, wenn man entweder kein gitk oder kein X für die Ausgabe zur Verfügung hat.

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

Dann bekommen Sie alle Unterschiede für diese Hashes nacheinander angezeigt. Drücken Sie 'q', um zum nächsten Diff zu gelangen.

10voto

minTwin Punkte 781

Das hat bei mir (im Jahr 2022) funktioniert, als ich meinen versehentlich gelöschten Stash in Git aus einer Windows-Umgebung wiederherstellen wollte.

Diese Schritte beschreiben, wie gelöschte Git Stashes oder Branches wiederhergestellt werden können (vorausgesetzt, sie wurden nicht dauerhaft durch Garbage Collection gelöscht).

  1. Navigieren Sie zu dem Verzeichnis, in dem sich Ihr Projekt befindet.

  2. Geben Sie den Befehl ein: git fsck --no-reflogs | find "dangling commit" enter image description here

  3. Es wird eine Liste von Hashes für Dangling Commits angezeigt. Diese bestehen aus Zweigen und Stashes, die gelöscht wurden. Beginnen Sie mit dem Kopieren und Einfügen der Hashes am Ende der Liste, um Ihren Stash oder Zweig zu finden. Verwenden Sie zum Beispiel den Befehl: git log -1 [hash]

  4. Wenn der entsprechende Hash dem entspricht, was Sie wiederherstellen wollen, verwenden Sie den folgenden Befehl, um ihn wiederherzustellen" git stash apply [hash]

3 Stimmen

"dangling commit" keine solche Datei oder Verzeichnis

6voto

Treviño Punkte 2447

Um die Commits im Terminal zu sehen, filtern wir nur die, die uns interessieren, und verwenden sie:

git log --oneline --all --grep="^WIP on .*: [a-f0-9]\+" --grep="^On [^ ]*:" --grep="^index on [^ ]*:" $( env LANG=C git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

Dies beruht auf Aristoteles Pagaltzis Antwort.

5voto

Abhijeet Punkte 8036

Mit den folgenden Schritten wiederhergestellt:

  1. Identifizieren Sie den Hash-Code des gelöschten Verstecks:

    gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

  2. Kirschpflücken im Vorrat:

    git cherry-pick -m 1 $stash_hash_code

  3. Lösen Sie etwaige Konflikte mit:

    Git-Mergetool

Außerdem könnten Sie Probleme mit der Commit-Nachricht haben, wenn Sie Gerrit verwenden. Bitte speichern Sie Ihre Änderungen, bevor Sie die nächsten Alternativen anwenden:

  1. Setzen Sie die vorherige Übertragung zurück und führen Sie die Änderung erneut durch.
  2. Sie können die Änderung auch zwischenspeichern, zurücksetzen und erneut eingeben.

0 Stimmen

@miva2 Ihr Edit hat den Link zur richtigsten Antwort in dieser Frage entfernt. Ich füge den Link wieder in den Kommentar ein stackoverflow.com/questions/89332/

5voto

Ben Punkte 7597

Was ich hier gesucht habe, ist, wie ich den Vorrat zurückbekomme, unabhängig davon, was ich ausgecheckt habe. Insbesondere hatte ich etwas versteckt, dann eine ältere Version ausgecheckt, diese dann gepoppt, aber der Vorrat war zu diesem früheren Zeitpunkt ein No-op, also verschwand der Vorrat; ich konnte nicht einfach git stash um sie wieder auf den Stapel zu legen. Das hat bei mir funktioniert:

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

Im Nachhinein betrachtet, hätte ich Folgendes verwenden sollen git stash apply no git stash pop . Ich habe eine bisect und hatte einen kleinen Flicken, den ich bei jeder Gelegenheit anwenden wollte. bisect Schritt. Jetzt mache ich das:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.

0 Stimmen

Ist dies eine Antwort oder die Fortsetzung der Frage?

0 Stimmen

Ein bisschen von beidem. Ich habe diese Seite gefunden, weil ich ein Versteck verloren hatte und versuchte, es wiederzufinden. Mein Anwendungsfall ist eine Zweiteilung, bei der ich eine Änderung vornehmen möchte, bevor ich jeden Schritt teste. Ich habe auf die harte Tour gelernt, dass man nicht einfach pop, test, stash, bisect machen kann, weil das einen anderen Commit auf dem Stash hinterlassen kann, daher stash apply .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X