So stellen Sie nicht festgeschriebene Änderungen wieder her

689

Ich hatte einige nicht festgeschriebene Änderungen in meinem Entwicklungszweig und habe sie mit versteckt git stash, aber es gab einige Änderungen, die unter diesen versteckten sehr wichtig waren. Gibt es eine Möglichkeit, diese Änderungen zurückzugewinnen?

Außerdem habe ich seitdem einige Änderungen zusätzlich zu den versteckten Codedateien vorgenommen.

Gibt es eine Möglichkeit, die versteckten Änderungen in einem neuen Zweig abzurufen, wenn dies möglich ist?

Aswathy P Krishnan
quelle
7
Haben Sie versucht, "Stash Pop" zu verwenden?
Robert
Nein, eigentlich bin ich neu in Git. Da mir nicht alle Befehle bekannt sind, habe ich nichts anderes ausprobiert! Ich möchte diese Änderungen nicht verlieren.
Aswathy P Krishnan
33
Wenn Sie die versteckten Änderungen nicht verlieren möchten, verwenden Sie 'git stash apply'. Dadurch werden die versteckten Änderungen auf Ihren aktuellen Zweig angewendet, während der Stash beibehalten wird. Wenn alles in Ordnung ist, können Sie nach dem Anwenden des Stashs den Stash mit 'git stash drop'
löschen
2
@robert Vielen Dank für die einfache Antwort im Vergleich zu der schrecklich komplizierten (für einen Neuling) akzeptierten Antwort.
Saheel Godhane

Antworten:

1183

Die einfache Antwort auf die einfache Frage lautet git stash apply

Überprüfen Sie einfach den Zweig, in dem Sie Ihre Änderungen vornehmen möchten, und dann git stash apply. Verwenden Sie dann git diff, um das Ergebnis zu sehen.

Nachdem Sie alle mit Ihren Änderungen am bist applysieht gut aus und Sie sind sicher , brauchen Sie nicht das Versteck jeder mehr- dann verwendet git stash dropes loszuwerden.

Ich schlage immer vor, git stash applyanstatt zu verwenden git stash pop. Der Unterschied besteht darin, dass applyder Vorrat zum einfachen erneuten Ausprobieren applyoder zum Betrachten usw. popverbleibt . Wenn der Vorrat extrahiert werden kann, wird er sofort auch dropangezeigt, und wenn Sie plötzlich feststellen, dass Sie ihn irgendwo extrahieren möchten sonst (in einem anderen Zweig) oder mit --indexoder einem solchen ist das nicht so einfach. Wenn Sie apply, können Sie wählen, wann drop.

Es ist alles auf die eine oder andere Weise ziemlich klein, und für einen Neuling sollte es ungefähr gleich sein. (Und den Rest kannst du überspringen!)


Was ist, wenn Sie fortgeschrittenere oder kompliziertere Dinge tun?

