pop-le et enregistrez-le à nouveau avec un nom différent?
Bartlomiej Lewandowski
5
Le popping et le stashing à nouveau ne sont pas toujours une option, car le stash peut être basé sur un état obsolète et entraîner des conflits lors du popping. (L'état obsolète n'a même plus besoin d'exister nulle part dans l'histoire.)
Tom
Réponses:
259
Supposons que votre liste de dissimulations ressemble à ceci:
$ git stash list
stash@{0}: WIP on master: Add some very important feature
stash@{1}: WIP on master: Fix some silly bug
Tout d'abord, vous devez supprimer l'entrée cachée que vous souhaitez renommer:
$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)
Maintenant, ajoutez-le à nouveau avec un nouveau message en utilisant sha de commit retourné après la suppression:
$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db
Et c'est tout:
$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature
Cette solution nécessite git 1.8.4 ou une version ultérieure, et oui, elle fonctionne également avec un répertoire de travail sale.
git show stash@{0}affiche toujours les anciennes informations par la suite. Comment y remédier? (Veuillez noter que la cachette obtient alors un SHA différent.)
Tino
4
Il est préférable d'obtenir le hachage git showet de commencer git stash store. Ensuite, git stash listvous verrez l'ancienne et la nouvelle cachette. Enfin, vous pouvez nettoyer l'ancienne cachette avec git stash drop.
hogi
6
git stash drop ne perdra-t-il pas les modifications?
Shravya Boggarapu
4
@ShravyaBoggarapu, non, git ne supprime pas le commit jusqu'à ce qu'il git gcsoit exécuté. Après, stash dropvous pouvez facilement trouver ce commit normalement inaccessible à l'aide de la git fsck | grep commitcommande.
qzb
2
@ ÐerÆndi simplement appliquer et enregistrer est une option facile, mais ne fonctionne pas lorsque les modifications ne peuvent pas être réappliquées en raison de conflits. Pendant ce temps, la suppression et le stockage des œuvres en toutes circonstances. J'ai testé ma solution une fois de plus - cela fonctionne très bien sur la dernière version de git (2.17.0).
qzb
62
Sauf si vous le faites manuellement ou apportez une amélioration à Git, vous pouvez utiliser un alias:
Avec [save options]n'importe quelle option de git stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Exemple:
$ 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
Cela fonctionnera même si vous avez des modifications locales non mises en scène :)
Impressionnant! Encore plus cool si vous pouviez le fairegit stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
mikemaccana
3
la réponse est donc 1) nettoyer la copie de travail, 2) appliquer la cachette que vous souhaitez renommer, 3) la supprimer de la liste des cachettes, 4) créer une nouvelle cachette avec le bon message.
gcb
2
Pour clarifier, vous renommez la dernière cachette, et après une telle action, elle devient la cachette supérieure?
onebree
2
Je supprime la cachette à renommer, enregistre les modifications actuelles le cas échéant, recrée la cachette supprimée avec le nom souhaité, réapplique les modifications actuelles le cas échéant.
Julien Carsique
3
Cette version vérifie que les deux arguments sont là pour ne pas simplement laisser tomber votre dernière cachette accidentellement. Il ne requiert également que le numéro de réserve, pas la stash@{0}référence entière . 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
C'est très simple. Tout d'abord, annulez la dernière cachette avec:
git stash pop
Après cela, vous pouvez enregistrer la cachette avec un nom personnalisé de cette façon:
Implémentez une nouvelle git reflog updatecommande qui met à jour le message associé à une entrée de reflog spécifique. Pour ce faire, une nouvelle update_reflog_ent()fonction (dans reflog.c ) changerait le message associé à l'entrée de reflog spécifique à mettre à jour. Une update_reflog()fonction utiliserait for_each_reflog_ent()avec update_reflog_entpour effectuer le changement.
Une git stash renamecommande n'aurait alors besoin que d'appeler git
reflog updateavec la référence appropriée et le nouveau message.
Ou vous pouvez, bien sûr, sauter la cachette et faire un git stash save [message]
Si vous souhaitez non seulement corriger le message de dissimulation et également corriger le message de validation de la dissimulation, de telle sorte que
git stash list
et
git log --oneline -1 stash
les deux sont d'accord sur ce qui est montré, il vous en faut un peu plus. Il pourrait y avoir une meilleure façon de le faire, mais cette recette ici est facile à comprendre, j'espère.
Pour pouvoir le faire, git commit --amendvous devez être sur le TIP d'une succursale. La solution est donc:
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
Expliqué:
Créez une nouvelle branche "scratch" (pas encore existante) à partir de la "cachette en question" et passez à celle-ci
Retirez l'ancienne cachette. C'est sûr, car nous l'avons toujours sur la branche.
Utilisez git commit --amendpour remplacer le message de validation, ce qui modifie le SHA de la "cachette en question"
Revenez en arrière (ce qui suppose que vous venez du "maître") et nettoyez
Désavantages:
Cela change temporairement de branche. Cette recette ne peut donc être appliquée que lorsqu'elle git status --porcelainest propre (lire: ne produit rien)
Il renumérote les cachettes, donc la cachette changée devient stash@{0}
Vous devez entrer le $MESSAGEdouble ou utiliser une variable d'environnement (dans l'exemple: MESSAGE)
Vous devez trouver un nom de branche inutilisé
Il existe des moyens de le faire sans changer de branche, mais cela dépasse le cadre de cette réponse.
Exemple
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
Production
*-. 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
Maintenant sans changer de commit (note: le SHA suivant sera différent à vos côtés):
git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list
Production
*-. 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
Comme vous pouvez le voir, l'image stash@{0}est affichée comme 2fbf900 (refs/stash) WIP on master: 8bdcc32 Ddans git log. Si vous regardez attentivement, vous verrez que plusieurs validations ont changé SHA. Cela est dû à la façon dont les cachettes sont gérées (les parents sont inclus dans la SHA et les cachettes ont leurs cachettes en tant que parent).
Répare ça:
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
Production
*-. 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
Comme vous pouvez également le voir, le refs/stashSHA a également changé.
À noter: cela détruit l'index qui a été enregistré avec la cachette d'origine, en le remplaçant par un nouvel index qui correspond à la validation parent de la cachette d'origine. Si l'on ne prévoyait pas d'utiliser l'index enregistré d'origine (ou qu'il correspondait déjà au parent de la cachette d'origine), ce n'est pas un problème.
torek
1
Voici une version modifiée de l'alias de Julien qui vous permet de gérer correctement le On <branch>préfixe généralement ajouté au début pour cacher les noms:
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
La plupart de la commande sert à analyser les arguments et à déterminer ce qui doit être fait pour le nom de la branche. Les gitoutils utilisés sont les suivants:
git rev-parse <stash> pour trouver le SHA de la cachette.
git stash list --format=%gs -1 <stash>pour trouver le sujet reflog de la cachette. Notez que ceci est différent du message de validation de la cachette, qui n'est pas modifié par cette commande. Le sujet de reflog est ce qui apparaît git stash listet vous pouvez changer le sujet de reflog sans changer les hachages des commits associés aux stashes. Cependant, vous pouvez toujours trouver le message de validation d'origine, alors ne l'utilisez pas git stash-renamepour supprimer des informations sensibles!
git stash drop <stash>pour supprimer l'ancienne référence à la cachette (mais nous avons toujours le SHA, il n'est donc pas perdu).
git stash store -m <new-message> <sha>pour enregistrer une nouvelle référence à la cachette avec les mêmes informations de validation mais un sujet de reflog différent .
git stash listpour lister les stashes une fois l'opération terminée. Notez que les nouveaux stashes sont toujours poussés au début de la liste. Il faudrait repousser toutes les cachettes avant la cachette d'intérêt afin de rétablir sa position d'origine.
Réponses:
Supposons que votre liste de dissimulations ressemble à ceci:
Tout d'abord, vous devez supprimer l'entrée cachée que vous souhaitez renommer:
Maintenant, ajoutez-le à nouveau avec un nouveau message en utilisant sha de commit retourné après la suppression:
Et c'est tout:
Cette solution nécessite git 1.8.4 ou une version ultérieure, et oui, elle fonctionne également avec un répertoire de travail sale.
la source
git show stash@{0}
affiche toujours les anciennes informations par la suite. Comment y remédier? (Veuillez noter que la cachette obtient alors un SHA différent.)git show
et de commencergit stash store
. Ensuite,git stash list
vous verrez l'ancienne et la nouvelle cachette. Enfin, vous pouvez nettoyer l'ancienne cachette avecgit stash drop
.git gc
soit exécuté. Après,stash drop
vous pouvez facilement trouver ce commit normalement inaccessible à l'aide de lagit fsck | grep commit
commande.Sauf si vous le faites manuellement ou apportez une amélioration à Git, vous pouvez utiliser un alias:
Utilisation: "
git stash-rename <stash> [save options] [<message>]
"Avec
[save options]
n'importe quelle option degit stash save
:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Exemple:
Cela fonctionnera même si vous avez des modifications locales non mises en scène :)
EDIT 2016/02/22
Script simplifié, crédits à qzb , https://stackoverflow.com/a/35549615/515973
Utilisation: "
git stash-rename <stash> [<message>]
"la source
git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
stash@{0}
référence entière . 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 }; _'
C'est très simple. Tout d'abord, annulez la dernière cachette avec:
Après cela, vous pouvez enregistrer la cachette avec un nom personnalisé de cette façon:
J'espère que cela vous sera utile. :)
la source
Je ne pense pas que ce soit possible. Il a été proposé de renommer la cachette, mais elle n'a pas encore été mise en œuvre.
Ou vous pouvez, bien sûr, sauter la cachette et faire un
git stash save [message]
la source
Pour le bénéfice du lecteur, voici une extension de la réponse correcte et acceptée actuellement .
Si vous souhaitez non seulement corriger le message de dissimulation et également corriger le message de validation de la dissimulation, de telle sorte que
et
les deux sont d'accord sur ce qui est montré, il vous en faut un peu plus. Il pourrait y avoir une meilleure façon de le faire, mais cette recette ici est facile à comprendre, j'espère.
Pour pouvoir le faire,
git commit --amend
vous devez être sur le TIP d'une succursale. La solution est donc:Expliqué:
git commit --amend
pour remplacer le message de validation, ce qui modifie le SHA de la "cachette en question"Désavantages:
Cela change temporairement de branche. Cette recette ne peut donc être appliquée que lorsqu'elle
git status --porcelain
est propre (lire: ne produit rien)Il renumérote les cachettes, donc la cachette changée devient
stash@{0}
Vous devez entrer le
$MESSAGE
double ou utiliser une variable d'environnement (dans l'exemple:MESSAGE
)Vous devez trouver un nom de branche inutilisé
Il existe des moyens de le faire sans changer de branche, mais cela dépasse le cadre de cette réponse.
Exemple
Production
Maintenant sans changer de commit (note: le SHA suivant sera différent à vos côtés):
Production
Comme vous pouvez le voir, l'image
stash@{0}
est affichée comme2fbf900 (refs/stash) WIP on master: 8bdcc32 D
dansgit log
. Si vous regardez attentivement, vous verrez que plusieurs validations ont changé SHA. Cela est dû à la façon dont les cachettes sont gérées (les parents sont inclus dans la SHA et les cachettes ont leurs cachettes en tant que parent).Répare ça:
Production
Comme vous pouvez également le voir, le
refs/stash
SHA a également changé.la source
Voici une version modifiée de l'alias de Julien qui vous permet de gérer correctement le
On <branch>
préfixe généralement ajouté au début pour cacher les noms:Syntaxe:
Exemple d'utilisation:
La plupart de la commande sert à analyser les arguments et à déterminer ce qui doit être fait pour le nom de la branche. Les
git
outils utilisés sont les suivants:git rev-parse <stash>
pour trouver le SHA de la cachette.git stash list --format=%gs -1 <stash>
pour trouver le sujet reflog de la cachette. Notez que ceci est différent du message de validation de la cachette, qui n'est pas modifié par cette commande. Le sujet de reflog est ce qui apparaîtgit stash list
et vous pouvez changer le sujet de reflog sans changer les hachages des commits associés aux stashes. Cependant, vous pouvez toujours trouver le message de validation d'origine, alors ne l'utilisez pasgit stash-rename
pour supprimer des informations sensibles!git stash drop <stash>
pour supprimer l'ancienne référence à la cachette (mais nous avons toujours le SHA, il n'est donc pas perdu).git stash store -m <new-message> <sha>
pour enregistrer une nouvelle référence à la cachette avec les mêmes informations de validation mais un sujet de reflog différent .git stash list
pour lister les stashes une fois l'opération terminée. Notez que les nouveaux stashes sont toujours poussés au début de la liste. Il faudrait repousser toutes les cachettes avant la cachette d'intérêt afin de rétablir sa position d'origine.la source
Manière la plus simple: faites éclater votre cachette avec git stash pop puis enregistrez-la à nouveau avec git stash sauvegardez votre nom
la source