tags:

views:

5711

answers:

3

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.

+18  A: 

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.

Kevin Ballard
Wow, that's confusing. It turns out that using "git diff HEAD..branch" shows all commits (x, y, z, c, d, e), but "git log HEAD..branch" does exactly what I want and only shows x, y, z! This is the exact opposite of using "...".
Greg Hewgill
`git diff HEAD..branch` is identical to `git diff HEAD branch`. The key thing to remember here is that log takes a list/range of revisions, while diff doesn't. That's why they treat their args differently.
Kevin Ballard
+4  A: 
git cherry branch [newbranch]

does exactly what you are asking.

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.

skiphoppy
Ah, that's a nice one too!
Greg Hewgill
+1  A: 

This is similar to the answer I posted on: http://stackoverflow.com/questions/2176278/preview-a-git-push/2831135#2831135

Drop these funcs into your bash profile:

  • gbout - git branch outgoing
  • gbin - git branch incoming

You can use this like:

  • If on master: gbin branch1 <-- this will show you what's in branch1 and not in master
  • If on master: gbout branch1 <-- this will show you what's in master that's not in branch 1

This will work with any branch.

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}

function gbin { 
    echo branch \($1\) has these commits and \($(parse_git_branch)\) does not 
    git log ..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}

function gbout { 
    echo branch \($(parse_git_branch)\) has these commits and \($1\) does not 
    git log $1.. --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}
Clint Modien