Find out which remote branch a local branch is tracking
Asked Answered
V

26

1259

See also:
How can I see which Git branches are tracking which remote / upstream branch?

How can I find out which remote branch a local branch is tracking?

Do I need to parse git config output, or is there a command that would do this for me?

Validate answered 5/10, 2008 at 5:41 Comment(2)
Sheesh. This is not an exact duplicate. This is a subset of the other, but there are other ways to do the out question, like git remote show origin. The main answer in the other question is a bash script wrapped around the simple answer here, which might be useful to some. Hopefully this question will not be completely closed.Lungan
Agreed, this definitely shouldn't be a dupe. It's asking something completely different than the linked questionLaquitalar
G
1427

Here is a command that gives you all tracking branches (configured for 'pull'), see:

$ git branch -vv
  main   aaf02f0 [main/master: ahead 25] Some other commit
* master add0a03 [jdsumsion/master] Some commit

You have to wade through the SHA and any long-wrapping commit messages, but it's quick to type and I get the tracking branches aligned vertically in the 3rd column.

If you need info on both 'pull' and 'push' configuration per branch, see the other answer on git remote show origin.


Update

Starting in git version 1.8.5 you can show the upstream branch with git status and git status -sb

Geode answered 21/9, 2012 at 21:54 Comment(7)
This output is more direct than git branch -av or git remote show origin, which give you a LOT of data, not just the tracked remoteParrish
While this give you information you want, I would disagree as it being the correct answer. It's an answer the same way giving someone a dictionary answers "how do you spell XYZ". case in point, you want to USE the resulting answer (the branch name) for some operation.. This answer only helps me visually see it... doesn't give you something usable in a subsequent command.Selfness
The output of this command can be misleading since a commit message may easily begin with for example "[my-feature] ...". Please see @Lungan 's answer that shows only the upstream branch (if any) and nothing else.Romansh
I agree with @jonas-berlin -- cdunn2001's answer is better if you want to parse the result -- my answer is good if you are looking for a simple command and are willing to visually scan the outputGeode
git branch -vv | grep '*'Stipulate
You can improve this by adding --list $localBranchName and it will only output the information for this specific branch, e.g.: git branch -vv --list masterAlgo
Just to clarify, this doesn't work for more complex setups where you are pushing to a different branch/remote than you pull from. In that case, it only displays the configured merge/pull branch, not the default push target for a branch.Arber
L
504

