Cela peut sembler une question trop fondamentale, mais j’ai cherché des réponses et je suis plus confus qu’auparavant.
Que signifient "les nôtres" et "les leurs" lors de la fusion de ma branche dans mon autre branche? Les deux branches sont "les nôtres".
Dans un conflit de fusion est "notre" toujours la partie supérieure des deux versions affichées?
Le terme "notre" fait-il toujours référence à la branche que HEAD désignait au début de la fusion? Si c'est le cas, pourquoi ne pas utiliser une référence possessive claire telle que "branche actuelle" au lieu d'utiliser un pronom possessif tel que "nôtre" qui est référentiellement ambigu (puisque les deux branches sont techniquement les nôtres)?
Ou utilisez-vous simplement le nom de la succursale (au lieu de dire "notre", dites simplement "maître local" ou autre)?
La partie la plus déroutante pour moi est si je spécifie dans le fichier .gitattributes d'une branche spécifique. Disons dans branche test J'ai le fichier .gitattributes suivant:
config.xml merge=ours
Maintenant, je vérifie et pointe HEAD sur master puis fusionne dans test . Puisque master est le nôtre, et que les .gitattributes de test ne sont pas extraits, cela aura-t-il un effet? Si cela a un effet, puisque master est maintenant "à nous", que va-t-il se passer?
Je suppose que vous êtes confus ici parce que c'est fondamentalement déroutant. Pour aggraver les choses, l’ensemble de nos affaires change de rôle (devient à l’arrière) lorsque vous effectuez une refonte.
En fin de compte, pendant un git merge
, la branche "notre" fait référence à la branche que vous fusionnez dans:
git checkout merge-into-ours
et la branche "leur" fait référence à la branche (unique) que vous fusionnez:
git merge from-theirs
et ici "nos" et "leurs" ont un sens, car même si "leurs" est probablement le vôtre de toute façon, "leur" n'est pas celui que vous étiez sur lorsque vous exécutiez git merge
.
Bien que l’utilisation du nom de la branche réelle puisse être assez cool, elle s’efface dans des cas plus complexes. Par exemple, au lieu de ce qui précède, vous pourriez faire:
git checkout ours
git merge 1234567
où vous fusionnez par un commit-ID brut. Pire, vous pouvez même faire ceci:
git checkout 7777777 # detach HEAD
git merge 1234567 # do a test merge
auquel cas no noms de branches sont impliqués!
Je pense que cela aide peu ici, mais en fait, dans gitrevisions
syntax , vous pouvez faire référence à un chemin individuel dans l'index par numéro, lors d'une fusion en conflit
git show :1:README
git show :2:README
git show :3:README
L'étape 1 correspond à l'ancêtre commun des fichiers, l'étape 2 correspond à la version de la branche cible et l'étape 3 à la version à partir de laquelle vous fusionnez.
La raison pour laquelle les notions "nos" et "leurs" ont été échangées pendant rebase
est que rebase fonctionne en effectuant une série de sélections, dans une branche anonyme (mode détaché HEAD). La branche cible est la branche anonyme, et la branche issue de la fusion est votre branche d'origine (avant la création de la base): "--ours" signifie donc la base anonyme créée, tandis que "- leurs" signifie "notre branche en cours de refonte". .
Quant à l’entrée gitattributes: elle pourrait avoir un effet: "notre" signifie en réalité "utilise le stade n ° 2" en interne. Mais comme vous le constatez, il n’est pas réellement en place à ce moment-là, donc ne devrait pas avoir d’effet ici ... eh bien, à moins que vous ne le copiez dans l’arbre de travail avant de commencer.
En outre, cela s’applique également à toutes les utilisations des nôtres et des leurs, mais certaines s’appliquent au niveau du fichier entier (-s ours
pour une stratégie de fusion; git checkout --ours
lors d’un conflit de fusion) et certaines au cas par cas (-X ours
ou -X theirs
pendant une fusion -s recursive
). Ce qui n'aide probablement pas dans la confusion.
Je n'ai jamais trouvé un meilleur nom pour ceux-ci, cependant. Et: voir Réponse de VonC à une autre question, où git mergetool
introduit encore plus de noms pour ceux-ci, les appelant "local" et "distant"!
Le 'ours' dans Git fait référence à la branche de travail originale qui a une partie faisant autorité/canonique de l'histoire de Git.
Le 'leurs' fait référence à la version qui contient le travail afin d'être rebasé (les modifications à relire sur la branche courante).
Cela peut sembler être interverti aux personnes qui ne sont pas conscientes du fait que le rebasage (par exemple, git rebase
) met votre travail en attente (ce qui est leur) afin de rejouer sur l'historique canonique/principal qui est la nôtre} _, car nous modifions nos modifications en tant que travail tiers.
La documentation de git-checkout
a été clarifiée dans Git> = 2.5.1 conformément à f303016
commit :
--ours
--theirs
Lorsque vous extrayez des chemins à partir de l'index, passez à l'étape n ° 2 ("notre") ou n ° 3 ("le leur") pour les chemins non fusionnés.
Notez que pendant
git rebase
etgit pull --rebase
, 'le nôtre' et le 'leur' peuvent apparaître échangés;--ours
donne la version de la branche sur laquelle les modifications sont redéfinies, alors que--theirs
donne la version de la branche contenant votre travail en cours de refonte.Ceci est dû au fait que
rebase
est utilisé dans un flux de travail qui traite l'historique de la télécommande comme étant celui canonique partagé, ainsi que le travail effectué sur la branche que vous rebasonnez en tant que travail tiers à intégrer, et que vous assumez temporairement le rôle. du détenteur de l'histoire canonique lors de la rebase. En tant que gardien de l'histoire canonique, vous devez afficher l'historique depuis la télécommande sous la formeours
(c'est-à-dire "notre histoire canonique partagée"), tandis que ce que vous avez fait de votre branche latérale sous la formetheirs
(c'est-à-dire "le travail d'un contributeur par-dessus"). ).
Pour git-merge
c'est expliquer de la manière suivante:
les notres
Cette option oblige les mecs en conflit à se résoudre eux-mêmes automatiquement en privilégiant notre version. Les modifications de l’autre arbre qui n’entrent pas en conflit avec notre côté se reflètent dans le résultat de la fusion. Pour un fichier binaire, tout le contenu est pris de notre côté.
Cela ne doit pas être confondu avec notre stratégie de fusion, qui ne regarde même pas ce que l’autre arbre contient. Il rejette tout ce que l’autre arbre a fait, déclarant que notre histoire contient tout ce qui s’y est passé.
les leurs
C'est l'opposé du nôtre.
De plus, voici comment les utiliser:
Le mécanisme de fusion (commandes
git merge
etgit pull
) permet de choisir les stratégies de fusion d’arrière-plan avec l’option-s
. Certaines stratégies peuvent également prendre leurs propres options, qui peuvent être passées en donnant des arguments-X<option>
àgit merge
et/ougit pull
.
Donc parfois cela peut être déroutant, par exemple:
git pull Origin master
où -Xours
est notre section locale, -Xtheirs
est leur branche (distante)git pull Origin master -r
où -Xours
est le leur (distant), -Xtheirs
est le nôtreLe deuxième exemple est donc opposé au premier parce que nous modifions notre branche par rapport à celle distante. Notre point de départ est donc distant et nos modifications sont traitées comme des modifications externes.
Similaire pour les stratégies git merge
(-X ours
et -X theirs
).
Je sais que cette question a été résolue, mais cette question m'a confondue si souvent que j'ai créé un petit site Web de référence pour m'aider à me rappeler: https://nitaym.github.io/ourstheirs/
Voici les bases:
$ git checkout master
$ git merge feature
Si vous souhaitez sélectionner la version dans master
:
$ git checkout --ours codefile.js
Si vous souhaitez sélectionner la version dans feature
:
$ git checkout --theirs codefile.js
$ git checkout feature
$ git rebase master
Si vous souhaitez sélectionner la version dans master
:
$ git checkout --ours codefile.js
Si vous souhaitez sélectionner la version dans feature
:
$ git checkout --theirs codefile.js
(Ceci est pour les fichiers complets, bien sûr)
Donc, si vous êtes sur la branche release/2.5 et que vous y fusionnez une branche feature/new-buttons, alors le contenu tel que trouvé dans release/2.5 est ce à quoi se réfère our to et le contenu tel que trouvé sur feature/new-buttons est ce à quoi leur se réfère. Au cours d'une action de fusion, c'est assez simple.
Le seul problème que la plupart des gens craignent est le cas de rebase . Si vous effectuez une nouvelle base au lieu d'une fusion normale, les rôles sont échangés. Comment ça Eh bien, cela est uniquement dû à la façon dont le rebasement fonctionne. Pensez à rebase pour travailler comme ça:
Bien sûr, ce n’est pas vraiment ce qui se passe, mais c’est un modèle de Nice mental. Et si vous regardez 2 et 3, vous comprendrez pourquoi les rôles sont maintenant échangés. À partir de 2, votre branche actuelle est maintenant la branche du serveur sans aucune de vos modifications. Il s'agit donc de our (la branche sur laquelle vous vous trouvez). Les modifications que vous avez apportées sont maintenant sur une branche différente de celle que vous utilisez actuellement (BranchX). Par conséquent, ces modifications (même si vous les avez apportées) sont leurss (l'autre branche utilisée dans votre action). .
Cela signifie que si vous fusionnez et que vous voulez que vos modifications gagnent toujours, vous diriez à git de toujours choisir "la nôtre", mais si vous modifiez vos revenus et que vous voulez que toutes vos modifications gagnent toujours, vous dites à git de toujours choisir "leurs".
De l'utilisation de git checkout
:
-2, --ours checkout our version for unmerged files
-3, --theirs checkout their version for unmerged files
-m, --merge perform a 3-way merge with the new branch
Lors de la résolution des conflits de fusion, vous pouvez utiliser git checkout --theirs some_file
et git checkout --ours some_file
pour rétablir le fichier à la version actuelle et aux versions entrantes, respectivement.
Si vous avez déjà utilisé git checkout --ours some_file
ou git checkout --theirs some_file
et souhaitez réinitialiser le fichier avec la version de fusion à 3 voies du fichier, vous pouvez effectuer git checkout --merge some_file
.