351 votes

Comment interrompre un stash pop ?

J'ai ouvert une cachette et il y avait un conflit de fusion. Contrairement à la question qui est listée comme un doublon, j'avais déjà des modifications non validées dans le répertoire que je voulais conserver. Je ne veux pas seulement faire disparaître le conflit de fusion, mais aussi remettre mon répertoire dans l'état où il était avant le pop.

J'ai essayé git merge --abort mais git a déclaré qu'aucune fusion n'était en cours. Existe-t-il un moyen simple d'interrompre un pop sans détruire les modifications que j'avais initialement dans le répertoire ?

0 votes

Quant à vos changements non engagés : ces changements étaient-ils déjà dans l'index ?

0 votes

Pouvez-vous afficher la version de git que vous utilisez ?

0 votes

Est-ce que git a divisé vos fichiers en >>>>> , ===== , <<<<< pour les fusions ?

65voto

Ben Jackson Points 28358

Ok, je pense que j'ai trouvé la solution pour "git stash unapply". C'est plus complexe que git apply --reverse parce que vous avez besoin d'une action de fusion inverse au cas où il y aurait eu une fusion faite par les git stash apply .

La fusion inverse exige que tous les changements actuels soient poussés dans l'index :

  • git add -u

Ensuite, inversez le merge-recursive qui a été fait par git stash apply :

  • git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1

Maintenant, il ne vous restera plus que les changements non-stash. Ils seront dans l'index. Vous pouvez utiliser git reset pour déstocker vos changements si vous le souhaitez.

Étant donné que l'original git stash apply Je suppose que l'inverse pourrait également échouer puisque certaines des choses qu'il veut défaire n'ont pas été faites.

Voici un exemple montrant comment la copie de travail (via le bouton git status ) finit par redevenir propre :

 $ git status
# On branch trunk
nothing to commit (working directory clean)
 $ git stash apply
Auto-merging foo.c
# On branch trunk
# 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:   foo.c
#
no changes added to commit (use "git add" and/or "git commit -a")
 $ git add -u
 $ git merge-recursive stash@{0}: -- $(git write-tree) stash@{0}^1
Auto-merging foo.c
 $ git status
# On branch trunk
nothing to commit (working directory clean)

3 votes

Après avoir fait cela, les modifications précédemment cachées seront-elles perdues pour toujours, ou seront-elles de nouveau dans la cache ?

8 votes

git stash apply ne laisse jamais tomber une cachette, et quand une fusion échoue, alors git stash pop conserve également la cachette

0 votes

De mauvaises choses se produiront s'il y a eu un conflit de fusion pendant le pop original de la cachette.

49voto

DavidG Points 689

Edit : Du git help stash dans la section pop :

L'application de l'état peut échouer en cas de conflits ; dans ce cas, il n'est pas supprimé de la liste de la cachette. Vous devez résoudre les conflits à la main et appeler git stash drop manuellement par la suite.

Si l'option --index est utilisée, elle essaie de rétablir non seulement les modifications de l'arbre de travail, mais aussi celles de l'index. Cependant, cela peut échouer, lorsque vous avez des conflits (qui sont stockés dans l'index, où vous ne pouvez donc plus appliquer les changements tels qu'ils étaient à l'origine).

Essayez de copier en dur votre dépôt dans un nouveau répertoire (afin d'en avoir une copie) et exécutez :

git stash show et enregistrez cette sortie quelque part si vous y tenez.

alors : git stash drop pour laisser tomber la réserve conflictuelle alors : git reset HEAD

Cela devrait laisser votre repo dans l'état où il était avant (si tout va bien, je n'ai toujours pas réussi à reproduire votre problème).

\===

J'essaye de reproduire votre problème mais tout ce que j'obtiens en utilisant git stash pop est :

error: Your local changes to the following files would be overwritten by merge:
...
Please, commit your changes or stash them before you can merge.
Aborting

Dans un endroit propre :