Two 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
Lungan answered 17/3, 2012 at 20:17 Comment(18)
Nice! The first one gives ugly errors in case nothing is tracked, while the second is especially helpful for scripting. BTW %(refname:short) is the name of the current ref within --format.Degeneracy
This is great! I am surprised that the second choice runs faster on my machine. It seems that git is called twice, but it certainly runs faster. Any idea why this is?Harquebus
Awesome! Can you point me at the docs where the @{u} comes into play? Not familiar and would love to understand that better.Cloaca
git help revisions (one of the little-known but most useful parts of the docs) and search for upstream.Lungan
Is this supposed to work in Windows? I am getting this error in PowerShell: Missing '=' operator after key in hash literal.Sociometry
@pilau, I think you need to escape the %.Lungan
The PowerShell escape character is backtick, not backslash. Maybe that will help. If you find the real solution, please post it!Lungan
This answer is much better than the two answers above it, especially if you want to do something like git diff `git rev-parse --abbrev-ref --symbolic-full-name @{upstream}`Televise
This is really useful echo 'git for-each-ref --format=\'%(refname:short) -> %(upstream:short)\' refs/heads/$1' > ~/bin/git-show-upstream; chmod +x ~/bin/git-show-upstreamCrawler
If you want to find out the upstream for some other branch, a variant of the second choice is: git for-each-ref --format='%(upstream:short)' $(git rev-parse --symbolic-full-name SOMEBRANCH) replacing SOMEBRANCH with the branch name, or "HEAD" for current branchRomansh
One important thing to remember is that the tracking branch does not necessarily have to be a remote branch.Romansh
In the case nothing is tracked you can avoid the ugly error message by redirecting error stream: git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/nullDonelson
I had to add parenthesis to avoid a long list in case the symbolic-ref is empty: git for-each-ref --format='%(upstream:short)' "$(git symbolic-ref -q HEAD)"Insensate
@Degeneracy ugly errors? I get fatal: no upstream configured for branch '<branchname>' , which is about as photogenic of an error as I could hope for. (Probably was ugly back in '12 when that comment was written, to be fair)Anissa
If I'd have asked the question, this would have been my accepted answer. This one is really friendly if you're consuming it within an automated script. Also, refer this: https://mcmap.net/q/14510/-git-show-remote-name-of-remote-branchChela
Thank you for this. Been looking for a simple way to print the branch-name for @{u}, @{-1} , and HEAD for ages.Nayarit
Does not work on a fresh clone of an empty repository.Cadency
@Crawler No need to create a shell script, just add an alias, e.g. git config --global alias.upb 'for-each-ref ...'Aforesaid
R
252

I think git branch -av only tells you what branches you have and which commit they're at, leaving you to infer which remote branches the local branches are tracking.

git remote show origin explicitly tells you which branches are tracking which remote branches. Here's example output from a repository with a single commit and a remote branch called abranch:

$ git branch -av
* abranch                d875bf4 initial commit
  master                 d875bf4 initial commit
  remotes/origin/HEAD    -> origin/master
  remotes/origin/abranch d875bf4 initial commit
  remotes/origin/master  d875bf4 initial commit

versus

$ git remote show origin
* remote origin
  Fetch URL: /home/ageorge/tmp/d/../exrepo/
  Push  URL: /home/ageorge/tmp/d/../exrepo/
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    abranch
    master
  Remote branches:
    abranch tracked
    master  tracked
  Local branches configured for 'git pull':
    abranch merges with remote abranch
    master  merges with remote master
  Local refs configured for 'git push':
    abranch pushes to abranch (up to date)
    master  pushes to master  (up to date)
Radius answered 11/10, 2011 at 22:25 Comment(3)
I need a command that discovers the upstream branch, so using 'origin' as input is making an assumption, so this does not work for meCashandcarry
But this DOES answer the OP. The command git remote show origin shows you local branches and what they track for both push and pull.Awestricken
@Awestricken I think the point was that this command assumes that the remote is called origin, while it could actually be anything (e.g. multiple remotes, with different branches tracking branches from different remotes).Rondure
C
100

Update: Well, it's been several years since I posted this! For my specific purpose of comparing HEAD to upstream, I now use @{u}, which is a shortcut that refers to the HEAD of the upstream tracking branch. (See https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-emltbranchnamegtupstreamemegemmasterupstreamememuem ).

Original answer: I've run across this problem as well. I often use multiple remotes in a single repository, and it's easy to forget which one your current branch is tracking against. And sometimes it's handy to know that, such as when you want to look at your local commits via git log remotename/branchname..HEAD.

All this stuff is stored in git config variables, but you don't have to parse the git config output. If you invoke git config followed by the name of a variable, it will just print the value of that variable, no parsing required. With that in mind, here are some commands to get info about your current branch's tracking setup:

LOCAL_BRANCH=`git name-rev --name-only HEAD`
TRACKING_BRANCH=`git config branch.$LOCAL_BRANCH.merge`
TRACKING_REMOTE=`git config branch.$LOCAL_BRANCH.remote`
REMOTE_URL=`git config remote.$TRACKING_REMOTE.url`

In my case, since I'm only interested in finding out the name of my current remote, I do this:

git config branch.$(git name-rev --name-only HEAD).remote
Complicated answered 31/8, 2011 at 0:37 Comment(10)
This was very useful in making an alias to rebase whatever my current branch is. Thanks!Partheniaparthenocarpy
Likewise useful for our 'fastforward' alias which'll advance the local tracking branch to the remote as long as the operation is a fast-forward.Faints
Actually I discovered this git name-rev --name-only HEAD won't tell you which branch you're actually on. For that I just used git branch | grep '^\*' | cut -d' ' -f2Faints
Thanks! Other answers to similar questions didn't mention @{u} alias/shortcut and that's exactly what I was looking for! No reason to compare with master branch if you only want to determine whether you need to pull or not.Inshore
@{u} is the bomb. And has been around since 1.7.0, which means that if it's not available in a git that someone is using in 2018, they're probably due for an upgrade.Judicator
Better than git name-rev to determine LOCAL_BRANCH is LOCAL_BRANCH=$(git symbolic-ref -q HEAD) (as shown in @rubo77's answer)Litre
Use symbolic-ref --short HEAD for a single word to describe the current branch.Dhoti
Caution: this doesn't have TRACKING_REMOTE fall back to origin if the remote config is not defined. Also, REMOTE_URL isn't cognizant of url.<base>.insteadOf. See this answer for the resolution.Dhoti
echoing complaint above, git name-rev --name-only HEAD would return tag name instead of branch name in certain cases and may also return the wrong branch name if the commit is the head of multiple branches.Keldon
!!! This strikes me as the start of the most correct approach in most cases. For example, I sometimes want to push some of my commits to the remote, but not all. So I might do branch=$(git branch --show-current), then use git config branch.$branch.pushRemote (defaulting to git config branch.$branch.remote if there's no separate push remote), and finally for example say I want to push all but the last two commits: git push "$remote" HEAD~2:"$branch". Of course in an alias/wrapper this ends up looking like just git p HEAD~2.Cavan
B
65

The local branches and their remotes.

git branch -vv 

All branches and tracking remotes.

git branch -a -vv

See where the local branches are explicitly configured for push and pull.

git remote show {remote_name}
Biological answered 16/7, 2016 at 0:37 Comment(4)
This is the correct answer. For example git remote show origin actually does show the url of my remote.Calutron
@Calutron this requires you to know the name of your remote (origin). Are you 100% sure that when you type git push you are pushing to origin? This is not the case for me and I'm actually here looking for simple answers because so many of my aliases/shortcuts hardcode origin but sometimes I work with multiple remotes and so those are broken for meMaragaret
@Maragaret the pattern in post below answer might help. I just tried it and it worked pretty well.Premedical
@Premedical Yeah I actually already up-voted that answer the same day. Its clean but would be nice if git could answer it without having to make multiple invocations. I went and rewrote several of my aliases/functions that used to hard-code originMaragaret
H
39

git branch -vv | grep 'BRANCH_NAME'

git branch -vv : This part will show all local branches along with their upstream branch .

grep 'BRANCH_NAME' : It will filter the current branch from the branch list.

Holierthanthou answered 15/11, 2019 at 8:18 Comment(1)
Thanks, I was using this to determine if the current branch was tracking a remote branch. Incase anyone else is doing the same thing... The output if there is no tracked branch will be * 'BRANCH_NAME' <commit-sha> 'commit message' if there is a tracked branch * 'BRANCH_NAME' <commit-sha> ['TRACKED_BRANCH_NAME']'commit message'Smoky
E
32

This will show you the branch you are on:

$ git branch -vv

This will show only the current branch you are on:

$ git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)

for example:

myremote/mybranch

You can find out the URL of the remote that is used by the current branch you are on with:

$ git remote get-url $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)|cut -d/ -f1)

