I have a repository with branches master and A and lots of merge activity between the two. How can I find the commit in my repository when branch A was created based on master?
My repository basically looks like this:
-- X -- A -- B -- C -- D -- F (master)
\ / \ /
\ / \ /
G -- H -- I -- J (branch A)
I'm looking for revision A, which is not what git merge-base (--all)
finds.
If you like terse commands,
Here's an explanation.
The following command gives you the list of all commits in master that occurred after branch_name was created
Since you only care about the earliest of those commits you want the last line of the output:
The parent of the earliest commit that's not an ancestor of "branch_name" is, by definition, in "branch_name," and is in "master" since it's an ancestor of something in "master." So you've got the earliest commit that's in both branches.
The command
is just a way to show the parent commit reference. You could use
or whatever.
PS: I disagree with the argument that ancestor order is irrelevant. It depends on what you want. For example, in this case
it makes perfect sense to output C2 as the "branching" commit. This is when the developer branched out from "master." When he branched, branch "B" wasn't even merged in his branch! This is what the solution in this post gives.
If what you want is the last commit C such that all paths from origin to the last commit on branch "A" go through C, then you want to ignore ancestry order. That's purely topological and gives you an idea of since when you have two versions of the code going at the same time. That's when you'd go with merge-base based approaches, and it will return C1 in my example.
Not quite a solution to the question but I thought it was worth noting the the approach I use when I have a long-living branch:
At the same time I create the branch, I also create a tag with the same name but with an
-init
suffix, for examplefeature-branch
andfeature-branch-init
.(It is kind of bizarre that this is such a hard question to answer!)
The following command will reveal the SHA1 of Commit A
git merge-base --fork-point A
You could use the following command to return the oldest commit in branch_a, which is not reachable from master:
Perhaps with an additional sanity check that the parent of that commit is actually reachable from master...
Here's an improved version of my previous answer previous answer. It relies on the commit messages from merges to find where the branch was first created.
It works on all the repositories mentioned here, and I've even addressed some tricky ones that spawned on the mailing list. I also wrote tests for this.
You can examine the reflog of branch A to find from which commit it was created, as well as the full history of which commits that branch pointed to. Reflogs are in
.git/logs
.