Git: Trouver l'ancêtre commun le plus récent de deux branches


844

Comment trouver l'ancêtre commun le plus récent de deux branches Git?


3
Définissez le plus récent: temps réel, nombre de validations, autre métrique?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

2
Pertinent (fusion croisée): stackoverflow.com/questions/26370185/…
jub0bs

1
@CiroSantilli 心 改造 中心 996ICU 六四 事件 c'est la même chose dans n'importe quelle métrique, n'est-ce pas?
YakovL

@YakovL Je crois que non à cause de la ramification et parce que vous pouvez définir des dates de validation arbitraires sur vos objets de validation: cette date elle-même n'est probablement pas ce que vous voulez.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
@CiroSantilli 新疆 改造 中心 996ICU 六四 事件 il me semble que cela ne peut être différent que si avant le dernier commit commun dans l'arborescence il y a un commit qui a un horodatage plus ancien. Pouvez-vous fournir un exemple moins trivial?
YakovL

Réponses:


1019

Vous recherchez git merge-base. Usage:

$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

85
Notez que cela trouve l'ancêtre commun le plus récent ... ce qui, je crois, est ce que le questionneur veut, donc +1. Juste pour le noter, au cas où quelqu'un viendrait ici en essayant de trouver le plus ancien ancêtre commun (comme je l'ai fait) - pour lequel, voir également: stackoverflow.com/questions/1527234/…
lindes

16
@funroll: Ou le raccourci pour cela:git log master...HEAD
CB Bailey

17
@lindes le plus ancien ancêtre commun ne serait-il pas le commit initial?
Thorbjørn Ravn Andersen

8
@ ThorbjørnRavnAndersen, oui, je suppose que c'est le cas ... La difficulté de description vient du fait que git utilise un graphe acyclique dirigé, et pourtant il est souvent considéré comme un arbre, ce qu'il n'est techniquement pas. Pour être plus prudent dans ma formulation, je parlais du cas où vous voulez que le parent de la première instance des "branches" divergent ... car ils peuvent avoir plusieurs points où ils ont fusionné et re-divisé, c'est le "plus ancien" d'entre eux, mais pas vraiment l'ancêtre le plus âgé, qui est (je pense) toujours le commit initial.
lindes

5
Bien que cette question concerne strictement la recherche d'un ancêtre commun de deux branches, toute personne souhaitant l'ancêtre commun de trois branches ou plus doit noter qu'elle doit passer le --octopusdrapeau pour obtenir le bon résultat. L'évident mais le faux git merge-base branch1 branch2 branch3vous donnera un commit, mais, comme décrit dans la section Discussion dans la documentation, ce n'est pas nécessairement un ancêtre commun des trois branches.
Mark Amery

46

git diff master...feature

affiche toutes les nouvelles validations de votre branche de fonctionnalité actuelle (éventuellement multi-validation).

man git-diff documents qui:

git diff A...B

est le même que:

git diff $(git merge-base A B) B

mais il ...est plus facile à taper et à mémoriser.

Comme mentionné par Dave , le cas particulier de HEADpeut être omis. Donc:

git diff master...HEAD

est le même que:

git diff master...

ce qui est suffisant si la branche courante l'est feature.

Enfin, n'oubliez pas que l'ordre est important! Faire git diff feature...masteraffichera les changements qui ne sont masterpas activés feature.

Je souhaite que plus de commandes git prennent en charge cette syntaxe, mais je ne pense pas qu'elles le fassent. Et certains ont même une sémantique différente pour ...: Quelles sont les différences entre les points doubles ".." et les points triple "..." dans les plages de validation Git?


8
Ou tout simplement git diff master...dans le cas particulier de la différenceHEAD
Dave

le "..." n'a pas fonctionné pour moi en PowerShell, drôle il a fonctionné dans la console git peut-être que le repo n'était pas complet, git diff $ (git merge-base AB) B l'a fait et puisque je suis un peu nouveau pour git J'étais un peu sceptique que cela puisse fusionner les branches :)
Moiz Ahmed

1
sensationnel. assez étonnant. et si la branche que vous voulez n'existe pas dans votre référentiel local parce que vous ne l'avez jamais vérifiée, vous pouvez simplement le fairegit diff origin/branchname...
Mark Ch

25

Comme indiqué dans une réponse précédente, git merge-base fonctionne:

$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

mais si myfeaturec'est la branche courante, comme cela est courant, vous pouvez utiliser use--fork-point :

$ git merge-base --fork-point develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2

Cet argument ne fonctionne que dans les versions suffisamment récentes de git. Malheureusement, cela ne fonctionne pas toujours, cependant, et on ne sait pas pourquoi. Veuillez vous référer aux limitations notées vers la fin de cette réponse .


Pour des informations complètes sur la validation, considérez:

$ git log -1 $(git merge-base --fork-point develop) 

Je l'ai git version 2.14.1.windows.1. L'exécution git merge-base --fork-point branch2avec une branche (avec ses propres validations) que je sais avoir bifurquée à partir de la branche actuelle ne donne aucun résultat, alors qu'elle git merge-base branch1 branch2montre correctement le point de bifurcation. Quel pourrait être le problème?
2017 ADTC

@ADTC Checkout branch2, puis exécutez git merge-base --fork-point branch1.
Acumenus

@ADTC Utilisez une visionneuse de validation graphique, par exemple gitk, etc. pour voir à quoi ressemble l'arborescence. Vous obtiendrez peut-être votre réponse.
Acumenus

Je ne vois rien d'étrange à propos de l'arbre tel que je le vois graphiquement. Je peux tracer les chemins et trouver l'ancêtre commun qui correspond au résultat de git merge-base branch1 branch2. Mais ce qui est étrange, c'est que cela --fork-pointne donne rien de toute façon. Avez-vous confirmé que cela fonctionne pour vous comme prévu?
2017 ADTC

1
J'obtiens le même que @ADTC. La commande 'git log -1 $ (git merge-base --fork-point anotherBranch)' n'affiche aucun résultat en utilisant git version 2.16.2.windows.1.
masinger

10

Avec gitkvous pouvez visualiser graphiquement les deux branches:

gitk branch1 branch2

Et puis il est facile de retrouver l'ancêtre commun dans l'histoire des deux branches.


6
Tout ne peut pas être fait visuellement dans tous les cas. Il y a des raisons pour lesquelles les choses doivent être automatisées par programme.
2017 ADTC
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.