for example:

https://github.com/someone/somerepo.git
Extrasystole answered 16/11, 2016 at 11:26 Comment(1)
Shortcut for the last one: git remote get-url $(git for-each-ref --format='%(upstream:remotename)' $(git symbolic-ref -q HEAD))Laminitis
R
26

You can use git checkout, i.e. "check out the current 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'.
Rhineland answered 23/10, 2014 at 10:27 Comment(1)
This doesn't seem to work with git v2.39.0Otoole
S
21

Yet another way

git status -b --porcelain

This will give you

## BRANCH(...REMOTE)
modified and untracked files
Stansberry answered 16/9, 2015 at 16:17 Comment(3)
Simple and shortParalyse
Warning: Format may by different on some corner cases, e.g. a fresh clone of empty repository: ## No commits yet on master...origin/master [gone]Cadency
Better is to use git status -b --porcelain=v2, see the Warning above.Cadency
R
20

I don't know if this counts as parsing the output of git config, but this will determine the URL of the remote that master is tracking:

$ git config remote.$(git config branch.master.remote).url
Rooftop answered 21/6, 2011 at 12:17 Comment(2)
Or git config branch.$(git symbolic-ref -q HEAD).remote if you just want the name of the remote being tracked of the current branch—git config remote.$(git config branch.$(git symbolic-ref -q HEAD).remote).url for the URL.Egerton
I needed to add --short option so it works. So for getting the remote name of current branch: git config branch.$(git symbolic-ref -q --short HEAD).remote and for getting the URL of the remote of current branch: git config remote.$(git config branch.$(git symbolic-ref -q --short HEAD).remote).urlEyra
Q
20

git-status porcelain (machine-readable) v2 output looks like this:

$ git status -b --porcelain=v2
# branch.oid d0de00da833720abb1cefe7356493d773140b460
# branch.head the-branch-name
# branch.upstream gitlab/the-branch-name
# branch.ab +2 -2

