Pop es und speichern Sie es erneut unter einem anderen Namen?
Bartlomiej Lewandowski
5
Das erneute Poppen und Verstauen ist nicht immer eine Option, da das Verstauen möglicherweise auf einem veralteten Status basiert und zu Konflikten beim Poppen führt. (Der veraltete Zustand muss nicht einmal mehr irgendwo in der Geschichte existieren.)
Tom
Antworten:
258
Nehmen wir an, Ihre Stash-Liste sieht folgendermaßen aus:
$ git stash list
stash@{0}: WIP on master: Add some very important feature
stash@{1}: WIP on master: Fix some silly bug
Zuerst müssen Sie den Stash-Eintrag entfernen, den Sie umbenennen möchten:
$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)
Fügen Sie es jetzt einfach erneut mit einer neuen Nachricht hinzu, indem Sie sha of commit verwenden, die nach dem Löschen zurückgegeben wurde:
$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db
Und das ist es:
$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature
Diese Lösung erfordert Git 1.8.4 oder höher und funktioniert auch mit Dirty Working Directory.
git show stash@{0}zeigt danach immer noch die alten Informationen. Wie kann man das beheben? (Bitte beachten Sie, dass der Vorrat dann eine andere SHA bekommt.)
Tino
4
Es fühlt sich besser an, den Hash zu bekommen git showund damit zu beginnen git stash store. Dann sehen git stash listSie mit Ihnen das alte und das neue Versteck. Endlich können Sie den alten Vorrat mit aufräumen git stash drop.
Hogi
6
Wird Git Stash Drop die Änderungen nicht verlieren?
Shravya Boggarapu
4
@ShravyaBoggarapu, nein, git entfernt Commit erst, wenn git gces ausgeführt wird. Nachdem stash dropSie dieses normalerweise unzugängliche Commit mit dem git fsck | grep commitBefehl leicht finden können .
QZB
2
@ ÐerÆndi Das einfache Anwenden und Speichern ist eine einfache Option, funktioniert jedoch nicht, wenn Änderungen aufgrund von Konflikten nicht erneut angewendet werden können. In der Zwischenzeit kann das Ablegen und Lagern unter keinen Umständen funktionieren. Ich habe meine Lösung noch einmal getestet - sie funktioniert einwandfrei mit der neuesten Git-Version (2.17.0).
QZB
62
Sofern Sie dies nicht manuell tun oder zu einer Verbesserung von Git beitragen, können Sie einen Alias verwenden:
Mit [save options]jeder Option von git stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Beispiel:
$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd
# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd
$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes
Das funktioniert auch, wenn Sie lokale, nicht bereitgestellte Änderungen haben :)
Genial! Noch cooler, wenn Sie könntengit stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
Mikemaccana
3
Die Antwort lautet also 1) saubere Arbeitskopie, 2) Stash anwenden, den Sie umbenennen möchten, 3) aus der Stash-Liste löschen, 4) einen neuen Stash mit der richtigen Nachricht erstellen.
GCB
2
Zur Verdeutlichung benennen Sie das letzte Versteck um, und nach einer solchen Aktion wird es zum obersten Versteck?
Onebree
2
Ich lösche den zu umbenennenden Stash, speichere aktuelle Änderungen, falls vorhanden, erstelle den gelöschten Stash mit dem gewünschten Namen neu und wende aktuelle Änderungen erneut an, falls vorhanden.
Julien Carsique
3
Diese Version überprüft, ob beide Argumente vorhanden sind, damit Ihr letzter Vorrat nicht versehentlich gelöscht wird. Es wird auch nur die Stash-Nummer benötigt, nicht die gesamte stash@{0}Referenz. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe
6
Es ist sehr einfach. Machen Sie zuerst den letzten Vorrat rückgängig mit:
git stash pop
Danach können Sie den Vorrat auf folgende Weise unter einem benutzerdefinierten Namen speichern:
Implementieren Sie einen neuen git reflog updateBefehl, der die einem bestimmten Reflog-Eintrag zugeordnete Nachricht aktualisiert. Zu diesem Zweck würde eine neue update_reflog_ent()Funktion (in reflog.c ) die Nachricht ändern, die dem jeweiligen zu aktualisierenden Reflog-Eintrag zugeordnet ist. Eine update_reflog()Funktion würde for_each_reflog_ent()mit verwenden update_reflog_ent, um die Änderung tatsächlich durchzuführen.
Ein git stash renameBefehl müsste dann nur git
reflog updatemit dem entsprechenden Verweis und der neuen Nachricht aufrufen .
Oder Sie könnten natürlich das Versteck aufschlagen und eine git stash save [message]
Wenn Sie nicht nur die Stash-Nachricht korrigieren möchten, sondern auch die Commit-Nachricht des Stash korrigieren möchten, so dass
git stash list
und
git log --oneline -1 stash
beide stimmen dem zu, was gezeigt wird, du brauchst ein bisschen mehr. Es gibt vielleicht einen besseren Weg, aber dieses Rezept hier ist leicht zu verstehen, hoffe ich.
Um dies tun zu können, müssen git commit --amendSie sich auf dem Tipp einer Niederlassung befinden. Daher lautet die Lösung:
git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash store -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch
Erklärt:
Erstellen Sie einen neuen (noch nicht vorhandenen) "Scratch" -Zweig aus dem "fraglichen Stash" und wechseln Sie zu diesem
Entfernen Sie den alten Vorrat. Dies ist sicher, da wir dies immer noch in der Filiale haben.
Verwenden Sie git commit --amenddiese Option , um die Festschreibungsnachricht zu ersetzen. Dadurch wird die SHA des "fraglichen Stashs" geändert.
Schalten Sie zurück (was davon ausgeht, dass Sie vom "Master" stammen) und bereinigen Sie
Nachteile:
Dadurch werden die Zweige vorübergehend gewechselt. Dieses Rezept kann also nur angewendet werden, wenn git status --porcelaines sauber ist (lesen Sie: gibt nichts aus)
Die Vorräte werden neu nummeriert, sodass der geänderte Vorrat wird stash@{0}
Sie müssen die Eingabe $MESSAGEzweimal oder verwenden Sie eine Umgebungsvariable (im Beispiel: MESSAGE)
Sie müssen einen nicht verwendeten Filialnamen finden
Es gibt Möglichkeiten, dies zu tun, ohne die Zweige zu wechseln, aber dies würde den Rahmen dieser Antwort sprengen.
Beispiel
git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list
Ausgabe
*-. e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D
Jetzt ohne Änderung des Commits (Hinweis: Der SHA im Folgenden wird an Ihrer Seite anders sein):
git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list
Ausgabe
*-. 2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Wie Sie sehen können, wird stash@{0}immer noch wie 2fbf900 (refs/stash) WIP on master: 8bdcc32 Din angezeigt git log. Wenn Sie genau hinschauen, werden Sie feststellen, dass mehrere Commits SHA geändert haben. Dies liegt daran, wie mit Stashes umgegangen wird (Eltern sind in der SHA enthalten, und Stashes haben ihre Stashes als Eltern).
Repariere das:
git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list
Ausgabe
*-. 4d55186 (refs/stash) ...changed...
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Wie Sie auch sehen können, refs/stashhat sich auch die SHA geändert.
Erwähnenswert: Dadurch wird der Index zerstört, der mit dem ursprünglichen Stash gespeichert wurde, und durch einen neuen Index ersetzt, der dem übergeordneten Commit des ursprünglichen Stash entspricht. Wenn man nicht vorhatte, den ursprünglich gespeicherten Index zu verwenden (oder er bereits mit dem übergeordneten Index des ursprünglichen Stashs übereinstimmte), ist dies kein Problem.
Torek
1
Hier ist eine modifizierte Version von Juliens Alias , mit der Sie das On <branch>Präfix, das normalerweise vor dem Speichern von Namen steht, richtig behandeln können :
repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed
Der größte Teil des Befehls dient zum Parsen der Argumente und zum Herausfinden, was mit dem Zweignamen geschehen soll. Die verwendeten gitWerkzeuge sind wie folgt:
git rev-parse <stash> um die SHA des Versteckes zu finden.
git stash list --format=%gs -1 <stash>um das Reflog-Thema des Stashs zu finden . Beachten Sie, dass sich dies von der Festschreibungsnachricht des Stash unterscheidet, die durch diesen Befehl nicht geändert wird. Das Reflog-Betreff wird angezeigt git stash list, und Sie können das Reflog-Betreff ändern, ohne die Hashes der mit den Stashes verknüpften Commits zu ändern. Sie können jedoch immer die ursprüngliche Festschreibungsnachricht finden. git stash-renameEntfernen Sie daher keine vertraulichen Informationen!
git stash drop <stash>den alten Verweis auf das Versteck fallen zu lassen (aber wir haben immer noch die SHA, damit sie nicht verloren geht).
git stash store -m <new-message> <sha>Speichern eines neuen Verweises auf den Stash mit denselben Festschreibungsinformationen, jedoch einem anderen Reflog-Betreff .
git stash listum die Verstecke nach Abschluss des Vorgangs aufzulisten. Beachten Sie, dass neue Verstecke immer an den Anfang der Liste verschoben werden. Es wäre notwendig, alle Verstecke vor dem Versteck von Interesse erneut zu verschieben, um seine ursprüngliche Position wiederherzustellen.
Antworten:
Nehmen wir an, Ihre Stash-Liste sieht folgendermaßen aus:
Zuerst müssen Sie den Stash-Eintrag entfernen, den Sie umbenennen möchten:
Fügen Sie es jetzt einfach erneut mit einer neuen Nachricht hinzu, indem Sie sha of commit verwenden, die nach dem Löschen zurückgegeben wurde:
Und das ist es:
Diese Lösung erfordert Git 1.8.4 oder höher und funktioniert auch mit Dirty Working Directory.
quelle
git show stash@{0}
zeigt danach immer noch die alten Informationen. Wie kann man das beheben? (Bitte beachten Sie, dass der Vorrat dann eine andere SHA bekommt.)git show
und damit zu beginnengit stash store
. Dann sehengit stash list
Sie mit Ihnen das alte und das neue Versteck. Endlich können Sie den alten Vorrat mit aufräumengit stash drop
.git gc
es ausgeführt wird. Nachdemstash drop
Sie dieses normalerweise unzugängliche Commit mit demgit fsck | grep commit
Befehl leicht finden können .Sofern Sie dies nicht manuell tun oder zu einer Verbesserung von Git beitragen, können Sie einen Alias verwenden:
Verwendung: "
git stash-rename <stash> [save options] [<message>]
"Mit
[save options]
jeder Option vongit stash save
:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Beispiel:
Das funktioniert auch, wenn Sie lokale, nicht bereitgestellte Änderungen haben :)
EDIT 2016/02/22
Vereinfachtes Skript, Credits für qzb , https://stackoverflow.com/a/35549615/515973
Verwendung: "
git stash-rename <stash> [<message>]
"quelle
git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
stash@{0}
Referenz. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
Es ist sehr einfach. Machen Sie zuerst den letzten Vorrat rückgängig mit:
Danach können Sie den Vorrat auf folgende Weise unter einem benutzerdefinierten Namen speichern:
Ich hoffe es ist nützlich für dich. :) :)
quelle
Ich denke nicht, dass das möglich ist. Es gab einen Vorschlag für die Umbenennung von Verstecken, der jedoch noch nicht umgesetzt wurde.
Oder Sie könnten natürlich das Versteck aufschlagen und eine
git stash save [message]
quelle
Zum Nutzen des Lesers finden Sie hier eine Erweiterung der aktuell akzeptierten und korrekten Antwort .
Wenn Sie nicht nur die Stash-Nachricht korrigieren möchten, sondern auch die Commit-Nachricht des Stash korrigieren möchten, so dass
und
beide stimmen dem zu, was gezeigt wird, du brauchst ein bisschen mehr. Es gibt vielleicht einen besseren Weg, aber dieses Rezept hier ist leicht zu verstehen, hoffe ich.
Um dies tun zu können, müssen
git commit --amend
Sie sich auf dem Tipp einer Niederlassung befinden. Daher lautet die Lösung:Erklärt:
git commit --amend
diese Option , um die Festschreibungsnachricht zu ersetzen. Dadurch wird die SHA des "fraglichen Stashs" geändert.Nachteile:
Dadurch werden die Zweige vorübergehend gewechselt. Dieses Rezept kann also nur angewendet werden, wenn
git status --porcelain
es sauber ist (lesen Sie: gibt nichts aus)Die Vorräte werden neu nummeriert, sodass der geänderte Vorrat wird
stash@{0}
Sie müssen die Eingabe
$MESSAGE
zweimal oder verwenden Sie eine Umgebungsvariable (im Beispiel:MESSAGE
)Sie müssen einen nicht verwendeten Filialnamen finden
Es gibt Möglichkeiten, dies zu tun, ohne die Zweige zu wechseln, aber dies würde den Rahmen dieser Antwort sprengen.
Beispiel
Ausgabe
Jetzt ohne Änderung des Commits (Hinweis: Der SHA im Folgenden wird an Ihrer Seite anders sein):
Ausgabe
Wie Sie sehen können, wird
stash@{0}
immer noch wie2fbf900 (refs/stash) WIP on master: 8bdcc32 D
in angezeigtgit log
. Wenn Sie genau hinschauen, werden Sie feststellen, dass mehrere Commits SHA geändert haben. Dies liegt daran, wie mit Stashes umgegangen wird (Eltern sind in der SHA enthalten, und Stashes haben ihre Stashes als Eltern).Repariere das:
Ausgabe
Wie Sie auch sehen können,
refs/stash
hat sich auch die SHA geändert.quelle
Hier ist eine modifizierte Version von Juliens Alias , mit der Sie das
On <branch>
Präfix, das normalerweise vor dem Speichern von Namen steht, richtig behandeln können :Syntax:
Anwendungsbeispiel:
Der größte Teil des Befehls dient zum Parsen der Argumente und zum Herausfinden, was mit dem Zweignamen geschehen soll. Die verwendeten
git
Werkzeuge sind wie folgt:git rev-parse <stash>
um die SHA des Versteckes zu finden.git stash list --format=%gs -1 <stash>
um das Reflog-Thema des Stashs zu finden . Beachten Sie, dass sich dies von der Festschreibungsnachricht des Stash unterscheidet, die durch diesen Befehl nicht geändert wird. Das Reflog-Betreff wird angezeigtgit stash list
, und Sie können das Reflog-Betreff ändern, ohne die Hashes der mit den Stashes verknüpften Commits zu ändern. Sie können jedoch immer die ursprüngliche Festschreibungsnachricht finden.git stash-rename
Entfernen Sie daher keine vertraulichen Informationen!git stash drop <stash>
den alten Verweis auf das Versteck fallen zu lassen (aber wir haben immer noch die SHA, damit sie nicht verloren geht).git stash store -m <new-message> <sha>
Speichern eines neuen Verweises auf den Stash mit denselben Festschreibungsinformationen, jedoch einem anderen Reflog-Betreff .git stash list
um die Verstecke nach Abschluss des Vorgangs aufzulisten. Beachten Sie, dass neue Verstecke immer an den Anfang der Liste verschoben werden. Es wäre notwendig, alle Verstecke vor dem Versteck von Interesse erneut zu verschieben, um seine ursprüngliche Position wiederherzustellen.quelle
Einfachster Weg: Pop deines Stash mit Git Stash Pop, dann speichere es erneut mit Git Stash Save deinen Namen
quelle