How to find the most recent common ancestor of two Git branches?
-
3Define most recent: real world time, number of commits, other metric? – Ciro Santilli OurBigBook.com Jul 17 '14 at 20:51
-
2Relevant (criss-cross merges): http://stackoverflow.com/questions/26370185/how-do-criss-cross-merges-arise-in-git – jub0bs Dec 26 '14 at 12:21
-
@YakovL I believe no because of branching and because you can set arbitrary commit dates on your commit objects: that date itself is likely not what you want. – Ciro Santilli OurBigBook.com May 19 '19 at 13:06
-
2@CiroSantilli新疆改造中心996ICU六四事件 it seems to me that can only be different if before the last common commit in the tree there's a commit that has an older timestamp. Can you provide a less trivial example? – YakovL May 19 '19 at 16:14
6 Answers
You are looking for git merge-base
. Usage:
$ git merge-base branch2 branch3
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2
-
113Note that this finds the most recent common ancestor... which I believe is what the questioner wants, so +1. Just noting it, in case anyone comes here trying to find the *oldest* common ancestor (as I did) -- for which, see also: http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git – lindes Feb 14 '11 at 09:52
-
4This is probably what he was looking for, but the man page does not guarantee it will be the most recent neither in real time or number of commits: only that it will be one of the best common ancestors. – Ciro Santilli OurBigBook.com Jul 17 '14 at 20:53
-
2I think I'll be using this little snippet a lot: `$(git merge-base HEAD master)`. For example, `git log $(git merge-base HEAD master)..HEAD` – funroll Sep 08 '14 at 15:48
-
21
-
29@lindes would the oldest common ancestor not be the initial commit? – Thorbjørn Ravn Andersen Feb 19 '15 at 18:17
-
11@ThorbjørnRavnAndersen, yes, I suppose that's so... The difficulty in description comes with the fact that git uses a Directed Acyclic Graph, and yet it's often thought of as a tree, which it technically is not. To be more careful in my wording, I was talking about the case where you want the parent of the first instance of the "branches" diverging... since they may have multiple points where they re-merged and re-split, this is the "oldest" of these, but not truly the oldest ancestor, which is (I think) always the initial commit. – lindes Feb 23 '15 at 04:57
-
14While this question is strictly about finding a common ancestor of *two* branches, anyone wanting the common ancestor of *three* or more branches should note that they need to pass the `--octopus` flag to get the right result. The obvious-but-wrong `git merge-base branch1 branch2 branch3` will give you a commit, but, as described in the Discussion section in the docs, it *isn't* necessarily a common ancestor of all three branches. – Mark Amery Sep 10 '16 at 17:51
-
FYI Run `git log -1 commitHash` to get further information about the commit, for example the commit message. – Kevin Katzke Nov 14 '22 at 23:28
git diff master...feature
shows all the new commits of your current (possibly multi-commit) feature branch.
man git-diff
documents that:
git diff A...B
is the same as:
git diff $(git merge-base A B) B
but the ...
is easier to type and remember.
As mentioned by Dave, the special case of HEAD
can be omitted. So:
git diff master...HEAD
is the same as:
git diff master...
which is enough if the current branch is feature
.
Finally, remember that order matters! Doing git diff feature...master
will show changes that are on master
not on feature
.
I wish more git commands would support that syntax, but I don't think they do. And some even have different semantics for ...
: What are the differences between double-dot ".." and triple-dot "..." in Git commit ranges?

- 347,512
- 102
- 1,199
- 985
-
9
-
the "..." didn't work for me in powershell, funny it worked in git console maybe the repo wasn't complete, git diff $(git merge-base A B) B did and since I am a bit new to git I was a bit sceptical that this might merge the branches :) – Moiz Ahmed Nov 13 '18 at 22:22
-
1wow. quite amazing. and if the branch you want doesn't exist in your local repo because you never checked it out, you can simply do `git diff origin/branchname...` – Mark Ch Feb 04 '20 at 10:24
-
2so what is the difference between `git diff branchA..branchB` and `git diff branchA...branchB` ? – Bharat Pahalwani Feb 10 '21 at 14:26
As noted in a prior answer, although git merge-base
works,
$ git merge-base myfeature develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2
If myfeature
is the current branch, as is common, you can use --fork-point
:
$ git merge-base --fork-point develop
050dc022f3a65bdc78d97e2b1ac9b595a924c3f2
This argument works only in sufficiently recent versions of git. Unfortunately it doesn't always work, however, and it is not clear why. Please refer to the limitations noted toward the end of this answer.
For full commit info, consider:
$ git log -1 $(git merge-base --fork-point develop)

- 57,944
- 17
- 167
- 143
-
1I have `git version 2.14.1.windows.1`. Running `git merge-base --fork-point branch2` with a branch _(with its own commits)_ that **I know** has forked from the current branch doesn't yield any result, whereas `git merge-base branch1 branch2` correctly shows the fork point. What could be the problem? – ADTC Oct 21 '17 at 00:22
-
@ADTC Checkout `branch2` and then run `git merge-base --fork-point branch1`. – Asclepius Oct 21 '17 at 01:58
-
@ADTC Use a graphical commit viewer, e.g. `gitk`, etc. to see what the tree looks like. Maybe you will get your answer. – Asclepius Oct 21 '17 at 03:19
-
I see nothing odd about the tree as I view it graphically. I can trace the paths and find the common ancestor which matches the result of `git merge-base branch1 branch2`. But what's odd is that `--fork-point` gives nothing either way. Have you confirmed it works for you as intended? – ADTC Oct 21 '17 at 06:26
-
@ADTC I now tried it with git 2.14.1 on Linux and it works fine for me. I don't know what to tell you. – Asclepius Oct 21 '17 at 15:50
-
@ADTC If you don't believe that `--fork-point` works in general, try testing it in a new test repo with just a couple of commits. It should work. – Asclepius Oct 21 '17 at 22:18
-
1I get the same that @ADTC. The command 'git log -1 $(git merge-base --fork-point anotherBranch)' doesn't show any result using git version 2.16.2.windows.1. – masinger Mar 26 '18 at 18:25
-
@masinger I've now updated my answer to note the limitation. FWIW, please refer to the caveats noted toward the end of [this answer](https://stackoverflow.com/a/20966716/832230). – Asclepius Mar 26 '18 at 21:11
-
I second that `--fork-point` often fails, especially with `gh pr checkout` and `git-pr` tools. – stason Jan 07 '21 at 03:59
With gitk
you can view the two branches graphically:
gitk branch1 branch2
And then it's easy to find the common ancestor in the history of the two branches.

- 17,357
- 9
- 82
- 98
-
12Not everything can be done visually in every case. There are reasons why things may need to be automated programmatically. – ADTC Oct 21 '17 at 00:21
-
2
-
3
git checkout myRep
git pull origin main --allow-unrelated-histories
git push origin myRep
find common ancestor of ALL branches
git merge-base $(git branch --format "%(refname)")

- 2,447
- 1
- 18
- 25