1208

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?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
readonly
  • 343,444
  • 107
  • 203
  • 205
  • 39
    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. – cdunn2001 Nov 18 '12 at 08:38
  • 8
    Agreed, this definitely shouldn't be a dupe. It's asking something completely different than the linked question – Adam Batkin Feb 21 '13 at 03:32

25 Answers25

1374

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

mtyurt
  • 3,369
  • 6
  • 38
  • 57
jdsumsion
  • 14,473
  • 1
  • 15
  • 9
  • 9
    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 remote – SimplGy Jul 24 '13 at 02:18
  • 14
    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. – UpAndAdam Apr 24 '15 at 17:52
  • The output of this command can be misleading since a commit message may easily begin with for example "[my-feature] ...". Please see @cdunn2001 's answer that shows only the upstream branch (if any) and nothing else. – Jonas Berlin Jul 03 '15 at 16:11
  • 1
    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 output – jdsumsion Mar 22 '16 at 19:11
  • git branch -vv | grep '*' – Swastik Padhi Nov 14 '17 at 07:42
  • 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 master` – Murmel Nov 21 '18 at 09:51
490

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
cdunn2001
  • 17,657
  • 8
  • 55
  • 45
  • 14
    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`. – Tino Nov 17 '12 at 15:27
  • 1
    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? – scicalculator Dec 04 '12 at 07:00
  • 1
    Awesome! Can you point me at the docs where the @{u} comes into play? Not familiar and would love to understand that better. – Matthew Ward Feb 13 '13 at 18:57
  • 13
    `git help revisions` (one of the little-known but most useful parts of the docs) and search for `upstream`. – cdunn2001 Feb 14 '13 at 05:38
  • 1
    Is this supposed to work in Windows? I am getting this error in PowerShell: `Missing '=' operator after key in hash literal.` – pilau Jul 31 '13 at 10:21
  • @pilau, I think you need to escape the `%`. – cdunn2001 Aug 02 '13 at 15:30
  • 1
    The PowerShell escape character is [backtick](http://www.techotopia.com/index.php/Windows_PowerShell_1.0_String_Quoting_and_Escape_Sequences), not backslash. Maybe that will help. If you find the real solution, please post it! – cdunn2001 Aug 03 '13 at 01:09
  • 18
    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}\`` – Jian May 09 '14 at 08:36
  • 2
    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-upstream` – albfan Jul 19 '14 at 18:43
  • 8
    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 branch – Jonas Berlin Jul 03 '15 at 16:19
  • 2
    One important thing to remember is that the tracking branch does not necessarily have to be a remote branch. – Jonas Berlin Jul 03 '15 at 16:23
  • 1
    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/null` – regulus Jan 27 '16 at 01:58
  • 1
    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)"` – Trendfischer May 02 '19 at 14:48
  • @Tino ugly errors? I get `fatal: no upstream configured for branch ''` , 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) – ijoseph Aug 15 '19 at 23:07
  • 1
    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://stackoverflow.com/a/32888639/1411958 – BhaveshDiwan Oct 23 '20 at 05:13
  • 1
    Thank you for this. Been looking for a simple way to print the branch-name for @{u}, @{-1} , and HEAD for ages. – dovidweisz Jun 14 '21 at 14:39
250

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)
Ajit George
  • 3,239
  • 1
  • 19
  • 10
  • 5
    I need a command that *discovers* the upstream branch, so using 'origin' as input is making an assumption, so this does not work for me – Alexander Mills Mar 13 '16 at 08:01
  • 2
    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. – dudewad Feb 22 '18 at 23:17
  • 2
    @dudewad 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). – Ruslan Oct 15 '19 at 08:45
97

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#gitrevisions-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
user151841
  • 17,377
  • 29
  • 109
  • 171
