I know I can do git branch --all
, and that shows me both local and remote branches, but it's not that useful in showing me the relationships between them.
How do I list branches in a way that shows which local branch is tracking which remote?
I know I can do git branch --all
, and that shows me both local and remote branches, but it's not that useful in showing me the relationships between them.
How do I list branches in a way that shows which local branch is tracking which remote?
Very much a porcelain command, not good if you want this for scripting:
git branch -vv # doubly verbose!
Note that with git 1.8.3, that upstream branch is displayed in blue (see "What is this branch tracking (if anything) in git?")
If you want clean output, see Carl Suster's answer - it uses a porcelain command that I don't believe existed at the time I originally wrote this answer, so it's a bit more concise and works with branches configured for rebase, not just merge.
git remote show origin
Replace 'origin' with whatever the name of your remote is.
If you look at the man page for git-rev-parse
, you'll see the following syntax is described:
<branchname>@{upstream}
, e.g.master@{upstream}
,@{u}
The suffix
@{upstream}
to a branchname (short form<branchname>@{u}
) refers to the branch that the branch specified by branchname is set to build on top of. A missing branchname defaults to the current one.
Hence to find the upstream of the branch master
, you would do:
git rev-parse --abbrev-ref master@{upstream}
# => origin/master
To print out the information for each branch, you could do something like:
while read branch; do
upstream=$(git rev-parse --abbrev-ref $branch@{upstream} 2>/dev/null)
if [[ $? == 0 ]]; then
echo $branch tracks $upstream
else
echo $branch has no upstream configured
fi
done < <(git for-each-ref --format='%(refname:short)' refs/heads/*)
# Output:
# master tracks origin/master
# ...
This is cleaner than parsing refs and config manually.
An alternative to kubi's answer is to have a look at the .git/config
file which shows the local repository configuration:
cat .git/config
git for-each-ref --format='%(refname:short) <- %(upstream:short)' refs/heads
will show a line for each local branch. A tracking branch will look like:
master <- origin/master
A non-tracking one will look like:
test <-
For the current branch, here are two good choices:
% git rev-parse --abbrev-ref --symbolic-full-name @{u}
origin/mainline
or
% git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
origin/mainline
That answer is also here, to a slightly different question which was (wrongly) marked as a duplicate.
For the current branch, you could also say git checkout
(w/o any branch). This is a no-op with a side-effects to show the tracking information, if exists, for the current branch.
$ git checkout
Your branch is up-to-date with 'origin/master'.
Here is a neat and simple one. Can check git remote -v
, which shows you all the origin and upstream of current branch.
I use this alias
git config --global alias.track '!f() { ([ $# -eq 2 ] && ( echo "Setting tracking for branch " $1 " -> " $2;git branch --set-upstream $1 $2; ) || ( git for-each-ref --format="local: %(refname:short) <--sync--> remote: %(upstream:short)" refs/heads && echo --Remotes && git remote -v)); }; f'
then
git track
Based on Olivier Refalo's answer
if [ $# -eq 2 ]
then
echo "Setting tracking for branch " $1 " -> " $2
git branch --set-upstream $1 $2
else
echo "-- Local --"
git for-each-ref --shell --format="[ %(upstream:short) != '' ] && echo -e '\t%(refname:short) <--> %(upstream:short)'" refs/heads | sh
echo "-- Remote --"
REMOTES=$(git remote -v)
if [ "$REMOTES" != '' ]
then
echo $REMOTES
fi
fi
It shows only local with track configured.
Write it on a script called git-track on your path an you will get a git track command
A more elaborated version on https://github.com/albfan/git-showupstream
git config --get-regexp "branch\.$current_branch\.remote"
will give you the name of the remote that is being tracked
git config --get-regexp "branch\.$current_branch\.merge"
will give you the name of the remote branch that's being tracked.
You'll need to replace $current_branch with the name of your current branch. You can get that dynamically with git rev-parse --abbrev-ref HEAD
The following mini-script combines those things. Stick it in a file named git-tracking
, make it executable, and make sure it's in your path.
then you can say
$ git tracking
<current_branch_name>-><remote_repo_name>/<remote_branch_name>
note that the remote branch name can be different from your local branch name (although it usually isn't). For example:
$git tracking
xxx_xls_xslx_thing -> origin/totally_bogus
as you can see in the code the key to this is extracting the data from the git config. I just use sed to clear out the extraneous data.
#!/bin/sh
current_branch=$(git rev-parse --abbrev-ref HEAD)
remote=$(git config --get-regexp "branch\.$current_branch\.remote" | sed -e "s/^.* //")
remote_branch=$(git config --get-regexp "branch\.$current_branch\.merge" | \
sed -e "s/^.* //" -e "s/refs\/.*\///")
echo "$current_branch -> $remote/$remote_branch"