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?
011 Answers
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.
21git remote show origin
Replace 'origin' with whatever the name of your remote is.
6If 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.
5An 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 <- 3For 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.
1For 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'. 2Here 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 2Based 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
0git 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"