How to get the changes on a branch in Git

Viewed 252394

What is the best way to get a log of commits on a branch since the time it was branched from the current branch? My solution so far is:

git log $(git merge-base HEAD branch)..branch

The documentation for git-diff indicates that git diff A...B is equivalent to git diff $(git-merge-base A B) B. On the other hand, the documentation for git-rev-parse indicates that r1...r2 is defined as r1 r2 --not $(git merge-base --all r1 r2).

Why are these different? Note that git diff HEAD...branch gives me the diffs I want, but the corresponding git log command gives me more than what I want.

In pictures, suppose this:

         x---y---z---branch
        /
---a---b---c---d---e---HEAD

I would like to get a log containing commits x, y, z.

  • git diff HEAD...branch gives these commits
  • however, git log HEAD...branch gives x, y, z, c, d, e.
10 Answers

In the context of a revision list, A...B is how git-rev-parse defines it. git-log takes a revision list. git-diff does not take a list of revisions - it takes one or two revisions, and has defined the A...B syntax to mean how it's defined in the git-diff manpage. If git-diff did not explicitly define A...B, then that syntax would be invalid. Note that the git-rev-parse manpage describes A...B in the "Specifying Ranges" section, and everything in that section is only valid in situations where a revision range is valid (i.e. when a revision list is desired).

To get a log containing just x, y, and z, try git log HEAD..branch (two dots, not three). This is identical to git log branch --not HEAD, and means all commits on branch that aren't on HEAD.

git cherry branch [newbranch]

does exactly what you are asking, when you are in the master branch.

I am also very fond of:

git diff --name-status branch [newbranch]

Which isn't exactly what you're asking, but is still very useful in the same context.

With Git 2.30 (Q1 2021), "git diff A...B(man)" learned "git diff --merge-base A B(man), which is a longer short-hand to say the same thing.

Thus you can do this using git diff --merge-base <branch> HEAD. This should be equivalent to git diff <branch>...HEAD but without the confusion of having to use range-notation in a diff.

Related