How to see how many commits a local branch is ahead/behind another local branch in git?

If I’m working on a feature branch, I would like to know how many commits this branch is ahead or behind the master branch. I can’t seem to find the command that does this.

  • Convert git repo with submodules to single repo
  • How do I checkout a feature with git?
  • Git: Cannot see new remote branch
  • How can I tell Jenkins to compile some, but not all branches of a repository?
  • Subversion checkout from a GitHub repository which contains symlinks
  • When coding in TypeScript should the generated .js files be committed to git?
  • How to ignore source files in bower
  • How to find all commits having a particular parent?
  • Retaining file permissions with Git
  • Git post-receive hook to update a local clone owned by a different user
  • Composer: Develop directly in vendor packages
  • Why does git stash creates 2 commit objects? Seems like 1 was adequate
  • 2 Solutions collect form web for “How to see how many commits a local branch is ahead/behind another local branch in git?”

    Listing and counting commits: git rev-list

    A quick way is to do what git status does when there’s an “upstream”. Specifically, git status simply counts revisions that are on the current branch that are not on the upstream branch. For instance, consider branch foo that has an upstream of origin/foo, and suppose you’ve made three local commits and then used git fetch to bring in one upstream commit:

                  L - L - L   <-- foo
                /
    ... - C - C
                \
                  U           <-- origin/foo
    

    Here Cs are common commits, Ls are local commits, and U is an upstream commit. If you’re on branch foo and you run git status you’ll see “ahead 3, behind 1”.

    Here’s how git gets those numbers:

    1. git rev-list foo --not origin/foo: this produces a list of all commits on foo but not on origin/foo. That is, starting at origin/foo (which is commit U), strike out the commit and all earlier commits reachable: that’s U and all the C commits. Then, start at foo and find all reachable commits that are not already struck out: that’s just the three L commits.

    2. Add --count to the git rev-list arguments to make it print a count instead of the raw commit-ID SHA-1 values.

    3. Repeat for git rev-list origin/foo --not foo: this is all commits that are reachable from origin/foo but not from foo, which in this example is just commit U. (Again, add --count to get just the count, rather than the actual commit IDs.)

    Note that foo --not origin/foo is also spelled origin/foo..foo in gitrevisions syntax. (In the case of git status it’s always looking at the current branch—which is named via HEAD—and its upstream. You can use the @{upstream} syntax to obtain the name of the upstream, or shorten this to @{u}; and HEAD is the default if you list no name at all; so to re-implement git status you can just look at git rev-list --count ..@{u} and git rev-list --count @{u}...)

    Using rev-list on local branches, vs using git cherry

    Hence, if you want to count commits reachable from branch feature but not from branch master, you can do the same thing but with the names feature and master. The git rev-list syntax master..feature names all commit IDs reachable from feature but not from master, and --count will get you a count:

    git rev-list --count master..feature
    

    If you’ve cherry-picked some commits from one branch to another, though, so that they have different commit IDs but the same diff, this will “over-count”. For instance suppose feature had five commits that master did’t, but then you (or someone) had decided that one of those five commits should be cherry-picked into master, you might now have this:

                  D - E - F - G - H   <-- feature
                /
    ... - C - C
                \
                  F'                  <-- master
    

    where F' is basically just a copy of commit F. If you ask git rev-list to count commits on feature that are not on master, you’ll get 5; but if you ask git cherry to find commits on feature that are not on master, it will eliminate commit F from its list, because it will see that F' is a copy of F. If you count the commits listed by git cherry you will therefore get 4, not 5.

    Use git cherry to find the commits present in one branch and not present in other

    git cherry -v master feature
    

    It will list all the commits present in feature branch which are not present in the master.

    Similarly,

    git cherry -v feature master 
    

    will list all the commits present in master branch which are not present in feature.

    You can also provide an additional third parameter for picking a starting point.

    git cherry -v feature master 1b219e
    

    UPDATE:

    You can create an alias to combine the two

    [alias]
        mydiff = !sh -c 'echo "Commits in $2 not in $1" && git cherry -v $1 $2 && echo "Commits in $1 not in $2" && git cherry -v $2 $1' -
    

    Use,

    git mydiff master feature
    
    Git Baby is a git and github fan, let's start git clone.