And to get the branch upstream only:

$ git status -b --porcelain=v2 | grep -m 1 "^# branch.upstream " | cut -d " " -f 3-
gitlab/the-branch-name

If the branch has no upstream, the above command will produce an empty output (or fail with set -o pipefail).

Questionary answered 19/2, 2020 at 9:44 Comment(3)
I like this solution, because it allows detecting in the script if any upstream branch is configured for a local branch, without knowing anything about their names.Wileen
Works well, unfortunately, a bit low on large repositories and it may add a long useless output after the branch information.Cadency
To speed it up and avoid possible unnecessary long output, use non-existing dir, e.g. git status -b --porcelain=v2 .non-existing-dirCadency
A
13

Another simple way is to use

cat .git/config in a git repo

This will list details for local branches

Aphra answered 10/12, 2014 at 7:19 Comment(2)
Works nicely on Linux. Will not work on Windows unless in a Unix-like prompt (e.g. cygwin or git bash).Sectionalize
In Windows simply use type .git/config instead of cat .git/config of course on plain command line..Rouault
P
11

Display only current branch info without using grep:

git branch -vv --contains

This is short for:

git branch -vv --contains HEAD

and if your current HEAD's commit id is in other branches, those branches will display also.

Pauly answered 22/6, 2022 at 14:5 Comment(0)
H
10

Another method (thanks osse), if you just want to know whether or not it exists:

if git rev-parse @{u} > /dev/null 2>&1
then
  printf "has an upstream\n"
else
  printf "has no upstream\n"
fi
Hijoung answered 27/8, 2015 at 17:26 Comment(1)
What language? This looks like a Linux shell script but gives no other information or context.Scone
A
9
git branch -r -vv

will list all branches including remote.

Alundum answered 7/3, 2016 at 2:36 Comment(0)
N
7

You can try this :

git remote show origin | grep "branch_name"

branch_name needs to be replaced with your branch

News answered 3/5, 2019 at 11:18 Comment(3)
What happens if your branch name also matches other branches? What happens your branch name matches some other text in the output of git remote show origin - if it's called merges or configure?Boost
didn't get u. do you mean multiple branches having same namesNews
Examples of "matches other branches": current branch is "foo" but there is also "foobar" that grep will match; current branch is "v3.4" but . in regexp means any character so will also match "v314"...Ansilme
M
6

Lists both local and remote branches:

$ git branch -ra

Output:

  feature/feature1
  feature/feature2
  hotfix/hotfix1
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
Metaphysical answered 15/4, 2019 at 23:30 Comment(0)
P
5

If you want to find the upstream for any branch (as opposed to just the one you are on), here is a slight modification to @cdunn2001's answer:

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

That will give you the remote branch name for the local branch named YOUR_LOCAL_BRANCH_NAME.

Polyzoic answered 22/10, 2018 at 13:43 Comment(1)
git rev-parse --abbrev-ref --symbolic-full-name HEAD@{upstream} Did it for me :)Slaughterhouse
P
4

Having tried all of the solutions here, I realized none of them were good in all situations:

  • works on local branches
  • works on detached branches
  • works under CI

This command gets all names:

git branch -a --contains HEAD --list --format='%(refname:short)'

