Annuler une fusion Git


225
develop branch
--> dashboard (working branch)

J'utilise git merge --no-ff developpour fusionner toutes les modifications en amont dans le tableau de bord

journal git:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <root@magneto.giveforward.com>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

La fusion contenait environ 50+ validations, et je me demande comment annuler la fusion pour que le tableau de bord revienne à l'état antérieur à la fusion

La deuxième partie de ceci est, si je ne fais pas de fusion avec --no-ff, je n'obtiens pas le commit ' Merge branch' develop 'into dashboard ' .. Comment pourrais-je annuler cette fusion?


3
Copie possible de la fusion Annuler un Git? .

Réponses:


321

Le fait d'annuler un commit de fusion a été traité de manière exhaustive dans d' autres questions. Lorsque vous effectuez une fusion à avance rapide, la seconde que vous décrivez, vous pouvez utiliser git resetpour revenir à l'état précédent:

git reset --hard <commit_before_merge>

Vous pouvez trouver <commit_before_merge>avec git reflog, git logou, si vous vous sentez le Moxy (et ont rien fait d' autre):git reset --hard HEAD@{1}


6
merci pour la réponse rapide .. en regardant le journal git, la validation avant la fusion est de 50+ validations, car le développement de la fusion git met en fait toutes les autres validations. Je suppose que ce que je ne comprends pas, si je ne sais pas où / où était cette fusion - comment la trouver? Vous mentionnez avoir trouvé le commit_before_merge .. Je suppose que je ne comprends pas cette partie
cgmckeever

4
ressemble à git reflog ressemble à cela résume bien les dernières têtes, et me permet de savoir où je dois réinitialiser. git log semble avoir trop de granularité pour localiser l'endroit où réinitialiser. Merci
cgmckeever

1
Ouais, c'est reflogune bouée de sauvetage. HEAD@{1}décrit simplement le deuxième état le plus récent de HEAD, ou plus techniquement: "Une référence suivie du suffixe @ avec une spécification ordinale entourée d'une paire d'accolades (par exemple {1}, {15}) spécifie la n-ième valeur antérieure de cette réf. "
Christopher

4
Qu'en est-il de pousser le retour à distance? Je ne vois pas comment cela fonctionnera.
Anton Savelyev

2
C'est sans espoir. Il détruit tous les commits après la fusion.
aaa90210

151

D'ici:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git revert ajoute un nouveau commit qui annule le commit spécifié.

L'utilisation de -m 1 indique qu'il s'agit d'une fusion et que nous voulons revenir au commit parent sur la branche principale. Vous utiliseriez -m 2 pour spécifier la branche de développement.


30
Notez que vous ne pouvez pas refusionner la branche après cela, comme le dit la documentation: "La restauration d'une validation de fusion déclare que vous ne voudrez plus jamais les modifications d'arborescence apportées par la fusion. Par conséquent, les fusions ultérieures n'apporteront que les modifications d'arborescence introduites par des validations qui ne sont pas des ancêtres de la fusion précédemment annulée. Cela peut ou non être ce que vous voulez. "
Dalibor Karlović,

23
@ DaliborKarlović Cette déclaration est un peu dure. Vous pouvez certainement ramener ces modifications plus tard, l'astuce consiste à annuler la validation de la restauration. Plus d'informations ici dans la section "Rétablir le retour"
Hilikus

3
Malheureusement, le herelien dans le commentaire @Hilikus n'est plus valide. Le site prétend que le contenu a été déplacé vers un livre ( git-scm.com/book/en/v2 ) mais si c'est le cas, il n'est pas trivial de s'y retrouver.
Jesse Chisholm

@ DaliborKarlović est-ce le cas avec la réponse ci-dessus de @Christopher?
James B

3
Le contenu de la fusion annulée a été déplacé ici
SEK

28

Réinitialisez simplement le commit de fusion avec git reset --hard HEAD^.

Si vous utilisez --no-ff, git crée toujours une fusion, même si vous n'avez rien validé entre les deux. Sans --no-ff, git fera simplement une avance rapide, ce qui signifie que vos branches HEAD seront définies sur HEAD de la branche fusionnée. Pour résoudre ce problème, recherchez l'ID de validation auquel vous souhaitez revenir et git reset --hard $COMMITID.


1
Bonne solution si vous ne connaissez pas le commit avant la fusion.
iglesiasedd

A travaillé pour moi car je ne sais pas id de validation. + 1
Anant Singh --- Alive to Die

si la fusion indésirable a déjà été validée sur remote, j'ai utilisé git push -f pour mettre à jour la branche distante après le rétablissement.
zumek

16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

Mais peut avoir des effets secondaires inattendus. Voir l' --mainline parent-numberoption dans git-scm.com/docs/git-revert

Un moyen brut mais efficace serait de vérifier le parent de gauche de ce commit, de faire une copie de tous les fichiers, de HEADreprendre et de remplacer tout le contenu par les anciens fichiers. Ensuite, git vous dira ce qui est annulé et vous créez votre propre commit de retour :)!


1
+1 parce que cette réponse ne dérange pas l'historique comme le fait la réinitialisation (vraiment important si vous avez déjà poussé à distance). Mais à quels effets secondaires inattendus dois-je m'attendre?
pedromanoel

3
Est-ce l'effet secondaire que vous avez mentionné? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
pedromanoel

1
Vous dites que git resetc'est la solution, mais mentionnez également qu'elle pourrait avoir des effets secondaires inattendus. Cependant, ce lien vient de git revert, pas git reset:)
Mark

2
Veuillez noter que git reset n'a pas d'indicateur -m. Notez également que @JorgeOrpinel fait référence aux documents git-revert, et non git-reset. Je pense qu'il voulait dire git revertnongit reset
Devin Gleason Lambert

Comment éviter Mainline a été spécifié mais commit 1234xyz n'est pas une erreur de fusion .
Achal

0

Si vous avez fusionné la branche, puis annulé la fusion à l'aide d'une demande d'extraction et fusionné cette demande d'extraction pour revenir.

La façon la plus simple que je ressentais était de:

  1. Supprimer une nouvelle branche de develop / master (où vous avez fusionné)
  2. Annulez le "retour" en utilisant git revert -m 1 xxxxxx(si le retour a été fusionné en utilisant une branche) ou en utilisantgit revert xxxxxx s'il s'agissait d'un retour simple
  3. La nouvelle branche devrait maintenant avoir les modifications que vous souhaitez fusionner à nouveau.
  4. Apportez des modifications ou fusionnez cette branche pour développer / maîtriser
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.