J'ai récemment appris que lors de la fusion de deux branches dans git, s'il y a des changements sur deux lignes adjacentes , git déclare que c'est un conflit. Par exemple, si le fichier test.txt
a ce contenu:
Line 1: A
Line 2: B
Line 3: C
Line 4: D
et en branche master
nous changeons cela en
Line 1: A
Line 2: B1
Line 3: C
Line 4: D
tandis que dans la branche, testing
nous changeons cela en
Line 1: A
Line 2: B
Line 3: C1
Line 4: D
et ensuite tenter de fusionner testing
dans master
, git déclare un conflit de fusion. Mon attente naïve était que la fusion se ferait sans conflit et produirait ceci:
Line 1: A
Line 2: B1
Line 3: C1
Line 4: D
Je suis sûr qu'il y a une bonne raison pour laquelle git ne fusionne pas de cette façon. Quelqu'un peut-il expliquer cette raison?
Réponses:
En supposant que cet extrait de code
a été changé dans une branche dans ce
et dans une autre branche dans ce
alors je ne voudrais pas que git le fusionne dans ce
sans me alarmer.
Afin d'éviter de causer de tels problèmes, git refuse généralement de fusionner automatiquement les modifications touchant les lignes voisines. Il vous donne une chance de vérifier si la logique du programme serait cassée ou non.
Cet exemple est trivial, mais lors de la fusion d'énormes branches, le risque de conflits "logiques" similaires est beaucoup plus grand. Parfois, j'aimerais même que le contexte soit encore plus grand qu'il ne l'est actuellement.
la source
Ce comportement est-il réservé aux git?
Après discussion avec un collègue, je viens d'essayer, et SVN le gère sans problème: vous obtenez les 2 lignes modifiées.
Les capacités de fusion de plusieurs VCS sont testées ici pour bazaar, darcs, git et mercurial : https://github.com/mndrix/merge-this
Il semble que seuls les darcs fusionnent avec succès le cas des "lignes adjacentes".
L'application de modifications adjacentes à des fichiers n'est pas un problème difficile. Je pense vraiment que ce comportement a été choisi exprès.
Pourquoi quelqu'un déciderait-il que la modification de lignes adjacentes produit un conflit?
Je pense que c'est pour vous forcer à le regarder .
Modif numéro 1, sur maître:
Modif numéro 2, fusionné à partir d'une branche:
Après la fusion, vous ne voulez pas que:
Voir ce comportement comme une fonctionnalité
Vous pouvez transformer le comportement de fusion git en avantage. Lorsque vous devez conserver 2 lignes cohérentes mais que vous ne pouvez pas les détecter (au moment de la compilation, au début de vos tests ou autre), vous pouvez essayer de les joindre.
Réécrivez ceci ...:
...pour ça:
Donc, lorsque vous fusionnez Modif 1 ...:
... avec Modif 2 ...:
..., git produira un conflit, et vous vous forcerez à le regarder.
la source
Je devine principalement, mais je pense que cela a à voir avec la ligne 2 utilisée comme contexte pour le changement de ligne 3.
Git ne peut pas simplement dire que "La ligne avec C est devenue une ligne avec C1" car il pourrait y avoir une autre ligne avec "C", donc il dit "La ligne avec C, c'est juste après le début du fichier, la ligne avec A, et la ligne avec B, est maintenant C1 "
Si "la ligne avec B" n'est plus là, alors une partie du contexte est perdue, et git ne peut que dire approximativement où la nouvelle ligne doit aller.
la source
Les autres réponses ici sont toutes pertinentes, mais pour moi, cela m'a toujours semblé une limitation inutile.
Comme d'autres l'ont dit, dans ces cas, vous ne voudriez certainement pas que Git fusionne les lignes sans avertissement.
Mais je voulais toujours l'option de le faire automatiquement, après avoir été averti. J'ai donc écrit un pilote de fusion git personnalisé qui pourrait fusionner les conflits sur les lignes adjacentes (ou individuelles) de manière interactive:
Cela me fait gagner beaucoup de temps, car je gère un projet où les gens travaillent souvent sur les mêmes fichiers et refactorisent beaucoup de code.
Le script est disponible sur GitHub sous une licence GPLv3 +. Vous le trouverez peut-être utile:
https://github.com/paulaltin/git-subline-merge
la source