Quand utiliseriez-vous les différentes stratégies de fusion git?

430

Dans la page de manuel sur git-merge, vous pouvez utiliser un certain nombre de stratégies de fusion.

  • résoudre - Cela ne peut résoudre que deux têtes (c'est-à-dire la branche actuelle et une autre branche dont vous avez tiré) en utilisant l'algorithme de fusion à 3 voies. Il essaie de détecter soigneusement les ambiguïtés de fusion croisées et est généralement considéré comme sûr et rapide.

  • récursif - Cela ne peut résoudre que deux têtes en utilisant un algorithme de fusion à 3 voies. Lorsqu'il existe plusieurs ancêtres communs pouvant être utilisés pour la fusion à 3 voies, il crée un arbre fusionné des ancêtres communs et l'utilise comme arbre de référence pour la fusion à 3 voies. Il a été signalé que cela entraîne moins de conflits de fusion sans provoquer de mauvaises fusions par les tests effectués sur les validations de fusion réelles tirées de l'historique de développement du noyau Linux 2.6. De plus, cela peut détecter et gérer les fusions impliquant des renommages. Il s'agit de la stratégie de fusion par défaut lors de l'extraction ou de la fusion d'une branche.

  • Octopus - Cela résout plus de cas à deux têtes, mais refuse de faire une fusion complexe qui nécessite une résolution manuelle. Il est principalement destiné à être utilisé pour regrouper les têtes de branche de sujet. Il s'agit de la stratégie de fusion par défaut lors de l'extraction ou de la fusion de plusieurs branches.

  • nôtre - Cela résout un nombre illimité de têtes, mais le résultat de la fusion est toujours la tête de branche actuelle. Il est destiné à remplacer l'ancien historique de développement des branches latérales.

  • subtree - Il s'agit d'une stratégie récursive modifiée. Lors de la fusion des arbres A et B, si B correspond à un sous-arbre de A, B est d'abord ajusté pour correspondre à la structure arborescente de A, au lieu de lire les arbres au même niveau. Cet ajustement est également effectué sur l'arbre des ancêtres communs.

Quand dois-je spécifier quelque chose de différent de la valeur par défaut? Quels scénarios conviennent le mieux à chacun?

Otto
la source

Réponses:

305

Je ne connais pas la résolution, mais j'ai utilisé les autres:

Récursif

Récursif est la valeur par défaut pour les fusions à avance rapide. Nous connaissons tous celui-là.

Poulpe

J'ai utilisé le poulpe quand j'ai eu plusieurs arbres qui devaient être fusionnés. Vous voyez cela dans des projets plus importants où de nombreuses succursales ont eu un développement indépendant et tout est prêt à se réunir en une seule tête.

Une branche de poulpe fusionne plusieurs têtes en un seul commit tant qu'elle peut le faire proprement.

Par exemple, imaginez que vous avez un projet qui a un master, puis trois branches dans lesquelles fusionner (appelez-les a, b et c).

Une série de fusions récursives ressemblerait à ceci (notez que la première fusion était une avance rapide, car je n'ai pas forcé la récursivité):

série de fusions récursives

Cependant, une fusion de poulpe unique ressemblerait à ceci:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

fusion de poulpe

Les notres

Le nôtre == Je veux tirer dans une autre tête, mais jeter tous les changements que la tête introduit.

Cela conserve l'historique d'une branche sans aucun des effets de la branche.

(Lire: On ne regarde même pas les changements entre ces branches. Les branches sont juste fusionnées et rien n'est fait aux fichiers. Si vous voulez fusionner dans l'autre branche et à chaque fois il y a la question "notre version de fichier ou leur version "que vous pouvez utiliser git merge -X ours)

Sous-arbre

La sous-arborescence est utile lorsque vous souhaitez fusionner dans un autre projet dans un sous-répertoire de votre projet actuel. Utile lorsque vous avez une bibliothèque que vous ne souhaitez pas inclure comme sous-module.

Dustin
la source
1
Le seul véritable avantage d'Ocotopus est donc de réduire le nombre de validations de fusion dans l'arbre?
Otto
60
Vous n'avez pas besoin de spécifier la stratégie de fusion de poulpe : elle est utilisée automatiquement si vous fusionnez plus de deux branches ( git merge A B ...).
Jakub Narębski
Désolé d'être hors sujet, mais de quel outil avez-vous fait ces captures d'écran? Cela ressemble à une très belle / jolie visualisation de l'histoire de la branche ...
Bernd Haug
4
gitg pour ceux sur l'environnement linux.
Akash Agrawal
2
Cet indice avec -X oursest génial, m'a juste sauvé une heure de travail.
Michael
49

En fait, les deux seules stratégies que vous souhaitez choisir sont les nôtres si vous souhaitez abandonner les modifications apportées par la branche, mais conservez la branche dans l'historique et sous - arbre si vous fusionnez un projet indépendant dans le sous-répertoire du superprojet (comme `` git-gui '' dans '' référentiel git).

octopus merge est utilisé automatiquement lors de la fusion de plus de deux branches. La résolution est ici principalement pour des raisons historiques et lorsque vous êtes touché par des cas de coin de stratégie de fusion récursive .

Jakub Narębski
la source
J'ai dû choisir «résoudre» au lieu de «récursif» par défaut pour une fusion à deux têtes qui avait des erreurs fatales de git-write-tree. La stratégie «Resolve» a fusionné proprement. Cela peut avoir à voir avec le déplacement de nombreux fichiers dans la branche en cours de fusion.
thaddeusmt
@thaddeusmt: Intéressant. Pourriez-vous s'il vous plaît, si possible, publier un rapport de bogue sur cet échec de la stratégie de fusion "récursive" à git mailing list? Merci d'avance.
Jakub Narębski
@ JakubNarębski Je ne sais pas comment je réunirais suffisamment d'informations pour déposer un rapport de bogue significatif, je suis un n00b avec Git, désolé. Comme je l'ai mentionné dans ma réponse ici ( stackoverflow.com/a/10636464/164439 ), je suppose que cela avait à voir avec moi la duplication des modifications dans les deux branches, et "résoudre" fait un meilleur travail d'ignorer les modifications dupliquées.
thaddeusmt
@ JakubNarębski maintenant vous pouvez également choisir le leur , qui est selon le manuel "l'opposé du nôtre . Le leur n'est pas choisi automatiquement pour vous. Pouvez-vous mettre à jour légèrement votre réponse, en ajoutant l' option leur
SebNag
3
@SebTu: il n'y a pas de theirsstratégie de fusion (c'est-à-dire --strategy=theirs), mais il y a une theirsoption pour la recursivestratégie de fusion par défaut (c'est-à-dire --strategy=recursive --strategy-option=theirs, ou juste -Xtheirs).
Jakub Narębski
23

Stratégie de fusion "Resolve" vs "Recursive"

Récursif est la stratégie à deux têtes par défaut actuelle, mais après quelques recherches, j'ai finalement trouvé des informations sur la stratégie de fusion "résoudre".

Extrait du livre O'Reilly Version Control with Git ( Amazon ) (paraphrasé):

À l'origine, "résoudre" était la stratégie par défaut pour les fusions Git.

Dans les situations de fusion croisée, où il existe plusieurs bases de fusion possibles, la stratégie de résolution fonctionne comme suit: choisissez l'une des bases de fusion possibles et espérez le meilleur. Ce n'est en fait pas aussi mauvais qu'il y paraît. Il s'avère souvent que les utilisateurs ont travaillé sur différentes parties du code. Dans ce cas, Git détecte qu'il remémore certains changements déjà en place et ignore les modifications en double, évitant le conflit. Ou, s'il s'agit de légères modifications qui provoquent un conflit, au moins le conflit devrait être facile à gérer pour le développeur.

J'ai fusionné avec succès des arborescences en utilisant "résoudre" qui a échoué avec la stratégie récursive par défaut. J'obtenais des fatal: git write-tree failed to write a treeerreurs, et grâce à ce billet de blog ( miroir ), j'ai essayé "-s résoudre", qui a fonctionné. Je ne sais toujours pas exactement pourquoi ... mais je pense que c'est parce que j'ai eu des changements en double dans les deux arbres et que je les ai résolus "sautés" correctement.

thaddeusmt
la source
J'utilise la fusion à 3 voies (p4merge) et des conflits ont été écrits dans le fichier .BASE lorsque la fusion récursive a échoué. Se replier sur la stratégie de résolution a aidé dans ce cas.
mrzl
1
Ce lien de blog cité dans la réponse est maintenant rompu.
-2

Comme les réponses ci-dessus ne montrent pas tous les détails de la stratégie. Par exemple, une réponse ne contient pas les détails sur l'importation resolveoption et le recursivequi a de nombreuses options de sous comme ours, theirs, patience, renormalize, etc.

Par conséquent, je recommanderais de visiter la gitdocumentation officielle qui explique toutes les fonctionnalités possibles:

https://git-scm.com/docs/merge-strategies

René B.
la source