323 votes

Comment appliquer à l'envers une cachette ?

J'ai un petit patch sauvegardé dans ma cachette git. Je l'ai appliqué à ma copie de travail en utilisant la fonction git stash apply . Maintenant, j'aimerais annuler ces changements en appliquant le correctif de manière inverse (un peu comme ce que fait le git revert ferait mais contre la réserve).

Quelqu'un sait-il comment faire ?

Clarification : Il y a d'autres changements dans ma copie de travail. Mon cas particulier est difficile à décrire mais vous pouvez imaginer un code de débogage ou expérimental qui se trouve dans la cachette. Il est maintenant mélangé dans ma copie de travail avec d'autres changements et je voudrais voir l'effet avec et sans les changements de la cachette.

Il ne semble pas que Stash supporte cela actuellement, mais une git stash apply --reverse serait une fonctionnalité intéressante.

1 votes

Ne peut-on pas simplement créer un patch inversé en faisant la différence entre la révision actuelle et la précédente ? Et ensuite appliquer celui-là ?

0 votes

Y a-t-il des changements dans l'arbre de travail autres que la réserve appliquée ?

0 votes

Ajouter ceci ici, ... était censé être une FAQ pas une question... stackoverflow.com/questions/59973103/

238voto

Greg Bacon Points 50449

Selon le Page de manuel de git-stash , "Une cachette est représentée comme un commit dont l'arbre enregistre l'état du répertoire de travail, et son premier parent est le commit à HEAD quand la cachette a été créée", et git stash show -p nous donne "les changements enregistrés dans la cachette comme une différence entre l'état caché et son parent original.

Pour garder vos autres changements intacts, utilisez git stash show -p | patch --reverse comme dans l'exemple suivant :

$ git init
Initialized empty Git repository in /tmp/repo/.git/

$ echo Hello, world >messages

$ git add messages

$ git commit -am 'Initial commit'
[master (root-commit)]: created 1ff2478: "Initial commit"
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 messages

$ echo Hello again >>messages

$ git stash

$ git status
# On branch master
nothing to commit (working directory clean)

$ git stash apply
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   messages
#
no changes added to commit (use "git add" and/or "git commit -a")

$ echo Howdy all >>messages

$ git diff
diff --git a/messages b/messages
index a5c1966..eade523 100644
--- a/messages
+++ b/messages
@@ -1 +1,3 @@
 Hello, world
+Hello again
+Howdy all

$ git stash show -p | patch --reverse
patching file messages
Hunk #1 succeeded at 1 with fuzz 1.

$ git diff
diff --git a/messages b/messages
index a5c1966..364fc91 100644
--- a/messages
+++ b/messages
@@ -1 +1,2 @@
 Hello, world
+Howdy all

Edit :

Une légère amélioration consiste à utiliser git apply à la place du patch :

git stash show -p | git apply --reverse

Alternativement, vous pouvez aussi utiliser git apply -R comme raccourci pour git apply --reverse .

J'ai trouvé ça très pratique ces derniers temps...

2 votes

Génial, merci. Il semble que cela pourrait être une fonctionnalité intéressante pour Stash.

7 votes

Oui, git apply -R est une amélioration, du moins pour moi sur ma boîte Windows avec git bash comme patch --reverse J'ai eu des problèmes pour localiser le fichier à corriger (je ne sais pas vraiment pourquoi l'alternative a fonctionné). +1 et bonne explication

0 votes

Ne serait-il pas préférable d'ajouter --index juste comme ça git stash show -p | git apply --reverse --index . En effet, il n'est plus nécessaire d'ajouter dans l'index les modifications qui sont annulées.

222voto

salman Points 1219
git checkout -f

supprimera tous les changements non-commit.

8 votes

Merci, vous m'avez aidé à résoudre le problème de la modification progressive qui n'a pas été annulée.

13 votes

C'était beaucoup plus simple

0 votes

C'était génial !

95voto

Jakub Narębski Points 87537

git stash[save] prend l'état de votre répertoire de travail, et l'état de votre index, et les stocke, en mettant l'index et la zone de travail à HEAD version.

git stash apply ramène ces changements, donc git reset --hard les retirerait à nouveau.

git stash pop ramène ces modifications et supprime la modification supérieure cachée, donc git stash [save] reviendrait à l'état précédent (pré-pop) dans ce cas.

41voto

Choco Smith Points 321

La page de manuel git de la V1 contenait une référence à propos de la désapplication d'une réserve. L'extrait est ci-dessous.

La nouvelle V2 page de manuel git n'inclut pas de référence à la désapplication d'une réserve, mais l'exemple ci-dessous fonctionne bien.

Désapplication d'une cachette Dans certains cas d'utilisation, vous pouvez vouloir appliquer des modifications mises en réserve, effectuer un travail, mais ensuite annuler les modifications qui provenaient initialement de la réserve. Git ne fournit pas une telle commande de désapplication de stash, mais il est possible d'obtenir cet effet en récupérant simplement le patch associé à un stash et en l'appliquant en sens inverse :

$ git stash show -p stash@{0} | git apply -R

Encore une fois, si vous ne spécifiez pas de cachette, Git prend la cachette la plus récente :

$ git stash show -p | git apply -R

Vous pouvez vouloir créer un alias et ajouter effectivement une commande stash-unapply à votre Git. Par exemple :

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
$ git stash apply
$ #... work work work
$ git stash-unapply

2 votes

Pour une raison quelconque, la section utile dont vous avez donné le lien, intitulée "Désappliquer une cachette", a été supprimée de la deuxième version. -La dernière version en date est 2.1.146, 2019-04-15- de ce livre V2- Outils Git - Mise en réserve et nettoyage . C'est peut-être parce que les auteurs pensent qu'il y a une meilleure façon de faire que je n'arrive pas à trouver.

1 votes

@NadAlaba merci pour l'info, j'ai mis à jour la réponse pour noter la différence entre v1 et v2... c'est bizarre, les auteurs du git ont enlevé la section sur la désapplication d'une réserve.

1 votes

Cette réponse est particulièrement utile pour montrer comment spécifier la réserve appliquée. Merci d'avoir inclus cette information importante ! Pour ceux qui auraient également inclus des fichiers non suivis, vous pouvez utiliser la méthode suivante git stash show -p --all stash@{3} | git apply -R

15voto

Slim Sim Points 26

Cela fait longtemps qu'il aurait fallu le faire, mais si j'interprète correctement le problème, j'ai trouvé une solution simple, notez qu'il s'agit d'une explication dans ma propre terminologie :

git stash [save] sauvegardera les changements actuels et mettra votre branche actuelle dans un "état propre".

git stash list donne quelque chose comme : stash@{0}: On develop: saved testing-stuff

git apply stash@{0} va définir la branche actuelle comme avant stash [save]

git checkout . Définira la branche actuelle comme après stash [save]

Le code qui est sauvegardé dans la cachette n'est pas perdu, il peut être retrouvé en git apply stash@{0} encore.

Quoi qu'il en soit, ça a marché pour moi !

0 votes

Juste pour être sûr, j'ai appliqué un git stash apply --reverse d'abord et ensuite simplement revenir à git stash apply stash@{x} comme vous le mentionnez. Ça a marché sans problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X