When working on feature branches (e.g., feature
) created off of our main (e.g., master
) branch, I use the following git command to view a list of commits that have been added to the feature
branch that are not on the master
branch:
git log --oneline master..HEAD
This outputs a nice short summary of the commits on feature
that aren't on master
(note, this command is run after checking out the feature
branch):
$ git log --oneline master..HEAD
1ca070a (HEAD -> feature) foo the bar
03a1047 baz the wuz
c9e8279 fop the sip
6ee6d6f up the ante
5812200 bop the binky
The problem is, it doesn't show the common ancestor commit on the master
branch. What I would like is for the command to include one more line, that's the common ancestor commit, like this:
1ca070a (HEAD -> feature) foo the bar
03a1047 baz the wuz
c9e8279 fop the sip
6ee6d6f up the ante
5812200 bop the binky
fb37d68 (master) fuzzy the wuzzy
I would expect that replacing master
with master~1
would include one commit prior to the common ancestor, and therefore include the common ancestor,
git log --oneline master~1..HEAD
but whether I specify master
or master~1
, the log summary is always the same.
$ git log --oneline master~1..HEAD
1ca070a (HEAD -> feature) foo the bar
03a1047 baz the wuz
c9e8279 fop the sip
6ee6d6f up the ante
5812200 bop the binky
My question is, how can I include the common ancestor commit in the log summary? Note that the common ancestor is not necessarily the tip of the master
branch.
I find that this kind of --boundary
includes too many commits quite often, but:
git log --boundary --right-only --oneline master...HEAD
should get you close-ish. Add --graph
(and for completeness --decorate
, though you obviously have log.decorate
set) to get something even more useful. Leave out the --right-only
to get the most useful output. Given the --right-only
, you can simplify this to --boundary master..HEAD
, but read on to see why I suggest not using --right-only
, but using --graph
.
What this does is a bit complicated:
The three dot syntax master...HEAD
requests a symmetric difference. That is, we get all commits that are reachable from master
but not from HEAD
from the left side of the three dots, and all commits reachable from HEAD
but not master
on the right side.
The --right-only
option, if specified, eliminates the left-side commits.
The --boundary
option adds back, to the set of commits to be visited by the graph walk, those commits that were specifically chosen as not to be shown via the symmetric difference algorithm.
Consider this graph, drawn with parent commits to the left and children to the right (rather than parents below and children above as git log --graph
does):
C--D--E <-- master
/
...--A--B
\
F--G--H <-- feature (HEAD)
The uppercase letters here stand in for commit hash IDs. Commits E
back to C
are reachable from master
, and commits H
back through F
are reachable from HEAD
(which is attached to the name feature
). Commit B
is the merge base of these two sets of commits.
Here, master...feature
selects commits C-D-E
on the left and F-G-H
on the right. (Note that reversing the names—feature...master
—selects the same commits, but now C-D-E
would be on the right.) So adding --right-only
to this set gets you almost what you want: commits through HEAD
, excluding commits reachable from master
. That's the same output you'd get from the simpler master..feature
.
Now, if we add --boundary
, Git will include commit B
as well. That is, both git log --boundary master..feature
or git log --boundary --right-only master...feature
will show commits B-F-G-H
(in the other order).
With --decorate
, when git log
shows commit H
, it will add the HEAD -> feature
decoration. But commit B
has no branch name, so it will not be decorated. It will be hard to tell that commit B
belongs to both branches.
Without --right-only
and with --boundary
and --graph
, Git will show commits C-D-E
on master and F-G-H
on feature, with E
and H
decorated, and will include boundary commit B
. The resulting graph will show pretty clearly that B
is the shared merge-base commit.
When the graph gets complicated, --boundary
adds back too many commits. The extra commits will still be displayed reasonably clearly—as clearly as these things get when there are as many graph lines as git log --graph
introduces, anyway. You can add --simplify-by-decoration
to help eliminate a lot of the visual clutter: the resulting graph is probably readable, and will let you identify the shared commit.