79

Given a project with several local branches, each tracking some remote branch, is there a command that lists all branches that have unpushed commits? (That is, even if none of those branches are checked out.)

I don't want to see the commits themselves, nor do I want to see branches that are up-to-date, I just want to see which branches are ahead of their remotes.

I have tried git log --branches --not --remotes --simplify-by-decoration --decorate --oneline, but it doesn't seem to show what I need. Running it on my current repo gives no output, but running git status on my current branch shows Your branch is ahead of 'origin/branchname' by 2 commits.

git for-each-ref --format="%(refname:short) %(push:track)" refs/heads and git branch -v both show branches that are up to date as well as ones that need pushing. However, they do both show my current branch as [ahead 2].

Other commands I have found eg. git log @{u}.., git cherry -v list the commits themselves, not the branches.

Side question: why would the output from git log --branches --not --remotes --simplify-by-decoration --decorate --oneline not include branches that git branch -v shows as ahead? Isn't the former command just looking at which refs/heads do not correspond to a known remote; so wouldn't a branch listed as [ahead 2] meet this criteria?

7
  • 1
    Possible duplicate of Show git ahead and behind info for all branches, including remotes Commented Aug 30, 2016 at 7:06
  • @TimBiegeleisen Interesting, but the accepted answer is a Bash script (I use Linux/OSX/Windows), and the other answer gives nearly empty output.
    – detly
    Commented Aug 30, 2016 at 7:12
  • 1
    @TimBiegeleisen Okay, I've identified the problem and this is indeed a duplicate.
    – detly
    Commented Aug 30, 2016 at 7:14
  • 1
    I felt that the effort needed to give you a high quality answer would far exceed doing a thorough search here on SO and elsewhere. Commented Aug 30, 2016 at 7:16
  • 1
    @TimBiegeleisen Hah, I've been searching all day for this, and I didn't think to use the terms "ahead" and "behind" (or "track" etc.)!
    – detly
    Commented Aug 30, 2016 at 7:18

4 Answers 4

111

The --no-walk option to log seems to do a better job of what I need than --simplify-by-decoration. My full command is:

git log --branches --not --remotes --no-walk --decorate --oneline

...which I've aliased to unpushed.

9
  • 1
    In constrast to @VonC's answer this does show branches with no corresponding remotes, so YMMV depending on your workflow. For mine, this is preferable :)
    – detly
    Commented Jan 10, 2018 at 5:42
  • 7
    Or, if you have multiple remotes: git log --branches --not --remotes=origin --no-walk --decorate --oneline to see what you haven't pushed to the origin remote. Commented Aug 13, 2018 at 18:52
  • 1
    @BenediktKöppel Ah that's a good idea, I do often work with multiple remotes.
    – detly
    Commented Aug 13, 2018 at 22:11
  • 13
    For me this also shows branches which are behind the remote and can be fast-forwarded. Those branches do not have unpushed local changes.
    – sigy
    Commented Nov 30, 2018 at 15:01
  • 1
    This was not useful for me. It lists basically every branch, even though exactly 0 have unpushed commits. Commented Jul 10, 2023 at 0:50
14
git for-each-ref --format="%(refname:short) %(push:track)" refs/heads

That remain the most precise answer that you can easily parse/grep to get the desired output (like removing up-to-date branches)

You can do so in a bash script that you will call git-xxx (no extension), somewhere in your $PATH or %PATH%.
That script can then be called with git xxx, and will use git bash.
That is portable and will work across platforms (meaning even on Windows, where <Git For Windows>/usr/bin includes 200+ linux commands (grep, sed, awk, xargs, ...)

2
  • 1
    Note that this doesn't highlight branches that are not tracking a remote (and which therefore have all unpushed commits).
    – Tamlyn
    Commented Jan 9, 2018 at 14:12
  • 1
    @Tamlyn I agree. In the context of this question however, I focused only on local branches which have set a remote tracking branch.
    – VonC
    Commented Jan 9, 2018 at 14:23
7

although the answers above are very helpful and show alot of data but for others coming here looking for a solution to find local branches which are ahead i.e. have not been pushed yet. can get the exact list by executing:

git branch -v | grep ahead
4
  • Not sure if this works reliably... I just tried it after a commit (no push) to an existing branch and no ahead text appears in the git branch -v command. This is with Git version git version 2.24.3 (Apple Git-128). It did, however, work with an older Git version, git version 2.13.0.windows.1 Commented Apr 23, 2021 at 18:18
  • I should also mention the test that did work on the older Git version was for a branch that existed on the remote and had a local un-pushed commit. However, it does not work for branches that do not exist on the remote (but I'm not sure if OP was asking about that scenario or not). Commented Apr 23, 2021 at 18:21
  • I modified it to find all branches out of sync with this: git branch -v |grep 'ahead\|behind'
    – Martin P.
    Commented Jun 30, 2022 at 19:05
  • This does not show branches with no upstream at all, which could be a significant gotcha... It also doesn't work if the terminal language is not English. Commented Jun 20, 2023 at 6:59
5

You can also see what branches are not yet merged to master

git checkout master

and then

git branch --no-merged
1
  • You can seemingly do this without checking out the branch first: "With --merged, only branches merged into the named commit (i.e. the branches whose tip commits are reachable from the named commit) will be listed. With --no-merged only branches not merged into the named commit will be listed. If the <commit> argument is missing it defaults to HEAD (i.e. the tip of the current branch)." git-scm.com/docs/git-branch Commented Jul 8, 2021 at 3:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.