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?
This question is related to
git
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 remote show origin
Replace 'origin' with whatever the name of your remote is.
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.
In case anyone's reading this and wanting to protect master
with client-side branch protection,
git branch -vv | grep "^\*" |grep -E '\* master |origin\/master'
will return 0
if either the local checked-out branch or its upstream remote branch is master
.
Just put this in your .git/hooks
directory's pre-commit
and update
files accordingly and Bob is your father's brother.
Here is a neat and simple one. Can check git remote -v
, which shows you all the origin and upstream of current branch.
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"
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
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.
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, 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'.
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
Source: Stackoverflow.com