Ich verwende git stash
und git stash pop
speichere häufig Änderungen in meinem Arbeitsbaum und speichere sie. Gestern hatte ich einige Änderungen an meinem Arbeitsbaum, die ich versteckt und geknallt hatte, und dann habe ich weitere Änderungen an meinem Arbeitsbaum vorgenommen. Ich würde gerne zurückgehen und die gestrigen Änderungen überprüfen, aber git stash pop
anscheinend alle Verweise auf das zugehörige Commit entfernen.
Ich weiß, wenn ich git stash
dann .git / refs / Stash enthält die Referenz des verwendeten commit das Versteck zu erstellen. Und .git / logs / refs / stash enthält den gesamten Stash. Aber diese Referenzen sind weg git stash pop
. Ich weiß, dass sich das Commit noch irgendwo in meinem Repository befindet, aber ich weiß nicht, was es war.
Gibt es eine einfache Möglichkeit, die gestrige Stash-Commit-Referenz wiederherzustellen?
Beachten Sie, dass dies für mich heute nicht kritisch ist, da ich tägliche Backups habe und zum gestrigen Arbeitsbaum zurückkehren kann, um meine Änderungen zu erhalten. Ich frage, weil es einen einfacheren Weg geben muss!
git stash pop
, können Sie diesgit stash apply
stattdessen tun . Es macht dasselbe, außer dass es den Verweis auf den angewendeten Stash nicht entfernt.git stash
,git pull -r upstream
,git push -f origin
,git stash pop
, und Pop sagte : "fatal: log für refs / Stash ist leer". 😲 Ich habe einige dieser Antworten ausprobiert, nichts hat funktioniert. Als ich in .git / refs / stash nachgesehen habe , war der SHA da drin . Möglicherweise ein Problem beim Markieren eines Windows-Netzlaufwerks für die Offline-Synchronisierung? 🤷♂️Antworten:
Sobald Sie den Hash des von Ihnen abgelegten Stash-Commits kennen, können Sie ihn als Stash anwenden:
Oder Sie können einen separaten Zweig dafür mit erstellen
Danach können Sie mit allen normalen Werkzeugen tun, was Sie wollen. Wenn Sie fertig sind, blasen Sie einfach den Ast weg.
Den Hash finden
Wenn Sie es gerade erst geöffnet haben und das Terminal noch geöffnet ist, wird der Hash-Wert weiterhin
git stash pop
auf dem Bildschirm gedruckt (danke, Dolda).Andernfalls können Sie es unter Linux, Unix oder Git Bash für Windows finden:
... oder mit Powershell für Windows:
Dies zeigt Ihnen alle Commits an den Spitzen Ihres Commit-Diagramms, auf die von keinem Zweig oder Tag mehr verwiesen wird. Jedes verlorene Commit, einschließlich jedes Stash-Commits, das Sie jemals erstellt haben, befindet sich irgendwo in diesem Diagramm.
Der einfachste Weg, das gewünschte Stash-Commit zu finden, besteht wahrscheinlich darin, diese Liste an
gitk
folgende Adresse zu übergeben :... oder sehen Sie die Antwort von Emragins, wenn Sie Powershell für Windows verwenden.
Dadurch wird ein Repository-Browser gestartet, der Ihnen jedes einzelne Commit im Repository anzeigt , unabhängig davon, ob es erreichbar ist oder nicht.
Sie können
gitk
dort durch etwas ersetzen ,git log --graph --oneline --decorate
wenn Sie ein schönes Diagramm auf der Konsole einer separaten GUI-App vorziehen.Suchen Sie nach Festschreibungsnachrichten dieses Formulars, um Stash-Commits zu erkennen:
WIP on somebranch : commithash Eine alte Commit-Nachricht
Hinweis : Die Festschreibungsnachricht liegt nur in dieser Form vor (beginnend mit "WIP ein"), wenn Sie zu diesem Zeitpunkt keine Nachricht angegeben haben
git stash
.quelle
%{ $_.Split(' ')[2]; }
das{print $3}
in diesemawk
Befehl in PowerShell entspricht, aber ich habe kein Windows-System, um das zu testen, und Sie benötigen immer noch ein Äquivalent für das/dangling commit/
Teil. Wie auch immer, lauf einfachgit fsck --no-reflog
und schau dir die Ausgabe an. Sie möchten die Hashes aus den Zeilen "Dangling Commit <commitID>".git stash save "<message>"
).git fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
Der letzte Eintrag ist wahrscheinlich der, den Sie möchtenstash apply
.git stash apply {ref}
restaurierte einen abgelegten Vorrat!git
ist so toll, dass es illegal sein sollte!Wenn Sie das Terminal nicht geschlossen haben, sehen Sie sich einfach die Ausgabe von an
git stash pop
und Sie haben die Objekt-ID des abgelegten Stashs. Normalerweise sieht es so aus:(Beachten Sie, dass
git stash drop
auch dieselbe Zeile erzeugt wird.)Um diesen Vorrat zurückzubekommen, laufen
git branch tmp 2cae03e
Sie einfach und Sie erhalten ihn als Zweig. Führen Sie Folgendes aus, um dies in einen Stash zu konvertieren:Wenn Sie es als Zweig haben, können Sie es auch frei manipulieren. Zum Beispiel, um es zu pflücken oder zusammenzuführen.
quelle
git stash apply commitid
danngit stash
ein neues Versteck zu bekommen.git stash pop
, wird der Stash auch nicht gelöscht, sodass dies normalerweise kein Problem darstellt.git stash pop
. Wenn Sie den Stash anwenden möchten, ohne ihn fallen zu lassen, verwenden Siegit stash apply
stattdessen. Wenn Sie eine Änderung auf mehrere Zweige anwenden möchten, können Sie stattdessen auch das Commit auswählen.Ich wollte nur diesen Zusatz zur akzeptierten Lösung erwähnen. Es war mir nicht sofort klar, als ich diese Methode zum ersten Mal ausprobierte (vielleicht hätte es so sein sollen), aber um den Stash aus dem Hash-Wert anzuwenden, verwenden Sie einfach "git stash apply":
Als ich neu bei Git war, war mir das nicht klar und ich habe verschiedene Kombinationen von "Git Show", "Git Apply", "Patch" usw. ausprobiert.
quelle
So erhalten Sie eine Liste der Verstecke, die sich noch in Ihrem Repository befinden, aber nicht mehr erreichbar sind:
Wenn Sie Ihrem Vorrat einen Titel gegeben haben, ersetzen Sie "WIP"
-grep=WIP
am Ende des Befehls durch einen Teil Ihrer Nachricht, z-grep=Tesselation
.Der Befehl sucht nach "WIP", da die Standard-Commit-Nachricht für einen Stash im Formular vorliegt
WIP on mybranch: [previous-commit-hash] Message of the previous commit.
quelle
!
).Ich habe gerade einen Befehl erstellt, der mir geholfen hat, mein verlorenes Stash-Commit zu finden:
Dadurch werden alle Objekte im Baum .git / objects aufgelistet, diejenigen Objekte vom Typ commit gefunden und anschließend eine Zusammenfassung der einzelnen Objekte angezeigt. Von diesem Punkt an ging es nur noch darum, die Commits zu durchsuchen, um einen geeigneten "WIP on work: 6a9bb2" zu finden ("work" ist mein Zweig, 619bb2 ist ein kürzlich abgeschlossener Commit).
Ich stelle fest, dass ich dieses Problem nicht hätte, wenn ich "git stash apply" anstelle von "git stash pop" verwenden würde, und wenn ich "git stash save message " verwende, wäre das Commit möglicherweise leichter zu finden gewesen.
Update: Mit Nathans Idee wird dies kürzer:
quelle
git fsck --unreachable | grep commit
sollte sha1 anzeigen, obwohl die zurückgegebene Liste möglicherweise ziemlich groß ist.git show <sha1>
zeigt an, ob es sich um das gewünschte Commit handelt.git cherry-pick -m 1 <sha1>
führt das Commit in den aktuellen Zweig ein.quelle
Windows PowerShell-Äquivalent mit gitk:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
Es gibt wahrscheinlich einen effizienteren Weg, dies in einem Rohr zu tun, aber das macht den Job.
quelle
Wenn Sie einen verlorenen Vorrat wiederherstellen möchten, müssen Sie zuerst den Hash Ihres verlorenen Vorrats ermitteln.
Wie Aristoteles Pagaltzis vorschlug,
git fsck
sollte ein Ihnen helfen.Persönlich verwende ich meinen
log-all
Alias, der mir jedes Commit (wiederherstellbare Commits) anzeigt, um einen besseren Überblick über die Situation zu erhalten:Sie können eine noch schnellere Suche durchführen, wenn Sie nur nach "WIP on" -Nachrichten suchen.
Sobald Sie Ihren sha1 kennen, ändern Sie einfach Ihr Stash-Reflog, um das alte Stash hinzuzufügen:
Sie werden es wahrscheinlich vorziehen, eine zugehörige Nachricht zu haben, also a
-m
Und Sie möchten dies sogar als Alias verwenden:
quelle
-d\\
sollte das sein-d\
(oder noch klarer-d' '
)git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
Ich mochte Aristoteles 'Ansatz, mochte aber nicht GITK ... da ich es gewohnt bin, GIT über die Befehlszeile zu verwenden.
Stattdessen nahm ich die baumelnden Commits und gab den Code zur Überprüfung in meinem Code-Editor in eine DIFF-Datei aus.
Jetzt können Sie die resultierende diff / txt-Datei (in Ihrem Home-Ordner) in Ihren txt-Editor laden und den tatsächlichen Code und die resultierende SHA anzeigen.
Dann einfach benutzen
quelle
Sie können alle nicht erreichbaren Commits auflisten, indem Sie diesen Befehl in Terminal schreiben -
Überprüfen Sie den nicht erreichbaren Commit-Hash -
Schließlich bewerben, wenn Sie den verstauten Artikel finden -
quelle
Warum stellen die Leute diese Frage? Weil sie das Reflog noch nicht kennen oder verstehen.
Die meisten Antworten auf diese Frage enthalten lange Befehle mit Optionen, an die sich fast niemand erinnern wird. Also kommen die Leute in diese Frage und kopieren und fügen alles ein, was sie für nötig halten, und vergessen es fast unmittelbar danach.
Ich würde jedem mit dieser Frage raten, nur das Reflog (Git Reflog) zu überprüfen, nicht viel mehr. Sobald Sie diese Liste aller Commits sehen, gibt es hundert Möglichkeiten, herauszufinden, nach welchem Commit Sie suchen, und es auszuwählen oder einen Zweig daraus zu erstellen. Dabei haben Sie das Reflog und die nützlichen Optionen für verschiedene grundlegende Git-Befehle kennengelernt.
quelle
In OSX mit git v2.6.4 habe ich versehentlich git stash drop ausgeführt und es dann gefunden, indem ich die folgenden Schritte durchlaufen habe
Wenn Sie den Namen des Lagers kennen, verwenden Sie:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>
Andernfalls finden Sie die ID aus dem Ergebnis manuell mit:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show
Wenn Sie dann die Commit-ID finden, klicken Sie einfach auf den Git-Stash Apply {Commit-ID}.
Hoffe das hilft jemandem schnell
quelle
Ich möchte der akzeptierten Lösung einen weiteren guten Weg hinzufügen, um alle Änderungen durchzugehen, wenn Sie entweder kein Gitk zur Verfügung haben oder kein X für die Ausgabe.
Dann werden alle Unterschiede für diese Hashes nacheinander angezeigt. Drücken Sie 'q', um zum nächsten Diff zu gelangen.
quelle
Ich konnte keine der Antworten erhalten, um unter Windows in einem einfachen Befehlsfenster zu arbeiten (in meinem Fall Windows 7).
awk
,grep
UndSelect-string
wurden als Befehle nicht erkannt. Also habe ich einen anderen Ansatz versucht:git fsck --unreachable | findstr "commit"
start cmd /k git show
wird ungefähr so aussehen:
start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e
git stash apply (your hash)
ist vielleicht nicht die beste Lösung, hat aber für mich funktioniert
quelle
Die von Aristoteles akzeptierte Antwort zeigt alle erreichbaren Commits, einschließlich nicht versteckter Commits. So filtern Sie das Rauschen heraus:
Dies schließt nur Commits ein, die genau 3 übergeordnete Commits haben (die ein Stash haben wird) und deren Nachricht "WIP on" enthält.
Beachten Sie, dass beim Speichern Ihres Stashs mit einer Nachricht (z. B.
git stash save "My newly created stash"
) die Standardnachricht "WIP on ..." überschrieben wird.Sie können weitere Informationen zu jedem Commit anzeigen, z. B. die Commit-Nachricht anzeigen oder an folgende Adresse übergeben
git stash show
:quelle
Mein Favorit ist dieser Einzeiler:
Dies ist im Grunde die gleiche Idee wie diese Antwort, aber viel kürzer. Natürlich können Sie noch hinzufügen
--graph
, um eine baumartige Anzeige zu erhalten.Wenn Sie das Commit in der Liste gefunden haben, bewerben Sie sich mit
Für mich hat die Verwendung
--no-reflogs
den verlorenen Stash-Eintrag enthüllt, aber--unreachable
(wie in vielen anderen Antworten gefunden) nicht.Führen Sie es auf Git Bash aus, wenn Sie unter Windows sind.
Credits: Die Details der oben genannten Befehle stammen von https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf
quelle
Stellen Sie es mithilfe der folgenden Schritte wieder her:
Identifizieren Sie den gelöschten Stash-Hash-Code:
gitk --all $ (git fsck --no-reflog | awk '/ dangling commit / {print $ 3}')
Cherry Pick the Stash:
git cherry-pick -m 1 $ stash_hash_code
Lösen Sie Konflikte, falls vorhanden:
Git Mergetool
Außerdem haben Sie möglicherweise Probleme mit der Festschreibungsnachricht, wenn Sie Gerrit verwenden. Bitte bewahren Sie Ihre Änderungen auf, bevor Sie die nächsten Alternativen befolgen:
quelle
Was ich hierher gebracht habe, ist, wie ich den Vorrat tatsächlich zurückbekomme, unabhängig davon, was ich ausgecheckt habe. Insbesondere hatte ich etwas verstaut, dann eine ältere Version ausgecheckt und sie dann geöffnet, aber das Versteck war zu diesem früheren Zeitpunkt ein No-Op, sodass das Versteck verschwand; Ich konnte es nicht einfach
git stash
zurückschieben. Das hat bei mir funktioniert:Im Nachhinein hätte ich
git stash apply
nicht verwenden sollengit stash pop
. Ich machte einenbisect
und hatte einen kleinen Patch, den ich bei jedembisect
Schritt anwenden wollte . Jetzt mache ich das:quelle
stash apply
.