planetp
planetp

Reputation: 16065

Getting tracking information for a Git branch

How can I get tracking information (i.e. remote and branch name) about a specific local Git branch, preferably in one command? There seem to be many ways to do this, e.g.

git rev-parse --abbrev-ref --symbolic-full-name branch_name@{upstream}

However, it returns the upstream in the form 'origin/branch_name', which makes it difficult to figure out the separate parts (e.g. when remote or branch name contains '/'). Is there more reliable solution, preferably using a single Git command?

Upvotes: 1

Views: 371

Answers (2)

Romain Valeri
Romain Valeri

Reputation: 21938

I'd use the built-in -v (verbose) or even -vv (very verbose) flag to get this from git branch output. You might also just grep the branch name to focus on what you wanted :

git branch -vv | grep <branchName>

Depending on what exactly you want to get, maybe also consider using the plumbing tool :

git for-each-ref --format="%(upstream:short)" refs/heads/<yourBranch>

and make it an alias for convenience

git config --global alias.get-rem '!f() { git for-each-ref --format="%(upstream:short)" refs/heads/$1; }; f'

# then just
git get-rem branch_name

Edit : For the very short part (i.e. "branch" instead of either "refs/remotes/origin/branch" or even "origin/branch"), you can use %(upstream:lstrip:-1) instead of %(upstream:short)

Upvotes: 0

Saurabh P Bhandari
Saurabh P Bhandari

Reputation: 6742

@RomainValeri in the answer suggested this command to display the tracking information.

git for-each-ref --format="%(upstream:short)" refs/heads/<yourBranch>

However, if you want to get rid of the slash then you can do this

git for-each-ref --format="%(upstream:remotename) %(upstream:lstrip=-1)"  \ 
# Insert your separator here                     ^
refs/heads/<yourBranch>

From git-docs,

upstream

The name of a local ref which can be considered “upstream” from the displayed ref. Respects :short, :lstrip and :rstrip in the same way as refname above ...

For any remote-tracking branch %(upstream), %(upstream:remotename) and %(upstream:remoteref) refer to the name of the remote and the name of the tracked remote ref, respectively. In other words, the remote-tracking branch can be updated explicitly and individually by using the refspec %(upstream:remoteref):%(upstream) to fetch from %(upstream:remotename).

More on lstrip,

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) turns refs/tags/foo into foo and %(refname:rstrip=2) turns refs/tags/foo into refs). 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) turns refs/tags/foo into tags/foo and %(refname:rstrip=-1) turns refs/tags/foo into refs). When the ref does not have enough components, the result becomes an empty string if stripping with positive < N >, or it becomes the full refname if stripping with negative < N >. Neither is an error.


Some examples :

  • Format : "%(upstream:remotename):%(upstream:lstrip=-1)"

    Output : <remote-name>:<branch-name>

  • Format : "%(upstream:remotename) %(upstream:lstrip=-1)"

    Output : <remote-name> <branch-name>


If the branch name includes a slash, then lstrip won't work. Instead remoteref can be used.

git for-each-ref --format="%(upstream:remotename) %(upstream:remoteref)" refs/heads/<yourBranch>

The output is in this format : <remote-name> refs/heads/<branch-name>

To remove refs/heads/ from the output, pipe the above command to this

sed 's/refs\/heads\///g'

Upvotes: 1

Related Questions