In the absence of merges back onto master, the last entry of git rev-list master..feature/new-branch
would be the one you want. a..b
in a rev-list gives you all the commits in b
's history that are not in a
's history. But since you've merged, all the commits in feature/new-branch's history are also in master's history, so we have to be a bit cleverer.
The question you linked (rather, this answer to it) gives a very good start. The trick is to use --first-parent
to avoid considering the right-hand-side of all the merges into master as being part of master's history. git rev-list --first-parent master
gives you all the commits that were committed directly into master, and doesn't show any commits that were merged. Alas, --first-parent
doesn't combine with ..
in the way we want, so we have to make our own ..
equivalent, using diff
. We can use diff
to take our list of all the commits in feature/new-branch's history, and remove all the commits that's are in master's "direct" history. I've used backslash escaping to split the one command across several lines:-
diff --new-line-format=%L --old-line-format= --unchanged-line-format= \
<(git rev-list --first-parent master) \
<(git rev-list --first-parent feature/new-branch)
The options to diff
make it only print out the lines that are in the second input but not the first input, with no + or - stuff and no headers. I'm not well up on POSIX, so it may be that only GNU diff has those options. Similarly, for the <( )
operator on the other two lines, you need bash or zsh. If you have to use some other shell, you'll probably need to use temporary files.
The first input (the one of lines to ignore) is the "direct" history to master, as we found out above; the second input is the "direct" history of feature/new-branch. The output of the command is all the commits that were committed to feature/new-branch "directly", but not to master "directly", where "directly" means "not through a merge". Including --first-parent
on the second input is necessary to avoid including any commits that were merged into master before branching feature/new-branch, but it'll have the side-effect of excluding commits from any other branches that were merged into feature/new-branch (which doesn't make a difference if you only want the first commit).
The output is in reverse order, as usual, so the last line of the output is the commit you're interested in.
I'm really curious to know what you're trying to achieve with this information, as it seems like it doesn't fit with Git's model of the world at all. Git users know and expect that the history of a branch includes the history from the branch's ancestor, and the history of any merges into it.