For my application, I had to filter out the HEAD & master refs, prefer remote refs, and strip off the word 'origin/'. and then if that wasn't found, use the first non HEAD ref that didn't have a / or a ( in it.

Parrotfish answered 25/8, 2020 at 19:7 Comment(0)
D
3

Improving on this answer, I came up with these .gitconfig aliases:

branch-name = "symbolic-ref --short HEAD"
branch-remote-fetch = !"branch=$(git branch-name) && git config branch.\"$branch\".remote || echo origin #"
branch-remote-push  = !"branch=$(git branch-name) && git config branch.\"$branch\".pushRemote || git config remote.pushDefault || git branch-remote-fetch #"
branch-url-fetch = !"remote=$(git branch-remote-fetch) && git remote get-url        \"$remote\" #"  # cognizant of insteadOf
branch-url-push  = !"remote=$(git branch-remote-push ) && git remote get-url --push \"$remote\" #"  # cognizant of pushInsteadOf
Dhoti answered 19/10, 2018 at 16:32 Comment(3)
which language is that?Fitment
@Dan Farrell: shell. Aliases starting with a ! use /bin/sh. The double quotes are quoted for git's config file.Dhoti
Best answer, works for a clone of an empty repository, too. And unlike git status -b --porcelain is quick and parseable.Cadency
G
1

I use this alias

git config --global alias.track '!sh -c "
if [ \$# -eq 2 ]
 then
   echo \"Setting tracking for branch \" \$1 \" -> \" \$2;
   git branch --set-upstream \$1 \$2;
 else
   git for-each-ref --format=\"local: %(refname:short) <--sync--> remote: %(upstream:short)\" refs/heads && echo --URLs && git remote -v;
fi  
" -'

then

git track

note that the script can also be used to setup tracking.

More great aliases at https://github.com/orefalo/bash-profiles

Granitite answered 4/4, 2012 at 15:27 Comment(0)
S
1

Following command will remote origin current fork is referring to

git remote -v

For adding a remote path,

git remote add origin path_name

Stochastic answered 9/7, 2015 at 4:30 Comment(1)
here you are not finding a remote path - you are addingWithdraw
C
0

If you are using Gradle,

def gitHash = new ByteArrayOutputStream()
    project.exec {
        commandLine 'git', 'rev-parse', '--short', 'HEAD'
        standardOutput = gitHash
    }

def gitBranch = new ByteArrayOutputStream()
    project.exec {
        def gitCmd = "git symbolic-ref --short -q HEAD || git branch -rq --contains "+getGitHash()+" | sed -e '2,\$d'  -e 's/\\(.*\\)\\/\\(.*\\)\$/\\2/' || echo 'master'"
        commandLine "bash", "-c", "${gitCmd}"
        standardOutput = gitBranch
    }
Calhoun answered 12/9, 2016 at 18:20 Comment(0)
H
0
git branch -vv | grep 'hardcode-branch-name'
# "git rev-parse --abbrev-ref head" will get your current branch name
# $(git rev-parse --abbrev-ref head) save it as string
#  find the tracking branch by grep filtering the current branch 
git branch -vv | grep $(git rev-parse --abbrev-ref head)
Hiedihiemal answered 8/2, 2022 at 19:57 Comment(1)
A good answer will always include an explanation why this would solve the issue, so that the OP and any future readers can learn from it.Opulence
M
0

This Q4 2023 thread discusses of the edge cases:

  • fresh empty cloned repository
  • or non-existing local branch

it does not work for a fresh clone of an empty repository

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

outputs nothing, while

git status -b --no-ahead-behind --porcelain=v2

outputs

# branch.oid (initial)
# branch.head master
# branch.upstream origin/master

I.e. it outputs a proper upstream branch.

But Jeff King (Peff) replies:

I think it would print "gone" if the upstream branch went missing.
But in this case, the actual local branch is missing. And for-each-ref will not show an entry at all for a ref that does not exist.
The "refs/heads/master" on your command line is not a ref, but a pattern, and that pattern does not match anything. So it's working as intended.

I think a more direct tool would be:

git rev-parse --symbolic-full-name master@{upstream}

That convinces branch_get_upstream() to return the value we want, but, sadly, it seems to get lost somewhere in the resolution process, and we spit out an error. Arguably, that is a bug (with --symbolic or --symbolic-full-name, I think it would be OK to resolve names even if they don't point to something, but it's possible that would have other unexpected side effects).

Mattie answered 14/11, 2023 at 22:38 Comment(0)
S
-5

I use EasyGit (a.k.a. "eg") as a super lightweight wrapper on top of (or along side of) Git. EasyGit has an "info" subcommand that gives you all kinds of super useful information, including the current branches remote tracking branch. Here's an example (where the current branch name is "foo"):

pknotz@s883422: (foo) ~/workspace/bd
$ eg info
Total commits:      175
Local repository: .git
Named remote repositories: (name -> location)
  origin -> git://sahp7577/home/pknotz/bd.git
Current branch: foo
  Cryptographic checksum (sha1sum): bd248d1de7d759eb48e8b5ff3bfb3bb0eca4c5bf
  Default pull/push repository: origin
  Default pull/push options:
    branch.foo.remote = origin
    branch.foo.merge = refs/heads/aal_devel_1
  Number of contributors:        3
  Number of files:       28
  Number of directories:       20
  Biggest file size, in bytes: 32473 (pygooglechart-0.2.0/COPYING)
  Commits:       62
Suspensive answered 5/10, 2008 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.