git init
echo hello world > a
git add a & git commit -m "a"
echo hallo welt >> a
echo hello world > b
git add b & git commit -m "b"
echo hallo welt >> b
git stash
echo hola mundo >> a
git stash pop

Je ne vois pas git essayer de fusionner mes modifications, il échoue simplement. Avez-vous des étapes de reproduction que nous pouvons suivre pour vous aider ?

0 votes

Essayez de stocker les changements dans un autre fichier.

0 votes

Essayer de cacher dans un fichier différent n'a pas fonctionné (voir les nouvelles étapes de reproduction). Je n'arrive pas à reproduire le problème...

1 votes

Cette solution ne fonctionne pas s'il y a des modifications non validées dans le répertoire de travail.

4voto

agentgonzo Points 517

OK, je pense avoir réussi à trouver une méthode de travail qui vous permettra de revenir là où vous devez être (comme si vous n'aviez pas fait la pop).

FAITES UNE SAUVEGARDE AU PRÉALABLE ! Je ne sais pas si cela va fonctionner pour vous, alors copiez votre repo entier juste au cas où cela ne fonctionnerait pas.

1) Corriger les problèmes de fusion et régler tous les conflits en sélectionnant tous les changements qui proviennent du patch (dans tortoisemerge, cela apparaît comme un.REMOETE (leur)).

git mergetool

2) Valider ces changements (ils seront déjà ajoutés via la commande mergetool). Donnez-lui un message de commit de "merge" ou quelque chose dont vous vous souvenez.

git commit -m "merge"

3) Maintenant, vous aurez toujours vos changements locaux non indexés que vous avez commencé à l'origine, avec un nouveau commit du patch (nous pouvons nous débarrasser de cela plus tard). Maintenant, livrez vos changements non-stagés

git add .
git add -u .
git commit -m "local changes"

4) Inversez le patch. Ceci peut être fait avec la commande suivante :

git stash show -p | git apply -R

5) Valider ces changements :

git commit -a -m "reversed patch"

6) Se débarrasser des commits patch/unpatch

git rebase -i HEAD^^^

à partir de là, supprimez les deux lignes contenant 'merge' et 'reversed patch'.

7) Récupérez vos modifications non modifiées et annulez le commit "modifications locales".

git reset HEAD^

Je l'ai testé avec un exemple simple et il vous ramène à l'endroit où vous voulez être - juste avant que la réserve ne soit ouverte, avec vos changements locaux et avec la réserve toujours disponible pour l'ouverture.

0 votes

Si cela ne fonctionne pas tout à fait, j'espère que cela vous permettra de faire une bonne partie du chemin ! :-)

0 votes

git stash show -p | git apply -R qui ne fonctionne pas si le git stash apply n'a pas fait de réelle fusion. Voir ma réponse...

2voto

asmeurer Points 13185

Quelques idées :

  • Utilisez git mergetool pour diviser les fichiers de fusion en parties originales et nouvelles. Avec un peu de chance, l'une d'entre elles est le fichier contenant vos modifications non stash.

  • Appliquez le diff de la cachette en sens inverse, pour annuler seulement ces changements. Vous devrez probablement séparer manuellement les fichiers avec les conflits de fusion (pour lesquels l'astuce ci-dessus devrait fonctionner).

Je n'ai pas testé l'une ou l'autre de ces solutions, donc je ne suis pas sûr qu'elles fonctionneront.

1voto

Jakub Narębski Points 87537

Je pourrais reproduire proprement git stash pop sur un répertoire "sale", avec des modifications non validées, mais pas encore pop qui génère un conflit de fusion.

Si sur le conflit de fusion la cachette que vous avez essayé d'appliquer n'a pas disparu, vous pouvez essayer d'examiner git show stash@{0} (éventuellement avec --ours o --theirs ) et comparer avec git statis y git diff HEAD . Vous devriez être en mesure de voir quelles modifications proviennent de l'application d'une cachette.

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