This is the inverse of how to list commits on a branch but not merged branches, so I'll ask it in the same format. Let's say my git commit history looks like this:
A---B---C---D---E---F master
\ /
X---Y---Z topic
How do I list the commits on the topic
branch -- that is, X
, Y
, and Z
? Note that simply doing git log topic
won't work -- that will return commits A
and B
as well.
I had thought I could run git merge-base topic master
to find B
, and then do git log B..Z
to get these commits. Unfortunately, git merge-base topic master
returns Z
, not B
, which makes sense in retrospect -- since Z
is already merged to master, the first commit between topic
and master
that shares history is Z
.
Git rev-list will list commits in one branch that are not in another branch. It is a great tool when you're trying to figure out if code has been merged into a branch or not. Using the --oneline option will display the title of each commit. The ^ operator excludes commits in the specified branch from the list.
To see the merge commit's message and other details, use git show-merge with the same arguments.
THE MERGE COMMIT For instance, when a branch named feature is merged with master, a new commit is created on the branch master which has two parents, the previous head of master and the head of feature. On merging the feature to master. These commands create a new merge commit 1c32600.
The nomenclature comes from the fact that Git uses three commits to generate the merge commit: the two branch tips and their common ancestor.
If you only merged topic
to master
once, and you know that you merged topic
into master
in merge commit E
, you can simply use the <rev>^-<n>
revision syntax:
git log E^-
If you don't remember the hash of commit E
and want an easy way to find it, based on the name of your branch (topic
), you can use one of the answers in the question "Find merge commit which include a specific commit". I personnally like git when-merged
:
git when-merged topic
Putting it all together:
git log $(git when-merged -c topic)^-
If you merged topic
several times to master
, then the syntax above will only list the commits that were merged in the most recent merge commit. In that case, you can use rocketraman's mergedtopiclg
alias
git mergedtopiclg $(git when-merged -c topic)
For completeness this alias is configured as
mergedtopiclg = !sh -c \"git lg $(git oldest-ancestor $1^2 ${2:-master})..$1^2\" -
# The oldest ancestor between an integration branch (by default, master) and a topic branch (by default HEAD)
# e.g. git oldest-ancestor master ai/topic
# See http://stackoverflow.com/a/4991675/430128
oldest-ancestor = !bash -c 'diff --old-line-format= --new-line-format= <(git rev-list --first-parent \"${1:-master}\") <(git rev-list --first-parent \"${2:-HEAD}\") | head -1' -
You can use the following command:
git log topic --not $(git rev-list master ^topic --merges | tail -1)^
git rev-list master ^topic --merges
returns the SHA-1 keys for all merge commits from master
to topic
; since it's possible that there are multiple merge commits I use tail -1
to just get the last merge commit which is the merge commit of master
and topic
.
Then we log all commits for topic
while omiting all commits for the first parent of the merge commit (--not <merge-commit>^
).
To use this command effectively I would define an alias as follows:
git config --global alias.<alias-name> '!f() { git log $1 --not $(git rev-list $2 ^$1 --merges | tail -1)^; }; f'
Which then can be used like this git <alias-name> topic master
.
Just for your information:
In my git version (1.9.0) it would also work if you omit tail
but I thought it would be cleaner to only return the relevant SHA-1 key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With