On a github project you can go to a /branches page and se pretty graphs like this one that for each branch show how far behind and how far ahead each branch is with respect to master.
Is there a command line tool that does something similar? Something that works with remotes as well? For example,
git branch -v -v
is close to what I am looking for, but only works for local branches.
To view your remote branches, simply pass the -r flag to the git branch command. You can inspect remote branches with the usual git checkout and git log commands.
branch is X commits behind means that there are X new (unmerged) commits on the branch which is being tracked by your current branch. branch is X commits ahead analogously means that your branch has X new commits, which haven't been merged into the tracked branch yet.
I've been curious about this as well, so i just whipped up a git branch-status
script that gives this information using git for-each-ref
#!/bin/bash # by http://github.com/jehiah # this prints out some branch status (similar to the '... ahead' info you get from git status) # example: # $ git branch-status # dns_check (ahead 1) | (behind 112) origin/master # master (ahead 2) | (behind 0) origin/master git for-each-ref --format="%(refname:short) %(upstream:short)" refs/heads | \ while read local remote do [ -z "$remote" ] && continue git rev-list --left-right "${local}...${remote}" -- 2>/dev/null >/tmp/git_upstream_status_delta || continue LEFT_AHEAD=$(grep -c '^<' /tmp/git_upstream_status_delta) RIGHT_AHEAD=$(grep -c '^>' /tmp/git_upstream_status_delta) echo "$local (ahead $LEFT_AHEAD) | (behind $RIGHT_AHEAD) $remote" done
Usage:
$ git branch-status dns_check (ahead 1) | (behind 112) origin/master master (ahead 2) | (behind 0) origin/master
Update 2015
My initial answer below is not ideal as the upstream branch is not necessarily the branch you are pushing t which could be different from the branch you are pulling from.
With Git 2.5+, the correct command is:
git for-each-ref --format="%(refname:short) %(upstream:track) %(upstream:remotename)" refs/heads
See more at "Viewing Unpushed Git Commits".
(As pointed out by void.pointer in the comments, upstream:track
is more precise than push:track
, depending on the default push policy)
(The (upstream:remotename)
part comes from HankCA's comment, to see if a branch had been pushed (or generally had an upstream equivalent).)
Git 2.13 (Q2 2017) uses a more generic ref-filter API with a more complete git for-each-ref push
:
See commit 3d9e4ce, commit 949af06, commit 56b4360, commit 6eac70f, commit 1a34728, commit 1a0ca5e, commit 3a42980, commit 17938f1, commit 3ba308c, commit a798410, commit b180e6f, commit 01f9582, commit 7743fcc, commit ffd921d, commit 99c6a71, commit d4919bb, commit 42d0eb0, commit 4f3e3b3, commit c58fc85 (10 Jan 2017) by Karthik Nayak (KarthikNayak
).
(Merged by Junio C Hamano -- gitster
-- in commit 93e8cd8, 27 Feb 2017)
push
:The name of a local ref which represents the
@{push}
location for the displayed ref.
Respects:short
,:lstrip
,:rstrip
,:track
, and:trackshort
options asupstream
does.
Produces an empty string if no@{push}
ref is configured.If
lstrip=<N>
(rstrip=<N>
) is appended, strips<N>
slash-separated path components from the front (back) of the refname
(e.g.%(refname:lstrip=2)
turnsrefs/tags/foo
intofoo
and%(refname:rstrip=2)
turnsrefs/tags/foo
intorefs
).If
<N>
is a negative number, strip as many path components as necessary from the specified end to leave-<N>
path components
(e.g.%(refname:lstrip=-2)
turnsrefs/tags/foo
intotags/foo
and%(refname:rstrip=-1)
turnsrefs/tags/foo
intorefs
)
Original answer (2014)
Another way will be available with Git 1.9/2/0 (Q1 2014).
See commit b28061c from Ramkumar Ramachandra (artagnon):
for-each-ref
: introduce %(upstream:track[short])
Introduce:
%(upstream:track)
to display "[ahead M, behind N]
" and%(upstream:trackshort)
to display "=
", ">
", "<
", or "<>
" appropriately (inspired bycontrib/completion/git-prompt.sh
).Now you can use the following format in for-each-ref:
%(refname:short) %(upstream:trackshort)
to display refs with terse tracking information.
Note that
:track
and:trackshort
only work with "upstream
", and error out when used with anything else.
Before Git 2.30 (Q1 2021), a commit and tag object may have CR at the end of each and every line (you can create such an object with hash-object or using --cleanup=verbatim
to decline the default clean-up action), but it would make it impossible to have a blank line to separate the title from the body of the message.
Be lenient and accept a line with lone CR on it as a blank line, too.
See commit e2f8958, commit 9f75ce3 (29 Oct 2020) by Philippe Blain (phil-blain
).
(Merged by Junio C Hamano -- gitster
-- in commit 4c7eb63, 09 Nov 2020)
ref-filter
: handle CRLF at end-of-line more gracefullyHelped-by: Junio C Hamano
Helped-by: Eric Sunshine
Signed-off-by: Philippe Blain
The ref-filter code does not correctly handle commit or tag messages that use CRLF as the line terminator.
Such messages can be created with the
--cleanup=verbatim
option ofgit commit
(man) andgit tag
(man), or by usinggit commit-tree
(man) directly.The function
find_subpos
inref-filter.c
looks for two consecutive LFs to find the end of the subject line, a sequence which is absent in messages using CRLF.
This results in the whole message being parsed as the subject line (%(contents:subject)
), and the body of the message (%(contents:body)
) being empty.Moreover, in
copy_subject
, which wants to return the subject as a single line, '\n
' is replaced by space, but '\r
' is untouched.This impacts the output of
git branch
(man),git tag
(man) andgit for-each-ref
(man) `.This behaviour is a regression for
git branch --verbose
(man), which bisects down to 949af0684c ("branch
: use ref-filter printing APIs", 2017-01-10, Git v2.13.0-rc0 -- merge listed in batch #1).Adjust the ref-filter code to be more lenient by hardening the logic in
copy_subject
andfind_subpos
to correctly parse messages containing CRLF.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With