Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: How to list commits on a merged branch?

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.

like image 859
singingwolfboy Avatar asked May 07 '14 14:05

singingwolfboy


People also ask

How can I see commits from one branch?

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.

How do I find a merge commit?

To see the merge commit's message and other details, use git show-merge with the same arguments.

What happens to commits after merge?

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.

How many commits are created if you merge two branches?

The nomenclature comes from the fact that Git uses three commits to generate the merge commit: the two branch tips and their common ancestor.


2 Answers

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' -
like image 166
philb Avatar answered Nov 13 '22 14:11

philb


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.

like image 35
Sascha Wolf Avatar answered Nov 13 '22 12:11

Sascha Wolf