web-dev-qa-db-fra.com

Comment inverser l'application d'une cachette?

J'ai un petit patch sauvé dans ma réserve. Je l'ai appliqué à ma copie de travail en utilisant git stash apply. Maintenant, je voudrais revenir sur ces modifications en inversant l’application du correctif (un peu comme ce que git revert ferait mais contre la réserve).

Est-ce que quelqu'un sait comment faire ça?

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 caché. À présent, ma copie de travail est mélangée à d'autres modifications et j'aimerais voir l'effet avec et sans les modifications de la réserve.

Il ne semble pas que stash prenne cela en charge actuellement, mais un git stash apply --reverse serait une fonctionnalité intéressante.

179
Pat Notz

Selon la page de manuel git-stash , "Un stash est représenté par un commit dont l’arborescence enregistre l’état du répertoire de travail, et son premier parent est le commit à HEAD lors de la création du stash" et git stash show -p nous donne "les modifications enregistrées dans la réserve en tant que diff entre l 'état caché et son parent initial.

Pour conserver vos autres modifications intactes, utilisez git stash show -p | patch --reverse comme suit:

$ 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

Modifier:

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

git stash show -p | git apply --reverse

Vous pouvez également utiliser git apply -R comme raccourci pour git apply --reverse.

Je trouve cela très utile ces derniers temps ...

154
Greg Bacon

git stash[save] prend l'état de votre répertoire de travail et de votre index, puis les cache, en définissant l'index et la zone de travail sur HEAD version. 

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

git stash pop ramène ces modifications et supprime les modifications les plus importantes, de sorte que git stash [save] reviendrait à l'état précédent (pré-pop) dans ce cas.

71
Jakub Narębski
git checkout -f

supprimera toutes les modifications non validées.

49
salman

Coupure directe dans la page de manuel -git Elle est clairement libellée et inclut même un alias; 

Désapplication d'un Stash Dans certains cas d'utilisation, vous pouvez appliquer des modifications masquées, effectuer des travaux, mais désappliquer ensuite les modifications issues du stash. Git ne fournit pas une telle commande stash unapply, mais il est possible d'obtenir l'effet en récupérant simplement le patch associé à une stash et en l'appliquant à l'envers:

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

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

$ git stash show -p | git apply -R

Vous voudrez peut-être créer un alias et ajouter efficacement 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
17
Choco Smith

C'est long, mais si j'interprète correctement le problème, j'ai trouvé une solution simple, remarquez, ceci est une explication dans ma propre terminologie:

git stash [save] permettra d'économiser les modifications actuelles et mettra votre branche actuelle sur "l'état de nettoyage"

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

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

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

Le code qui est enregistré dans la cachette n'est pas perdu, il peut être retrouvé par git apply stash@{0} à nouveau. 

Anywhay, cela a fonctionné pour moi!

12
Slim Sim

En plus de la réponse @Greg Bacon, si des fichiers binaires étaient ajoutés à l’index et faisaient partie de la réserve à l’aide de

git stash show -p | git apply --reverse

peut entraîner 

error: cannot apply binary patch to '<YOUR_NEW_FILE>' without full index line
error: <YOUR_NEW_FILE>: patch does not apply

L'ajout de --binary résout le problème, mais n'a malheureusement pas encore compris pourquoi.

 git stash show -p --binary | git apply --reverse
1
MHosafy

Ceci s’ajoute aux réponses ci-dessus, mais ajoute une recherche de la cachette git sur la base du message, car le numéro de la cachette peut changer lorsque de nouvelles cachettes sont enregistrées.

apply(){
  if [ "$1" ]; then
    git stash apply `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"`
  fi
}
remove(){
  if [ "$1" ]; then
    git stash show -p `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"` | git apply -R
    git status
  fi
}
  1. Créer une réserve avec un nom (message) $ git stash save "my stash"
  2. Pour nommer $ apply "my stash"
  3. Pour supprimer le stash nommé $ remove "my stash"
0
lifesoordinary