Reputation: 30761
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?
Upvotes: 1102
Views: 646700
Reputation: 496722
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 plumbing 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.
Upvotes: 1537
Reputation: 6506
Get info about all remotes, branches and tracking:
for remote in $(git remote show -n); do git remote show -n "${remote:?}"; done
or get just names of remotes with their url
git remote -v show -n
Upvotes: 3
Reputation: 1230
Here is a neat and simple one. Can check git remote -v
, which shows you all the origin and upstream of current branch.
Upvotes: 7
Reputation: 6056
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.
Upvotes: 165
Reputation: 10882
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"
Upvotes: 1
Reputation: 12940
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
Upvotes: 4
Reputation: 1852
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 <-
Upvotes: 68
Reputation: 149726
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'.
Upvotes: 22
Reputation: 150565
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
Upvotes: 95
Reputation: 18257
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.
Upvotes: 43
Reputation: 51435
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
Upvotes: 6
Reputation: 49354
git remote show origin
Replace 'origin' with whatever the name of your remote is.
Upvotes: 371