Quelle est la signification précise de "nôtre" et "leur" dans git?
Cela peut sembler trop basique d'une question, mais j'ai cherché des réponses et je suis plus confus maintenant qu'avant.
Que signifient" nôtre "et" leur " dans git lors de la fusion de ma branche dans mon autre branche? Les deux branches sont "les nôtres".
Dans un conflit de fusion est" nôtre " toujours la partie supérieure des deux versions affichées?
Est-ce que "nôtre" fait toujours référence à la branche que HEAD pointait quand la fusion a commencé? Si oui alors pourquoi ne pas utiliser une référence possessive claire comme "branche actuelle" au lieu d'utiliser un pronom possessif comme "nôtre" qui est référentiellement ambigu (puisque les deux branches sont techniquement les nôtres)?
Ou utilisez simplement le nom de la branche(au lieu de dire "nôtre", dites simplement "local master" ou tel)?
La partie la plus confuse pour moi est si je spécifie dans une branche spécifique .fichier gitattributes. Disons dans branche de test j'ai ce qui suit .fichier gitattributes:
config.xml merge=ours
Maintenant, je commande et pointe vers master puis fusionnez dans test . Depuis maître est la nôtre, et test's .gitattributes n'est pas extrait, aura-t-il même un effet? Si cela a un effet, puisque maître est maintenant "le nôtre", alors que se passera-t-il?
4 réponses
Je soupçonne que vous êtes confus ici parce que c'est fondamentalement confus. Pour aggraver les choses, tout le nôtre / le leur change de rôle (devient en arrière) lorsque vous faites un rebase.
En fin de compte, pendant un git merge
, la branche "nôtre" 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, "le nôtre" et "le leur" ont du sens, car même si" le leur " est probablement le vôtre de toute façon, "le leur" n'est pas celui que vous étiez sur quand vous avez couru git merge
.
Bien que l'utilisation du nom de la branche réelle puisse être assez cool, elle s'effondre dans des cas plus complexes. Par exemple, au lieu de ce qui précède, vous pouvez faire:
git checkout ours
git merge 1234567
Où vous fusionnez par commit-ID brut. Pire, vous pouvez même faire ceci:
git checkout 7777777 # detach HEAD
git merge 1234567 # do a test merge
Auquel cas il n'y a pas de noms de branche impliqués!
Je pense que c'est peu d'aide ici, mais en fait, dans gitrevisions
la syntaxe, 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
Stage # 1 est l'ancêtre commun des fichiers, stage # 2 est la version de la branche cible et stage # 3 est la version à partir de laquelle vous fusionnez.
La raison pour laquelle les notions "nôtre" et "leur" sont échangées pendant rebase
est que rebase fonctionne en faisant une série de pics de cerise, dans une branche anonyme (mode tête détachée). La branche cible est la branche anonyme, et le merge-from branch est votre branche d'origine (pré-rebase): donc "--ours" signifie l'anonyme rebase est en train de construire tandis que "--leur" signifie "notre branche en cours de rebasation".
Quant à l'entrée gitattributes: elle pourrait avoir un effet: "nôtre" signifie vraiment "utiliser l'étape #2" en interne. Mais comme vous le remarquez, il n'est pas réellement en place à l'époque, donc il ne devrait pas avoir un effet ici ... Eh bien, pas à moins que vous le copiez dans l'arbre de travail avant de commencer.
Aussi, par en passant, cela s'applique à toutes les utilisations de la nôtre et de la leur, mais certaines sont au niveau du fichier entier (-s ours
pour une stratégie de fusion; git checkout --ours
pendant un conflit de fusion) et certaines sont pièce par pièce (-X ours
ou -X theirs
lors d'une fusion -s recursive
). Ce qui n'aide probablement pas à la confusion.
Je n'ai jamais trouvé un meilleur nom pour ceux-ci, cependant. Et: voir la réponse de VonC à une autre question, Où git mergetool
introduit encore plus de noms pour ceux-ci, les appelant "local" et "télécommande"!
Le' nôtre ' dans Git fait référence à la branche de travail originale qui a une partie autoritaire/canonique de l'histoire de git.
Le 'leur ' fait référence à la version qui contient le travail afin d'être rebasé (modifications à rejouer sur la branche en cours).
Cela peut sembler être échangé à des personnes qui ne savent pas que faire un rebasage (par exemple git rebase
) met réellement votre travail en attente (qui est Le leur ) afin de rejouer sur l'histoire canonique / principale qui est la nôtre , parce que nous rebasons nos changements en tant que travail tiers.
La documentation de git-checkout
a été clarifiée dans Git > = 2.5.1 selon f303016
commit :
--ours
--theirs
Lors de la vérification des chemins de l'index, consultez l'étape #2 ('nôtre') ou # 3 ('Leur') pour les chemins non fusionnés.
Notez que pendant
git rebase
etgit pull --rebase
, 'nôtre' et 'leur' peuvent apparaître échangés;--ours
donne le version de la branche les modifications sont rebasées sur, tandis que--theirs
donne la version de la branche qui contient votre travail qui est rebasé.C'est parce que
rebase
est utilisé dans un flux de travail qui traite l'historique de la télécommande comme le canonique partagé, et traite le travail effectué sur la branche que vous rebasez comme le travail tiers à intégrer, et vous assumez temporairement le rôle de gardien de l'historique canonique pendant le rebasage. Comme le gardien de la historique canonique, vous devez afficher l'historique de la télécommande commeours
(c'est-à-dire "notre historique canonique partagé"), tandis que ce que vous avez fait de votre côté se branche commetheirs
(c'est-à-dire "le travail d'un contributeur sur le dessus").
Pour git-merge
c'est expliquer de la manière suivante:
Le Nôtre
Cette option force les parties en conflit à être auto-résolues proprement en favorisant notre version. Les changements de l'autre arbre qui ne sont pas en conflit avec notre côté sont reflète 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 la stratégie de fusion nôtre, qui ne regarde même pas ce que l'autre arbre contient du tout. Il rejette tout ce que l'autre arbre a fait, déclarant que notre histoire contient tout ce qui s'y est passé.
Leur
C'est l'opposé de la nôtre.
En outre plus, ici est expliqué comment utiliser les:
Le mécanisme de fusion (commandes
git merge
etgit pull
) permet de choisir les stratégies de fusion backend avec l'option-s
. Certaines stratégies peuvent également prendre leurs propres options, qui peuvent être passés en donnant-X<option>
argumentsgit merge
et/ougit pull
.
Donc parfois cela peut être déroutant, par exemple:
-
git pull origin master
où-Xours
est notre local,-Xtheirs
est leur branche (distante) -
git pull origin master -r
où-Xours
est le leur (distant),-Xtheirs
est le nôtre
Donc le 2ème exemple est opposé au 1er, parce que nous rebasons notre branche au-dessus de la branche distante, donc notre point de départ est distant, et nos modifications sont traitées comme externes.
Similaire pour les stratégies git merge
(-X ours
et -X theirs
).
Je sais que cela a été répondu, mais ce problème m'a confus tant de fois que j'ai mis en place un petit site de référence pour m'aider à me souvenir: https://nitaym.github.io/ourstheirs/
Voici les bases:
Fusionne:
$ git checkout master
$ git merge feature
Si vous voulez sélectionner la version dans master
:
$ git checkout --ours codefile.js
Si vous voulez sélectionner la version dans feature
:
$ git checkout --theirs codefile.js
Rebases:
$ git checkout feature
$ git rebase master
Si vous voulez sélectionner la version dans master
:
$ git checkout --ours codefile.js
Si vous voulez sélectionnez la version dans feature
:
$ git checkout --theirs codefile.js
(Ceci est pour les fichiers complets, bien sûr)
- nôtre : c'est la branche sur laquelle vous êtes actuellement.
- Leur: C'est l'autre branche qui est utilisé dans votre action.
Donc, si vous êtes sur la branche presse/2.5 et de la fusion de la branche fonctionnalité/nouvelle-boutons, alors le contenu trouvé dans presse/2.5 est-ce que nôtre désigne et le contenu que l'on trouve sur fonctionnalité/nouvelle-boutons est-ce que leur désigne. Lors d'une action de fusion c'est joli tout droit vers l'avant.
Le seul problème pour lequel la plupart des gens tombent est le cas de rebase . Si vous effectuez une re-base au lieu d'une fusion normale, les rôles sont échangés. Comment est-ce? Eh bien, cela est causé uniquement par la façon dont le rebasage fonctionne. Pensez à rebase pour travailler comme ça:
- Tous les commits que vous avez effectués depuis votre dernier tirage sont déplacés vers une branche de leur propre, nommons-le BranchX .
- vous checkout la tête de votre branche actuelle, en rejetant tout local les modifications que vous avait mais de cette façon récupérer tous les changements d'autres ont poussé pour cette branche.
- Maintenant, chaque commit sur BranchX est sélectionné dans l'ordre ancien à nouveau dans votre branche actuelle.
- BranchX {[3] } est supprimé à nouveau et n'apparaîtra donc jamais dans aucun historique.
Bien sûr, ce n'est pas vraiment ce qui se passe, mais c'est un bon modèle d'esprit pour moi. Et si vous regardez 2 et 3, vous comprendrez pourquoi les rôles sont échangés maintenant. À partir de 2, votre branche actuelle est maintenant la branche du serveur sans aucune de vos modifications, donc c'est Le Nôtre (la branche sur laquelle vous êtes). Les modifications que vous avez apportées sont maintenant sur une autre branche qui n'est pas celui (BranchX) et donc ces changements (malgré les modifications que vous avez effectuées) sont leur (l'autre branche utilisés dans votre action).
Cela signifie que si vous fusionnez et que vous voulez que vos modifications gagnent toujours, vous direz à git de toujours choisir "nôtre" mais si vous rebasez et que vous voulez que toutes vos modifications soient toujours gagnez, vous dites à git de toujours choisir "le leur".