web-dev-qa-db-fra.com

Quelle est la signification précise de "notre" et de "leur" dans git?

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?

218
CommaToast

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"!

265
torek

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 et git 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 forme ours (c'est-à-dire "notre histoire canonique partagée"), tandis que ce que vous avez fait de votre branche latérale sous la forme theirs (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 et git 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/ou git pull.


Donc parfois cela peut être déroutant, par exemple:

  • git pull Origin master-Xours est notre section locale, -Xtheirs est leur branche (distante)
  • git pull Origin master -r-Xours est le leur (distant), -Xtheirs est le nôtre

Le 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).

33
kenorb

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:

Fusions:

$ 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

Rebases:

$ 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)

17
Nitay
  • Ours: C'est la branche sur laquelle vous vous trouvez actuellement.
  • Theirs: c'est l'autre branche utilisée dans votre action.

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:

  1. Tous les commits que vous avez effectués depuis votre dernier tirage sont déplacés vers une branche distincte, appelons-le BranchX.
  2. Vous récupérez la tête de votre branche actuelle, en éliminant tout fichier local modifications que vous aviez mais de cette façon, récupérer toutes les modifications que d'autres ont poussées pour cette branche.
  3. Désormais, chaque commit sur BranchX est sélectionné en fonction de l’ancien à l’ancien dans votre branche actuelle.
  4. BranchX est à nouveau supprimé et n'apparaîtra donc jamais dans l'historique.

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".

1
Mecki

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

0
Joshua Ryan