286 votes

Refaire une fusion annulée dans Git

J'ai rencontré un petit problème ici : J'avais une branche spécifique au problème 28s dans Git, que j'ai fusionné dans le général develop branch. Il s'est avéré que je l'avais fait trop vite, alors j'ai utilisé git-revert pour annuler la fusion. Maintenant, cependant, le temps est venu de fusionner 28s en develop mais la commande git-merge voit la fusion originale, et annonce joyeusement que tout va bien et que les branches ont déjà été fusionnées. Que dois-je faire maintenant ? Créer un commit 'Revert "Revert "28s -> develop"" ? Cela ne semble pas être une bonne façon de faire, mais je ne peux pas en imaginer une autre pour le moment.

Ce à quoi ressemble l'arborescence :

Git log output

4 votes

C'est GitX ( gitx.frim.nl ).

199voto

J-16 SDiZ Points 14191

Vous devez "inverser l'inversion". En fonction de la façon dont vous avez effectué la réversion originale, cela peut ne pas être aussi facile qu'il n'y paraît. Regardez le document officiel sur ce sujet .

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

pour permettre :

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

Mais est-ce que tout cela fonctionne ? Bien sûr que oui. Vous pouvez inverser une fusion, et d'un point de vue d'un point de vue purement technique, git l'a fait très naturellement et n'a pas eu de réels problèmes.
Il a juste considéré que c'était un changement de "l'état avant la fusion" à "état après la fusion", et c'est tout.
Rien de compliqué, rien de bizarre, rien de vraiment dangereux. Git le fera sans même y penser.

Donc, d'un point de vue technique, il n'y a rien de mal à revenir sur une fusion, mais Du point de vue du flux de travail, c'est quelque chose que vous devez généralement essayer d'éviter. d'éviter .

Si c'est possible, par exemple, si vous trouvez un problème qui a été fusionné dans l'arbre principal, plutôt que de rétablir la fusion, essayez vraiment difficile de :

  • bisecter le problème dans la branche que vous avez fusionnée, et juste le corriger,
  • ou essayer de revenir sur le commit individuel qui l'a causé.

Oui, c'est plus complexe, et non, ça ne marchera pas toujours (parfois, la réponse est : " oui "). la réponse est : " oups, je n'aurais vraiment pas dû fusionner, parce que ce n'était pas encore n'était pas encore prêt, et j'ai vraiment besoin de le défaire. tous de la fusion"). Ainsi, vous vous devriez vraiment inverser la fusion, mais quand vous voulez refaire la fusion, vous devez vous devez maintenant le faire en annulant le retour en arrière.

17 votes

Bon lien (+1). J'ai pris la liberté de copier une partie du document dans votre réponse afin de permettre aux lecteurs de voir immédiatement les options pertinentes dans ce cas. Si vous n'êtes pas d'accord, n'hésitez pas à revenir sur votre réponse.

6 votes

Nous venons de rencontrer un cas où nous devions le faire et nous avons constaté que le plaisir ne s'arrête pas là. C'est une branche qui a été fusionnée depuis longtemps, nous devions donc continuer à la mettre à jour. Mon approche ici : tech.patientslikeme.com/2010/09/29/

0 votes

J'ai suivi l'article du blog de @jdwyah et c'était glorieux (sérieusement, c'était génial que ça ait marché).

69voto

Maksim Kotlyar Points 1022

Supposons que vous ayez une telle histoire

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

Où A, B sont des commits ratés et W - est un revert de M

Donc, avant de commencer à corriger les problèmes trouvés, je fais un cherry-pick de W commit dans ma branche.

git cherry-pick -x W

Puis je rétablis W commit sur ma branche

git revert W 

Après je peux continuer à réparer.

L'histoire finale pourrait ressembler à ça :

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

Lorsque j'envoie un PR, il est clairement indiqué que le PR est un undo revert et ajoute de nouveaux commits.

4 votes

Cela semble pouvoir être utile, mais les détails sont si peu nombreux (que sont C et D dans le dernier diagramme) que c'est plus frustrant qu'utile.

5 votes

@Isochronous C et D semblent être des commits qui corrigent les problèmes introduits par A et B.

0 votes

@Thomas exactement

35voto

Sam Dufel Points 10154

Pour revenir en arrière sans trop perturber votre flux de travail :

  • Créer une copie de la corbeille locale de développer
  • Inverser le commit revert sur la copie locale de development
  • Fusionnez cette copie dans votre branche de fonctionnalité, et poussez votre branche de fonctionnalité sur votre serveur git.

Votre branche de fonctionnalité devrait maintenant pouvoir être fusionnée normalement lorsque vous serez prêt. Le seul inconvénient est que vous aurez quelques commits de fusion/réduction supplémentaires dans votre historique.

18voto

Richard Points 503

Pour revenir sur un revert dans GIT :

git revert <commit-hash-of-previous-revert>

5voto

knweiss Points 331

Au lieu d'utiliser git-revert vous auriez pu utiliser cette commande dans le devel à la branche jeter (annuler) le mauvais commit de fusion (au lieu de simplement le rétablir).

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

Cela ajustera également le contenu du répertoire de travail en conséquence. Soyez prudent. :

  • Enregistrez vos modifications dans la branche de développement (depuis la mauvaise fusion) parce qu'elles aussi seront effacées par la git-reset . Tous les commits après celui que vous spécifiez comme l'adresse git reset l'argument disparaîtra !
  • Aussi, ne faites pas cela si vos modifications ont déjà été extraites d'autres dépôts car la réinitialisation réécrira l'historique.

Je recommande d'étudier le git-reset man-page attentivement avant d'essayer ceci.

Maintenant, après la réinitialisation, vous pouvez ré-appliquer vos modifications dans devel et ensuite faire

git checkout devel
git merge 28s

Il s'agira d'une véritable fusion entre 28s en devel comme la version initiale (qui est maintenant effacé de l'historique de git).

11 votes

Pour tous ceux qui ne sont pas très familiers avec git et qui voudraient suivre ces instructions : attention à la combinaison des éléments suivants reset --hard y push origin . Sachez également qu'un push forcé vers l'origine peut vraiment perturber les PRs ouverts sur GitHub.

0 votes

Très utile pour résoudre certains problèmes de fusion sur un serveur git privé. Merci !

1 votes

+1 pour cette technique. Potentiellement destructeur, mais peut vous épargner bien des maux de tête (et une histoire tronquée) lorsqu'il est appliqué judicieusement.

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