Categories
branch git git-branch

How do I fetch all Git branches?

2061

I cloned a Git repository containing many branches. However, git branch only shows one:

$ git branch
* master

How would I pull all the branches locally so when I do git branch, it shows the following?

$ git branch
* master
* staging
* etc...

10

  • 1

    Also discussed at stackoverflow.com/questions/67699/…

    – gliptak

    Sep 25, 2012 at 14:40

  • 2

    This question shows how to get all branches after using the --single-branch setting when cloning: stackoverflow.com/questions/17714159/… (git fetch --all will never work if you’ve specified only one branch!)

    May 21, 2015 at 17:10

  • 3

    You will not see that output ever because the asterisk represents the branch that is currently checkout out. Since you can only have one branch checked out at once, you can have only one asterisk on the left of your branch listing.

    – Robino

    Dec 7, 2015 at 15:09

  • 7

    I saw a lot of answers but none of them mentioned what I think is probably the easiest way to do what you want: git clone --bare <repo url> .git (notice you need to add “–bare” and “.git” at the end to clone the repo as a “bare” repo), then git config --bool core.bare false (sets the “bare” flag to false), then git reset --hard (moves the HEAD to current HEAD on the repo). Now if you git branch you should see all branches from the repo you cloned.

    Mar 25, 2017 at 17:37


  • 5

    @GabrielFerraz Then you are abusing the comment functionality on Stack Overflow. Users can upvote your comment but not downvote.

    – pipe

    Sep 7, 2017 at 14:40

2782

TL;DR answer

git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all

(It seems that pull fetches all branches from all remotes, but I always fetch first just to be sure.)

Run the first command only if there are remote branches on the server that aren’t tracked by your local branches.

Complete answer

You can fetch all branches from all remotes like this:

git fetch --all

It’s basically a power move.

fetch updates local copies of remote branches so this is always safe for your local branches BUT:

  1. fetch will not update local branches (which track remote branches); if you want to update your local branches you still need to pull every branch.

  2. fetch will not create local branches (which track remote branches), you have to do this manually. If you want to list all remote branches:
    git branch -a

To update local branches which track remote branches:

git pull --all

However, this can be still insufficient. It will work only for your local branches which track remote branches. To track all remote branches execute this oneliner BEFORE git pull --all:

git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

P.S. AFAIK git fetch --all and git remote update are equivalent.



Kamil Szot’s comment, which folks have found useful.

I had to use:

for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done

because your code created local branches named origin/branchname and
I was getting “refname ‘origin/branchname’ is ambiguous whenever I
referred to it.

37

  • 47

    Sorry. I can’t imagine that this is what the OP actually wants. The ‘pull’ command is ‘fetch+merge’ and the merge part will overlay all the branches on top of one another – leaving one giant mess.

    – GoZoner

    Apr 25, 2012 at 14:06

  • 13

    that fetch wouldn’t create a new remote branch you still need to check it out with git checkout -b localname remotename/remotebranch

    – Learath2

    Oct 20, 2012 at 17:06

  • 143

    I had to use for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done because your code created local branches named origin/branchname and I was getting “refname ‘origin/branchname’ is ambiguous whenever I referred to it.

    Sep 22, 2013 at 23:46


  • 24

    I don’t know if I’m using a different version of GIT, but I had to amend the script to git pull --all; for remote in `git branch -r | grep -v \>`; do git branch --track ${remote#origin/} $remote; done. The change strips out HEAD.

    – kim3er

    Sep 29, 2013 at 13:16


  • 18

    For the Windows folks: for /F %remote in ('git branch -r') do ( git branch --track %remote) && git fetch --all && git pull --all

    – Max

    Dec 20, 2013 at 6:03


1055

To list remote branches:

git branch -r

To checkout a remote branch as a local branch:

git checkout -b local_branch_name origin/remote_branch_name

13

  • 128

    This is exactly what I was looking for when I found the question above. I suspect many people looking for how to pull a remote branch definitely don’t want to merge the branch into their current working copy, but they do want a local branch identical to the remote one.

    – Frug

    Oct 19, 2012 at 16:03

  • 23

    Even if the branch is not visible locally, I can do git checkout remotebranchnameand it works. what’s the difference with your solution?

    Nov 6, 2014 at 10:43

  • 21

    Its default behaviour now. Wasn’t the case on older git versions. Using git checkout remotebranchname used to just create a new unrelated branch that is named remotebranchname.

    – Learath2

    Nov 15, 2014 at 13:10

  • 18

    The accepted answer does something fundamentaly different and to be frank I don’t even understand why its the accepted answer

    – Learath2

    Jul 23, 2015 at 16:28

  • 19

    The OP asked for all branches. This answer only does one.

    Aug 5, 2016 at 15:19

215

You will need to create local branches tracking remote branches.

Assuming that you’ve got only one remote called origin, this snippet will create local branches for all remote tracking ones:

for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

After that, git fetch --all will update all local copies of remote branches.

Also, git pull --all will update your local tracking branches, but depending on your local commits and how the ‘merge’ configure option is set it might create a merge commit, fast-forward or fail.

5

  • 6

    This robustifies the solution against branch names containing shell metacharacters (as per pinkeen’s comment on the other answer), and avoids spurious error output: git branch -r | grep -v — ‘ -> ‘ | while read remote; do git branch –track “${remote#origin/}” “$remote” 2>&1 | grep -v ‘ already exists’; done

    Aug 11, 2015 at 23:28


  • 10

    Are you sure that git pull --all will update all local tracking branches? As far as I can tell it only updates the current branch from all remotes.

    – Andy

    Jul 26, 2016 at 16:07

  • 4

    Did this. Local branches matching remote branches were not created. What is the git command that simply says “pull all remote branches creating local ones if they do not exist?”

    – JosephK

    Feb 11, 2017 at 10:47

  • @JosephK perhaps your remote is not called origin? See this answer which will work on all remote names.

    – Tom Hale

    Sep 14, 2018 at 15:53

  • @TomHale It was “origin,” but thanks for your answer – though crazy that much is necessary to do what should be one or maybe two flags. I am now trying gitless, to try to avoid the insanity of some aspects of git.

    – JosephK

    Dec 10, 2018 at 7:33