Es gibt mindestens drei oder vier verschiedene "Möglichkeiten, Git Stash zu verwenden". Das Obige ist für "Weg 1", den "einfachen Weg":

  1. Sie haben mit einem sauberen Zweig begonnen, an einigen Änderungen gearbeitet und dann festgestellt, dass Sie sie im falschen Zweig durchgeführt haben. Sie möchten nur die Änderungen, die Sie jetzt haben, in einen anderen Zweig "verschieben".

    Dies ist der oben beschriebene einfache Fall. Laufen Sie git stash save(oder einfach git stash, dasselbe). Schauen Sie sich den anderen Zweig an und verwenden Sie git stash apply. Dadurch wird git in Ihren früheren Änderungen zusammengeführt, wobei der ziemlich leistungsstarke Zusammenführungsmechanismus von git verwendet wird. Überprüfen Sie die Ergebnisse sorgfältig (mit git diff), um festzustellen , ob sie Ihnen gefallen, und verwenden Sie sie gegebenenfalls, git stash dropum den Vorrat fallen zu lassen. Du bist fertig!

  2. Sie haben einige Änderungen vorgenommen und sie gespeichert. Dann haben Sie zu einem anderen Zweig gewechselt und weitere Änderungen vorgenommen, wobei Sie vergessen haben, dass Sie die versteckten hatten.

    Jetzt möchten Sie diese Änderungen beibehalten oder sogar verschieben und auch Ihren Vorrat anwenden.

    Sie können in der Tat git stash savewieder, wie git stashein "Stapel" von Änderungen vornimmt. Wenn Sie das tun, haben Sie zwei Verstecke, einen, der gerade aufgerufen wurde stash- aber Sie können auch schreiben stash@{0}- und einen, der geschrieben ist stash@{1}. Verwenden Sie git stash list(jederzeit), um sie alle zu sehen. Das neueste ist immer das niedrigste. Wenn Sie git stash drop, lässt es das neueste und dasjenige fallen, stash@{1}das an die Spitze des Stapels verschoben wurde. Wenn Sie noch mehr hatten, dass derjenige war stash@{2}wird stash@{1}, und so weiter.

    Sie können applyund dann auch dropeinen bestimmten Vorrat: git stash apply stash@{2}und so weiter. Wenn Sie einen bestimmten Vorrat löschen, werden nur die höher nummerierten neu nummeriert. Auch hier ist der ohne Nummer stash@{0}.

    Wenn Sie viele Verstecke aufstapeln, kann es ziemlich chaotisch werden (war das Versteck, das ich wollte stash@{7}oder war es stash@{4}? Warten Sie, ich habe gerade ein anderes geschoben, jetzt sind es 8 und 5?). Ich persönlich ziehe es vor, diese Änderungen in eine neue Niederlassung zu übertragen, da Niederlassungen Namen haben und cleanup-attempt-in-Decembermir viel mehr bedeuten als stash@{12}. (Der git stashBefehl nimmt eine optionale Speichernachricht entgegen, und diese können helfen, aber irgendwie werden alle meine Verstecke nur mit Namen benannt WIP on branch.)

  3. (Extra-Advanced) Sie haben vor der Ausführung bestimmte Teile Ihres Codes verwendet git stash save -poder sorgfältig git addbearbeitet und / oder git rmbearbeitet git stash save. Sie hatten eine Version im versteckten Index- / Staging-Bereich und eine andere (andere) Version im Arbeitsbaum. Sie wollen das alles bewahren. Jetzt verwenden Sie also git stash apply --index, und das schlägt manchmal fehl mit:

    Conflicts in index.  Try without --index.
    
  4. Sie verwenden, git stash save --keep-indexum zu testen, "was festgeschrieben wird". Dieser geht über den Rahmen dieser Antwort hinaus; Siehe stattdessen diese andere StackOverflow-Antwort .

In komplizierten Fällen empfehle ich, zuerst in einem "sauberen" Arbeitsverzeichnis zu beginnen, indem Sie alle Änderungen übernehmen, die Sie jetzt haben (in einem neuen Zweig, wenn Sie möchten). Auf diese Weise enthält das "irgendwo", auf das Sie sie anwenden, nichts anderes, und Sie werden nur die versteckten Änderungen ausprobieren:

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Jetzt sind Sie an einem "sauberen" Ausgangspunkt. Oder vielleicht geht es eher so:

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

Die wichtigste Sache zu erinnern ist , dass die „Stash“ ist ein begehen, es ist nur ein wenig „komisch / seltsam“ begeht das ist nicht „auf einem Zweig“. Die applyOperation überprüft, was das Commit geändert hat, und versucht, es zu wiederholen, wo immer Sie sich gerade befinden. Das Versteck ist immer noch da ( applybehält es bei sich), sodass Sie es sich genauer ansehen oder entscheiden können, dass dies der falsche Ort war, applyund es erneut versuchen können, oder was auch immer.


Jedes Mal, wenn Sie einen Vorrat haben, können Sie git stash show -peine vereinfachte Version des Vorrats sehen. (Diese vereinfachte Version betrachtet nur die Änderungen des "endgültigen Arbeitsbaums", nicht die gespeicherten Indexänderungen, --indexdie separat wiederhergestellt werden.) Der Befehl git stash applyohne --indexversucht nur, dieselben Änderungen jetzt in Ihrem Arbeitsverzeichnis vorzunehmen.

Dies gilt auch dann, wenn Sie bereits einige Änderungen vorgenommen haben. Der applyBefehl wendet gerne einen Stash auf ein geändertes Arbeitsverzeichnis an (oder versucht zumindest, ihn anzuwenden). Sie können zum Beispiel Folgendes tun:

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

