2009-11-18 4 views
3

Je teste juste git pour savoir si je pourrais l'utiliser pour mon travail. J'ai rencontré un problème qui semble petit mais qui pourrait devenir réel avec le vrai code. Mon fichier ressemble: text.txt J'ai une branche locale « Branch1 » et les changements dans les deux commises branche et maître. En master j'ai changé la première ligne de la branche la seconde. Ainsi, le diff pour le maître ressemble à ceci:Comment est-ce un conflit?

+1 master 
2 
3 
4 

Pour la branche est:

1 
-2 
+2b1 
3 
4 

Exécution de fusion git Branch1 résout dans un conflit:

<<<<<<< HEAD 
1 master 
2 
======= 
1 
2b1 
>>>>>>> branch1 
3 
4 

Je sais celui peut être résolu facilement. Mais comment est-ce un conflit, de toute façon. Ne devrait pas être capable de fusionner ceci?

+0

> Suggérez-vous que cela fonctionnerait correctement avec plus de lignes? Oui, il devrait le faire, si nous parlons de lignes * modifiées *, pas de nouvelles lignes ou de lignes supprimées (ce qui déplacerait le nombre de lignes, et ferait de l'absence de contexte un moyen sûr d'avoir un conflit à chaque fois). – VonC

+0

> Par ailleurs, j'ai essayé de rebaser -> même conflit. Si vous avez ajouté le paramètre '-C0' et que vous avez toujours un conflit, cela signifie que certaines lignes se chevauchent, que de nouvelles lignes ou des lignes supprimées existent en tant que différence. '-C0' ne fonctionne que si les mêmes lignes sont présentes, à l'exception de quelques unes (différentes dans chaque version) modifiées. – VonC

Répondre

4

Aucun contexte n'isole les deux modifications, ce qui ne permet pas de déterminer la résolution correcte. Avec une ligne de contexte, les changements sont: changer le bloc "1/2" en "1 maître/2" et changer le bloc "1/2/3" en "1/2b1/3".

Essayer d'appliquer le deuxième 'correctif' au résultat du premier correctif résout une erreur car le contexte nécessaire pour appliquer le correctif ne correspond pas. Le patch nécessite "1/2/3", mais a "1 master/2/3". Un contexte suffisant est important dans des scénarios plus complexes car sans lui, il serait facile de fusionner le patch au mauvais endroit sans avertissement si la branche locale avait suffisamment déplacé les lignes et la quantité minimale de contexte vérifiée au niveau du l'emplacement d'origine était suffisamment non spécifique pour que le patch s'applique quand il ne le devrait pas.

5

Couple de commentaires:

  • d'abord, un petit exemple ne serait jamais fusionné de toute façon:

    warning: Cannot merge binary files: afile.txt (HEAD vs. abranch)
  • alors, si vous avez beaucoup de « petits » conflits de fusion que vous connaissez devrait être résolu indépendamment du contexte, vous pouvez essayer de rebaser d'abord votre branche sur master, en ignorant le contexte:

    git rebase -C0 master

puis de fusionner votre branche en master.

Ceci est généralement pas une bonne idée d'ignorer tout le contexte pour un rebasage, mais si vous êtes certain vos modifications (comme dans « modifications ne nécessitant pas de contexte du tout »), cela fonctionnera.

De git rebase man page:

-C<n> 

Assurez-vous au moins <n> lignes entourant correspondance de contexte avant et après chaque modification.
Lorsque moins de lignes de contexte environnant existent, elles doivent toutes correspondre.
Par défaut, aucun contexte n'est jamais ignoré.


Vous pouvez tester assez facilement (ici dans une session PowerShell, avec Git1.6.5.1, sur Xp)

d'abord créer une petite chauve-souris utilitaire genfile.bat

echo hello, World %1 > afile.txt 
echo hello, World %2 >> afile.txt 
echo hello, World 3 >> afile.txt 
echo hello, World 4 >> afile.txt 
echo hello, World 5 >> afile.txt 

puis créez un dépôt et ajoutez un fichier:

PS D:\git\tests\mergeLines> git init m0 
PS D:\git\tests\mergeLines> cd m0 
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2 
PS D:\[...]\m0> git add -A 
PS D:\[...]\m0> git ci -m "afile to be modified concurrently" 

Votre fichier ressemble à ceci:

hello, World 1 
hello, World 2 
hello, World 3 
hello, World 4 
hello, World 5 

Modifier dans une branche

PS D:\[...]\m0> git co -b abranch 
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2_modified 
PS D:\[...]\m0> git ci -a -m "afile modified in abranch" 

Vous aurez:

hello, World 1 
hello, World 2_modified 
hello, World 3 
hello, World 4 
hello, World 5 

modifier ensuite dans maître

PS D:\[...]\m0> git co master 
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1_master 2 
PS D:\[...]\m0> git ci -a -m "afile modified in master" 

qui vous donne:

hello, World 1_master 
hello, World 2 
hello, World 3 
hello, World 4 
hello, World 5 

clone qui repo pour une première expérience (ex: une fusion de abranch en master)

PS D:\[...]\m0> cd .. 
PS D:\git\tests\mergeLines> git clone m0 m1 
PS D:\git\tests\mergeLines> cd m1 
PS D:\[...]\m1> git co -b abranch origin/abranch 
PS D:\[...]\m1> git co master 
PS D:\[...]\m1> git merge abranch 

Cela vous donne un conflit:

Auto-merging afile.txt 
CONFLICT (content): Merge conflict in afile.txt 
Automatic merge failed; fix conflicts and then commit the result. 

PS D:\[...]\m1> type afile.txt 
<<<<<<< HEAD 
hello, World 1_master 
hello, World 2 
======= 
hello, World 1 
hello, World 2_modified 
>>>>>>> abranch 
hello, World 3 
hello, World 4 
hello, World 5 

Clone le premier nouveau repo, cette fois pour rebaser d'abord abranch sur master, sans contexte:

PS D:\[...]\m1> cd .. 
PS D:\git\tests\mergeLines> git clone m0 m2 
PS D:\git\tests\mergeLines> cd m2 
PS D:\[...]\m2> git co -b abranch origin/abranch 
PS D:\[...]\m2> git rebase -C0 master 

Votre fichier est fusionné en silence:

hello, World 1_master 
hello, World 2_modified 
hello, World 3 
hello, World 4 
hello, World 5 

Bien sûr, si vous revenez à master et maintenant fusionner abranch, le résultat sera une fusion avance rapide.

PS D:\git\tests\mergeLines\m2> git co master 
Switched to branch 'master' 
PS D:\git\tests\mergeLines\m2> git merge abranch 
Updating c8f48b4..8bee1d2 
Fast forward 
afile.txt | 2 +- 
1 files changed, 1 insertions(+), 1 deletions(-) 
+0

Merci pour votre aide, jusqu'à présent. Je ne fais que commencer avec git et n'ai jusqu'à présent rien entendu du contexte. (Une recherche rapide ne l'a pas rendu plus clair) Quoi qu'il en soit, c'est un scénario auquel je suis régulièrement confronté, sauf avec plus de lignes de code. Suggérez-vous, cela fonctionnerait correctement avec plus de lignes? J'y ai réfléchi pendant un certain temps.Je pense que si Git est si supérieur cela devrait fonctionner. Par ailleurs, j'ai essayé de rebaser -> même conflit. – Benjamin