Comment résoudre un conflit de git stash sans commettre?
comme dans cette question , je veux aussi savoir comment résoudre un conflit git stash pop
sans ajouter toutes les modifications à une propagation (tout comme" git stash pop " sans conflit le fait).
mon approche actuelle est très peu cool parce que je le fais de cette façon:
git stash pop -> CONFLICT
git stash drop
[resolve conflict]
[add conflict files]
git reset HEAD <all files that are in commit-mode>
[Update] une façon de le reproduire:
mkdir foo; cd foo; git init
echo "1" > one
echo "2" > two
git add -A; git commit -m "first"
echo "1.1" > one
echo "2.1" > two
git stash
echo "2.2" > two
git commit -a -m "second"
echo "Only this file would stay in HEAD without the conflict" > third
git add third
git stash pop
git status
2016-06-27: Ajout d'un nouveau fichier appelé "tiers", à l'exemple de montrer que les solutions de contournement comme la solution de scy ne fonctionnent que pour les têtes vides mais ne corrigent pas le problème initial que la tête n'a pas le même contenu que pour un git stash pop
sans conflit.
10 réponses
supposons que vous ayez ce scénario où vous stockez vos changements afin de tirer de l'origine. Peut-être parce que vos modifications locales ne sont que debug: true
dans certains fichiers de paramètres. Maintenant vous tirez et quelqu'un a introduit un nouveau cadre là, créant un conflit.
git status
dit:
# On branch master
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: src/js/globals.tpl.js
no changes added to commit (use "git add" and/or "git commit -a")
OK. J'ai décidé d'aller avec ce que Git a suggéré: j'ai résolu le conflit et commis:
vim src/js/globals.tpl.js
# type type type …
git commit -a -m WIP # (short for "work in progress")
maintenant mon de la copie de travail est dans l'état que je veux, mais j'ai créé un commit que je ne veux pas avoir. Comment puis-je me débarrasser de cette propagation sans modifier ma copie de travail? Attendez, il y a une commande populaire pour ça!
git reset HEAD^
ma copie de travail n'a pas été modifiée, mais la propagation WIP a disparu. C'est exactement ce que je voulais! (Notez que je n'utilise pas --soft
ici, parce que s'il y a des fichiers auto-fusionnés dans votre planque, ils sont auto-échelonnés et donc vous finiriez avec ces dossiers mis en scène à nouveau après reset
.)
mais il reste encore une chose: la page de manuel de git stash pop
nous rappelle que " appliquer l'état peut échouer avec des conflits; dans ce cas, il n'est pas retiré de la liste des cachettes. Vous devez résoudre les conflits à la main et appeler git stash drop
manuellement par la suite." c'est exactement ce que nous faisons maintenant:
git stash drop
et fait.
Je ne pense pas que faire un commit et ensuite Réinitialiser la branche pour supprimer ce commit et les solutions de rechange similaires suggérées dans d'autres réponses sont la bonne façon de résoudre ce problème.
la solution suivante me semble beaucoup plus propre et elle est également suggérée par le Git lui-même - exécuter git status
dans le dépôt avec un conflit:
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
faisons ce que Git suggère sans commettre:
- résoudre le (S) conflit(s) manuellement (ou à l'aide d'un outil de fusion de L'interface graphique).
- utiliser
git reset
pour marquer le(S) conflit (s) résolu (s) et déballer les changements. Vous pouvez l'exécuter sans paramètres et Git va tout supprimer de l'index. Vous n'avez pas à exécutergit add
avant. - enfin, retirez la cachette avec
git stash drop
, parce que Git ne fait pas cela en cas de conflit.
:
$ git stash pop
# ...manually resolve conflict(s)
$ git reset
$ git stash drop
Note: ajouter des fichiers à l'index après la résolution d'un conflit est fait exprès. De cette façon, vous pouvez différencier les changements de la cachette précédente et les changements que vous avez faits après que le conflit a été résolu. Si vous ne l'aimez pas, vous pouvez toujours utiliser git reset
pour supprimer tout de l'index.
une autre note: je recommande fortement l'utilisation de l'un des outils de fusion à trois voies pour résolution de conflits, p.ex. KDiff3 . Il résout généralement majorité des conflits automatiquement lui-même.
au lieu d'ajouter les modifications que vous faites pour résoudre le conflit, vous pouvez utiliser git reset HEAD file
pour résoudre le conflit sans mettre en scène vos modifications.
Vous pouvez exécuter cette commande deux fois, cependant. Une fois pour marquer que le conflit a été résolu et une autre pour déballer les changements qui ont été mis en place par la routine de résolution de conflit.
il est possible qu'il y ait un mode reset qui fait ces deux choses simultanément, bien qu'il y ait pas un maintenant.
git checkout stash -- .
travaillait pour moi.
Note : cela peut être dangereux car il n'essaie pas de fusionner les changements de la cachette dans votre copie de travail, mais l'écrira avec les fichiers cachés à la place. Donc vous pouvez perdre vos changements non engagés.
Il semble que ce peut être la réponse que vous cherchez, je n'ai pas essayé personnellement, mais il me semble qu'il peut faire l'affaire. Avec cette commande GIT va essayer d'appliquer les changements à mesure qu'ils étaient avant, sans essayer de les ajouter pour la validation.
git stash apply --index
voici l'explication complète:
git add .
git reset
git add .
mettra en scène tous les fichiers disant à git que vous avez résolu le conflit
git reset
va dégrafer tous les fichiers mis en scène sans créer de commit
le moyen le plus rapide que j'ai trouvé est de résoudre le conflit, puis faire git add -u
, et puis faire git reset HEAD
, qui n'implique même pas un commit.
selon git stash questions , après la fixation du conflit, git add <file>
est la bonne voie de l'action.
C'est après avoir lu ce commentaire que j'ai compris que les modifications sont automatiquement ajoutées à l'index (par conception). C'est pourquoi git add <file>
achève le processus de résolution des conflits.
ce n'est pas la meilleure façon de le faire, mais ça marche:
$ git stash apply
$ >> resolve your conflict <<
$ >> do what you want to do with your code <<
$ git checkout HEAD -- file/path/to/your/file