Aaron Wells
  • 1,135
  • 7
  • 5
  • 3
    This was very useful in making an alias to rebase whatever my current branch is. Thanks! – Justin Spahr-Summers Jan 17 '12 at 08:19
  • 1
    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. – Altreus Jul 25 '12 at 10:02
  • 7
    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' ' -f2` – Altreus Jul 25 '12 at 11:41
  • 2
    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. – Dan M. Oct 15 '17 at 01:27
  • 2
    `@{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. – Chris Cleeland Apr 04 '18 at 16:27
  • Better than `git name-rev` to determine LOCAL_BRANCH is `LOCAL_BRANCH=$(git symbolic-ref -q HEAD)` (as shown in @rubo77's answer) – qneill Sep 05 '18 at 15:15
  • 1
    Use `symbolic-ref --short HEAD` for a single word to describe the current branch. – Tom Hale Oct 19 '18 at 15:32
  • **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..insteadOf`. See [this answer](https://stackoverflow.com/a/52896538/5353461) for the resolution. – Tom Hale Oct 19 '18 at 16:36
  • 1
    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. – xiay Mar 10 '22 at 20:12
61

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}
nikkypx
  • 1,925
  • 17
  • 12
  • 1
    This is the correct answer. For example `git remote show origin` actually does show the url of my remote. – kingaj Jul 07 '20 at 23:25
  • @kingaj 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 me – nhed May 06 '21 at 15:50
  • @nhed the pattern in [post below](https://stackoverflow.com/a/40630957/3495504) answer might help. I just tried it and it worked pretty well. – the-typist May 07 '21 at 16:42
  • @the-typist 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 `origin` – nhed May 09 '21 at 00:52
38

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.

  • 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 message'` if there is a tracked branch `* 'BRANCH_NAME' ['TRACKED_BRANCH_NAME']'commit message'` – TMin Feb 02 '22 at 18:58
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
rubo77
  • 19,527
  • 31
  • 134
  • 226
  • Shortcut for the last one: `git remote get-url $(git for-each-ref --format='%(upstream:remotename)' $(git symbolic-ref -q HEAD))` – elboulangero Feb 02 '23 at 02:40
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'.
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
21

Yet another way

git status -b --porcelain

This will give you

## BRANCH(...REMOTE)
modified and untracked files
FragLegs
  • 424
  • 3
  • 4
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
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 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. – Anakhand Nov 16 '19 at 00:59
  • 1
    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).url` – Nelson Apr 24 '20 at 19:14
19

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).

AndiDog
  • 68,631
  • 21
  • 159
  • 205
  • 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. – Michał Góral Jan 13 '22 at 11:20
11

Another simple way is to use

cat .git/config in a git repo

This will list details for local branches

rayryeng
  • 102,964
  • 22
  • 184
  • 193
Trickmaster
  • 187
  • 2
  • 5
10

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.

PhillipMcCubbin
  • 495
  • 1
  • 4
  • 10
9

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
Wayne Walker
  • 2,316
  • 3
  • 23
  • 25
9
git branch -r -vv

will list all branches including remote.

Undo
  • 25,519
  • 37
  • 106
  • 129
7

You can try this :

git remote show origin | grep "branch_name"

branch_name needs to be replaced with your branch

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
xpioneer
  • 3,075
  • 2
  • 16
  • 18
  • 1
    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`? – Tom Swirly Jul 20 '19 at 14:25
  • didn't get u. do you mean multiple branches having same names – xpioneer Jul 23 '19 at 09:03
  • 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"... – Beni Cherniavsky-Paskin Jun 18 '20 at 17:40
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
joseluisq
  • 508
  • 1
  • 7
  • 19
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.

Jeremy Thomerson
  • 722
  • 2
  • 8
  • 19
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.

Erik Aronesty
  • 11,620
  • 5
  • 64
  • 44
2

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
Tom Hale
  • 40,825
  • 36
  • 187
  • 242
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

Olivier Refalo
  • 50,287
  • 22
  • 91
  • 122
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

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
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ravikanth
  • 151
  • 1
  • 10
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)
Fred Yang
  • 2,521
  • 3
  • 21
  • 29
  • 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. – Tyler2P Feb 13 '22 at 16:38
-3

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
Nathan Musoke
  • 166
  • 1
  • 12
Pat Notz
  • 208,672
  • 30
  • 90
  • 92