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 mast
If you like terse commands,
git rev-list $(git rev-list --first-parent ^branch_name master | tail -n1)^^!
Here's an explanation.
The following command gives you the list of all commits in master that occurred after branch_name was created
git rev-list --first-parent ^branch_name master
Since you only care about the earliest of those commits you want the last line of the output:
git rev-list ^branch_name --first-parent master | tail -n1
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
git rev-list commit^^!
is just a way to show the parent commit reference. You could use
git log -1 commit^
or whatever.
PS: I disagree with the argument that ancestor order is irrelevant. It depends on what you want. For example, in this case
_C1___C2_______ master \ \_XXXXX_ branch A (the Xs denote arbitrary cross-overs between master and A) \_____/ branch B
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.