Sie können hier die Reihenfolge "Anwenden" auswählen und bestimmte Verstecke auswählen, die in einer bestimmten Reihenfolge angewendet werden sollen. Beachten Sie jedoch, dass jedes Mal, wenn Sie im Grunde genommen eine "Git-Zusammenführung" durchführen, und wie in der Zusammenführungsdokumentation gewarnt wird:

Es wird davon abgeraten, git merge mit nicht trivialen, nicht festgeschriebenen Änderungen auszuführen: Obwohl dies möglich ist, befinden Sie sich möglicherweise in einem Zustand, aus dem Sie im Falle eines Konflikts nur schwer herauskommen können.

Wenn Sie mit einem sauberen Verzeichnis beginnen und nur mehrere git applyVorgänge ausführen, ist das Zurücksetzen einfach: Verwenden Sie git reset --harddiese Option, um zum sauberen Status zurückzukehren und Ihre applyVorgänge zu ändern . (Deshalb empfehle ich für diese komplizierten Fälle, zuerst in einem sauberen Arbeitsverzeichnis zu beginnen.)


Was ist mit dem schlimmsten Fall?

Nehmen wir an, Sie machen viel fortgeschrittenes Git-Zeug und haben einen Stash erstellt und möchten dies git stash apply --index, aber es ist nicht mehr möglich, den gespeicherten Stash mit anzuwenden --index, da der Zweig seit dem Speichern zu stark auseinander gegangen ist.

Dafür ist da git stash branch.

Wenn du:

  1. Überprüfen Sie dann das genaue Commit , bei dem Sie das Original erstellt stashhaben
  2. Erstellen Sie einen neuen Zweig und schließlich
  3. git stash apply --index

der Versuch , neu erstellen , um die Änderungen auf jeden Fall wird funktionieren. Das macht es. (Und dann wird der Vorrat gelöscht, da er erfolgreich angewendet wurde.)git stash branch newbranch


Ein --indexpaar abschließende Worte über (was zum Teufel ist das?)

Was das --indexmacht, ist einfach zu erklären, aber intern etwas kompliziert:

  • Wenn Sie Änderungen haben, müssen Sie git adddiese vor dem commitEinfügen (oder "inszenieren") .
  • Wenn Sie ausgeführt haben git stash, haben Sie möglicherweise beide Dateien bearbeitet foound zorgnur eine davon bereitgestellt.
  • Wenn Sie also darum bitten, das Versteck zurückzubekommen, ist es möglicherweise hilfreich, wenn es sich um git adddie added-Dinge handelt und nicht um git add die nicht hinzugefügten Dinge. Das heißt, wenn Sie added, fooaber nicht zorgzurück, bevor Sie das getan haben stash, könnte es schön sein, genau das gleiche Setup zu haben. Was inszeniert wurde, sollte wieder inszeniert werden; Was geändert, aber nicht inszeniert wurde, sollte erneut geändert, aber nicht inszeniert werden.

Die --indexFlagge, die applyversucht, die Dinge auf diese Weise einzurichten. Wenn Ihr Arbeitsbaum sauber ist, funktioniert dies normalerweise nur. Wenn Ihr Arbeitsbaum jedoch bereits Daten enthält add, können Sie hier sehen, wie Probleme auftreten können. Wenn Sie auslassen , --indexversucht der applyVorgang nicht, das gesamte bereitgestellte / nicht bereitgestellte Setup beizubehalten. Stattdessen wird nur die Merge-Maschinerie von git aufgerufen, wobei das Work-Tree-Commit im "Stash Bag" verwendet wird . Wenn es Ihnen nicht wichtig ist, inszeniert / nicht inszeniert zu bleiben, --indexmacht es das Weglassen viel einfacher git stash apply, seine Sache zu erledigen.

