Ist es möglich, eine einzelne Datei oder ein Diff einer Datei aus einem Git-Stash zu extrahieren, ohne den Stash-Änderungssatz zu entfernen?
Wie würde ich eine einzelne Datei (oder Änderungen an einer Datei) aus einem Git-Stash extrahieren?
Danni
Jakub Narębski
Auf der git stash Manpage können Sie lesen (im Abschnitt „Diskussion“, gleich nach der Beschreibung „Optionen“), dass:
Ein Stash wird als Commit dargestellt, dessen Baum den Status des Arbeitsverzeichnisses aufzeichnet, und sein erster Elternteil ist der Commit bei HEAD, als der Stash erstellt wurde.
So können Sie Stash behandeln (zB stash@{0}
ist erster / oberster Stash) als Merge-Commit und verwende:
$ git diff stash@{0}^1 stash@{0} -- <filename>
Erläuterung: stash@{0}^1
bedeutet den ersten Elternteil des angegebenen Stashs, der, wie in der obigen Erklärung angegeben, der Commit ist, bei dem Änderungen gespeichert wurden. Wir verwenden diese Form von “git diff” (mit zwei Commits), weil stash@{0}
/ refs/stash
ist ein Merge-Commit, und wir müssen git mitteilen, gegen welchen Elternteil wir uns differenzieren wollen. Kryptischer:
$ git diff stash@{0}^! -- <filename>
sollte auch funktionieren (vgl git rev-parse Manpage zur Erklärung von rev^!
Syntax, im Abschnitt “Bereiche angeben”).
Ebenso können Sie verwenden git-Kasse So checken Sie eine einzelne Datei aus dem Stash aus:
$ git checkout stash@{0} -- <filename>
oder um es unter einem anderen Dateinamen zu speichern:
$ git show stash@{0}:<full filename> > <newfile>
oder
$ git show stash@{0}:./<relative filename> > <newfile>
(Hinweis dass hier stash@{0}
)).
Möglicherweise müssen Sie sich schützen stash@{0}
von Shell-Erweiterung, dh verwenden "stash@{0}"
oder 'stash@{0}'
.
-
Das ist ziemlich cool … ich nicht Ja wirklich verstehe, wie stash funktioniert, bis ich deine Antwort gelesen habe (was mich zur git-checkout-Ergänzung geführt hat). Ich habe das wirklich nicht verstanden, wenn Sie einen Stash erstellen, speichert Git ZWEI Commits – einen für den Status des Index und einen für den Status der Arbeitskopie, die eine Zusammenführung zwischen dem Index und dem ursprünglichen HEAD ist. Dies erklärt die seltsamen Bäume, die ich gesehen habe, wenn ich das Repository mit “gitk –all” visualisiere, wenn Stashes vorhanden sind.
– Pat Notz
9. Juli 2009 um 20:56 Uhr
-
Meistens finde ich die Git-Checkout-Anwendung der beste Weg, um das zu erreichen, was ich tun wollte. Ich war jedoch neugierig und habe es doppelt überprüft
git checkout
Manpage von . Die Datei kann nicht an einem anderen Ort abgelegt werden. Es gibt einen Hinweis darauf in: stackoverflow.com/questions/888414/…– Danni
9. Juli 2009 um 22:15 Uhr
-
$ git checkout stash@{0} —
ist sehr nützlich, danke – Gravitation
9. September 2009 um 5:18 Uhr
-
Notiere dass der
git checkout
Ansatz kopiert die genau Datei aus dem Stash – sie wird nicht mit dem zusammengeführt, was sich in Ihrem Arbeitsverzeichnis befindetgit stash apply
möchten. (Wenn Sie also Änderungen an der Basis vorgenommen haben, auf der das Stash erstellt wurde, gehen sie verloren).– Peterflynn
5. April 2013 um 22:04 Uhr
-
Beachten Sie, dass in Ordnung für
git stash apply
Um die Änderungen in einer Datei zusammenzuführen, die seit dem Zwischenspeichern der Datei in der Arbeitsstruktur geändert wurde, muss diese Datei in der Arbeitsstruktur bereitgestellt werden. Damit die automatische Zusammenführung funktioniert, dürfen dieselben Dateien nicht sowohl in der Arbeitskopie als auch in der zusammenzuführenden Zwischenkopie geändert werden. Schließlich entfernt stash apply den Gegenstand nicht wie aus dem Stashgit stash pop
möchten.– Ville
4. November 2013 um 16:15 Uhr
Wenn du benutzt git stash apply
eher, als git stash pop
wird es den Stash auf Ihren Arbeitsbaum anwenden, aber den Stash behalten.
Wenn dies erledigt ist, können Sie add
/commit
die gewünschte Datei und setzen Sie dann die verbleibenden Änderungen zurück.
-
Um ein bestimmtes Versteck zu öffnen:
git stash pop stash@{0}
(listen Sie die gespeicherten Änderungen auf:git stash list
)– HerrYoshiji
15. Januar 2015 um 16:53 Uhr
-
Wenn andere Dateien im Stash einen Merge-Konflikt verursachen, lässt mich Git die gewünschte Datei nicht festschreiben 🙁
– kambunt
7. Dezember 2019 um 23:45 Uhr
Walf
Bearbeiten: Siehe die Antwort von cambunctious, die ich jetzt im Grunde bevorzuge, weil sie nur die Änderungen im Stash verwendet, anstatt sie mit Ihrem aktuellen Zustand zu vergleichen. Dies macht die Operation additiv, mit viel geringerer Wahrscheinlichkeit, dass die seit der Erstellung des Stashs geleistete Arbeit rückgängig gemacht wird.
Um es interaktiv zu tun, würden Sie zuerst tun
git diff stash^! -- path/to/relevant/file/in/stash.ext perhaps/another/file.ext > my.patch
… dann die Patch-Datei in einem Texteditor öffnen, nach Bedarf ändern und dann ausführen
git apply < my.patch
Die Antwort von cambunctious umgeht die Interaktivität, indem sie einen Befehl direkt an den anderen weiterleitet, was in Ordnung ist, wenn Sie wissen, dass Sie alle Änderungen aus dem Stash haben möchten. Sie können die bearbeiten stash^!
ein beliebiger Commit-Bereich sein, der die gewünschten kumulativen Änderungen enthält (aber überprüfen Sie zuerst die Ausgabe des Vergleichs).
Wenn das Anwenden von Patch/Diff fehlschlägt, können Sie den letzten Befehl in ändern git apply --reject
der alle Änderungen vornimmt, die er kann, und geht .rej
Dateien, in denen es Konflikte gibt, die es nicht lösen kann. Die .rej
Dateien können dann mit angewendet werden wiggle
so:
wiggle --replace path/to/relevant/file/in/stash.ext{,.rej}
Dadurch wird entweder der Konflikt gelöst oder Sie erhalten Konfliktmarkierungen, die Sie bei einer Zusammenführung erhalten würden.
Wenn Ihre Distribution das nicht hat wiggle
Sie können es einfach bauen:
cd /usr/local/src/
git clone git://git.neil.brown.name/wiggle
cd wiggle/
git checkout v1.3
make install
Bisherige Lösung: Es gibt eine einfache Möglichkeit, Änderungen von jedem Branch, einschließlich Stashes, zu erhalten:
$ git checkout --patch stash@{0} path/to/file
Sie können die Dateispezifikation weglassen, wenn Sie viele Teile patchen möchten. Oder lassen Sie patch (aber nicht den Pfad) weg, um alle Änderungen in einer einzigen Datei zu erhalten. Ersetzen 0
mit der Lagernummer von git stash list
, wenn Sie mehr als einen haben. Beachten Sie, dass dies wie ist diff
und Bewerbungsangebote alle Unterschiede zwischen den Filialen. Um Änderungen von nur einem einzigen Commit/Stash zu erhalten, werfen Sie einen Blick auf git cherry-pick --no-commit
.
-
Kopiert dies die genaue Datei aus dem Stash oder wird sie zusammengeführt? Wenn Sie seit der Erstellung des Stashs Änderungen vorgenommen haben, gehen diese beim Kopieren verloren.
– Daniel
30. Oktober 2018 um 11:39 Uhr
-
@ Daniel Read
git help checkout
.--patch
Führt interaktives Zusammenführen durch. Es wendet alle Hunks an, die Sie in der Shell genehmigen (oder was auch immer Sie speichern, wenn Sie dies wünschene
dit den Patch). Der Pfad allein überschreibt die Datei, wie ich geschrieben habe, “alle Änderungen”.– Wal
31. Oktober 2018 um 6:45 Uhr
-
leichte Verbesserung:
git config --global alias.applydiffat '!git checkout --patch "$1" -- $(git diff --name-only "$1"^ "$1")'
— dann tungit applydiffat stash@{4}
verwendet nur Dateien, die sich zwischen dem Stash und seinem übergeordneten Element geändert haben.– Kennzeichen
8. Mai 2020 um 18:38 Uhr
RAM
$ git checkout stash@{0} -- <filename>
Anmerkungen:
-
Stell sicher, dass du Leerzeichen nach dem “–“ und den Dateinamenparameter
-
Ersetzen Sie null (0) durch Ihre spezifische Stash-Nummer. Verwenden Sie zum Abrufen der Stash-Liste:
git stash list
Basierend auf der Antwort von Jakub Narębski – Kürzere Version
Kurze Antwort
Um die ganze Datei zu sehen: git show stash@{0}:<filename>
Um den Unterschied zu sehen: git diff stash@{0}^1 stash@{0} -- <filename>
-
Ich glaube nicht, dass es ihm/ihr darum ging, den Stash für eine bestimmte Datei anzuzeigen, sondern nur diese Datei zu öffnen.
– Amalgowinus
1. April 2016 um 18:29 Uhr
-
Das habe ich gesucht. Dann kannst du ersetzen
diff
mitdifftool
um Ihr bevorzugtes externes Diff zu verwenden.– Peet Brits
17. Januar 2017 um 10:36 Uhr
-
Mein Git-Repo war beschädigt, aber ich hatte die Dateien abgelegt, konnte mich aber wegen der Beschädigung nicht bewerben. Ich konnte dies verwenden und zu einer neuen Datei leiten, sie unterscheiden, und ich konnte loslegen. Danke!
– Adam Tulper
24. November 2020 um 21:16 Uhr
kambunt
Verwenden Sie Folgendes, um die Änderungen an einer Datei in einem Stash auf Ihren Arbeitsbaum anzuwenden.
git diff stash^! -- <filename> | git apply
Dies ist im Allgemeinen besser als die Verwendung git checkout
weil Sie keine Änderungen verlieren, die Sie an der Datei vorgenommen haben, seit Sie den Stash erstellt haben.
-
Ich glaube nicht, dass es ihm/ihr darum ging, den Stash für eine bestimmte Datei anzuzeigen, sondern nur diese Datei zu öffnen.
– Amalgowinus
1. April 2016 um 18:29 Uhr
-
Das habe ich gesucht. Dann kannst du ersetzen
diff
mitdifftool
um Ihr bevorzugtes externes Diff zu verwenden.– Peet Brits
17. Januar 2017 um 10:36 Uhr
-
Mein Git-Repo war beschädigt, aber ich hatte die Dateien abgelegt, konnte mich aber wegen der Beschädigung nicht bewerben. Ich konnte dies verwenden und zu einer neuen Datei leiten, sie unterscheiden, und ich konnte loslegen. Danke!
– Adam Tulper
24. November 2020 um 21:16 Uhr
Nathan Küche
Sie können das Diff für ein Stash mit “git show stash@{0}
” (oder was auch immer die Nummer des Stashs ist; siehe “git stash list”). Es ist einfach, den Abschnitt des Diffs für eine einzelne Datei zu extrahieren.
-
Noch einfacher für Köpfe wie mich: verwenden
git show stash
um den obersten Vorrat anzuzeigen (normalerweise den einzigen, den Sie haben). Ebenso können Sie den Unterschied zwischen Ihrem aktuellen Zweig und dem Stash mit anzeigengit diff head stash
.– Dizzley
2. November 2013 um 10:00 Uhr