torek
quelle
2
Ich verstehe deinen Kommentar nicht. Meinst du: du bist gerannt git stash pop? Oder meinst du: du hast einige Dateien bearbeitet, bist aber noch nicht git stashwieder gelaufen ? Oder meinst du etwas ganz anderes?
Torek
1
Ja. Beachten Sie, dass ich in meiner (langen) Bearbeitung empfehle, das, was Sie jetzt haben, applyfestzuschreiben, bevor Sie einen Stash erstellen. Sie müssen nicht haben , um dies zu tun, aber es macht die Dinge viel einfacher für Sie, zu betrachten. Sie können verwenden, rebase -ium mehrere Commits zusammenzudrücken oder bestimmte Änderungen oder was auch immer später auszuwählen.
Torek
1
Ja: git stash apply --index(erinnere dich an die beiden Striche). Wenn Sie weglassen --index, keine große Sache; Der einzige Punkt --indexist, das inszenierte / nicht inszenierte Setup beizubehalten. (Sie hatten wahrscheinlich überhaupt kein spezielles Setup.) Dann git statususw. und wie gewünscht hinzufügen / festschreiben usw. Wenn (und nur wenn) Sie mit dem Stash fertig sind, verwenden Sie es git stash drop, um es zu verwerfen.
Torek
1
Solange Sie (nicht halten dropoder pop) , um das Versteck, haben Sie immer das Original sicher verstaute Code auf einem Commit, weil ein Versteck ist ein fest! Wenn Sie es genau zurückbekommen möchten, aber in einem Zweig, verwenden Sie git stash branch(siehe diesen Abschnitt oben oder das Pro Git-Buch in Shunyas Antwort ). Sie können dann git checkoutdiesen Zweig oder git cherry-pickdas
Festschreiben
2
@ChuckWolber: Die Namenskonventionen von Git lassen zu wünschen übrig (wie viele verschiedene Bedeutungen können wir den Wörtern "remote", "Tracking" und "branch" zuweisen?!). Es ist jedoch erwähnenswert, dass Sie einen Stash auf etwas anwenden können, das nicht mit dem ursprünglichen Stash zusammenhängt.
Torek
57
git stash pop

wird alles wieder in Position bringen

Wie in den Kommentaren vorgeschlagen, können Sie git stash branch newbranchden Stash auf einen neuen Zweig anwenden. Dies entspricht dem Ausführen von:

git checkout -b newbranch
git stash pop
Stefano Falasca
quelle
Danke für die Hilfe. Kann ich diese Änderungen in einen neuen Zweig übernehmen? Im Moment bin ich auf Entwicklungszweig
Aswathy P Krishnan
3
git stash branch newbranch erstellt einen neuen Zweig mit den versteckten Änderungen.
Robert
3
@ Robert: git stash branch newbranchwerde das in der Tat tun; Beachten Sie jedoch, dass der neue Zweig mit dem übergeordneten Zweig erstellt wird, der auf das Commit festgelegt ist, das HEADzum Zeitpunkt der stashAusführung festgelegt wurde. Mit anderen Worten, es ist für den Fall, dass Sie nach einer langen Hack-Sitzung oder was auch immer zurückkommen, auf das Chaos starren und entscheiden, "Ich hätte das auf einen Ast legen sollen, anstatt es zu verstecken" :-)
torek
Ich habe meine Frage bearbeitet. Ich möchte diese Änderungen nach Möglichkeit in einen neuen Zweig übernehmen.
Aswathy P Krishnan
1
Manchmal möchten Sie nur die TLDR-Antwort :)
Sachinruk
24

Um dies zu vereinfachen, haben Sie zwei Möglichkeiten, Ihren Vorrat erneut anzuwenden:

  1. git stash pop - Stellen Sie den gespeicherten Zustand wieder her, aber der Stash wird aus dem temporären Speicher gelöscht.
  2. git stash apply - Stellen Sie den gespeicherten Zustand wieder her und verlassen Sie die Stash-Liste für eine mögliche spätere Wiederverwendung.

In diesem Artikel erfahren Sie mehr über Git-Stashes .

Nesha Zoric
quelle
19

So überprüfen Sie Ihren Stash-Inhalt: -

Git Stash Liste

Wenden Sie eine bestimmte Stash-Nr. aus der Stash-Liste an: -

Git Stash Apply Stash @ {2}

oder um nur den ersten Vorrat anzuwenden: -

Git Stash Pop

Hinweis: Git Stash Pop entfernt den Stash aus Ihrer Stash-Liste, während Git Stash nicht angewendet wird. Verwenden Sie sie also entsprechend.

Shivansh Rajolia - HeLleR
quelle
2

Auf dem Mac hat das bei mir funktioniert:

git stash list (siehe alle deine stashs)

git stash list

git stash bewerben (nur die Nummer, die Sie von Ihrer Stash-Liste wollen)

so was:

git stash apply 1
Zack
quelle
0

Sie können die nicht festgeschriebenen Änderungen mit "git stash" speichern und dann mit "git checkout -b" in einen neuen Zweig auschecken und dann die versteckten Commits "git stash apply" anwenden.

S. Sandeptha
quelle