Home » How to » github – How to clone all remote branches in Git?

github – How to clone all remote branches in Git?

Posted by: admin February 21, 2020 Leave a comment


I have a master and a development branch, both pushed to GitHub. I’ve cloned, pulled, and fetched, but I remain unable to get anything other than the master branch back.

I’m sure I’m missing something obvious, but I have read the manual and I’m getting no joy at all.

How to&Answers:

First, clone a remote Git repository and cd into it:

$ git clone git://example.com/myproject
$ cd myproject

Next, look at the local branches in your repository:

$ git branch
* master

But there are other branches hiding in your repository! You can see these using the -a flag:

$ git branch -a
* master

If you just want to take a quick peek at an upstream branch, you can check it out directly:

$ git checkout origin/experimental

But if you want to work on that branch, you’ll need to create a local tracking branch which is done automatically by:

$ git checkout experimental

and you will see

Branch experimental set up to track remote branch experimental from origin.
Switched to a new branch 'experimental'

That last line throws some people: “New branch” – huh?
What it really means is that the branch is taken from the index and created locally for you. The previous line is actually more informative as it tells you that the branch is being set up to track the remote branch, which usually means the origin/branch_name branch

Now, if you look at your local branches, this is what you’ll see:

$ git branch
* experimental

You can actually track more than one remote repository using git remote.

$ git remote add win32 git://example.com/users/joe/myproject-win32-port
$ git branch -a
* master

At this point, things are getting pretty crazy, so run gitk to see what’s going on:

$ gitk --all &


If you have many remote branches that you want to fetch at once, do:

$ git pull --all

Now you can checkout any branch as you need to, without hitting the remote repository.


This Bash script helped me out:

for branch in $(git branch --all | grep '^\s*remotes' | egrep --invert-match '(:?HEAD|master)$'); do
    git branch --track "${branch##*/}" "$branch"

It will create tracking branches for all remote branches, except master (which you probably got from the original clone command). I think you might still need to do a

git fetch --all
git pull --all

to be sure.

One liner: git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs
As usual: test in your setup before copying rm -rf universe as we know it

Credits for one-liner go to user cfi


Using the --mirror option seems to copy the remote tracking branches properly.
However, it sets up the repository as a bare repository, so you have to turn it back into a normal repository afterwards.

git clone --mirror path/to/original path/to/dest/.git
cd path/to/dest
git config --bool core.bare false
git checkout anybranch

Reference: Git FAQ: How do I clone a repository with all remotely tracked branches?


You can easily switch to a branch without using the fancy “git checkout -b somebranch origin/somebranch” syntax. You can just do:

git checkout somebranch

Git will automatically do the right thing:

$ git checkout somebranch
Branch somebranch set up to track remote branch somebranch from origin.
Switched to a new branch 'somebranch'

Git will check whether a branch with the same name exists in exactly one remote, and if it does, it tracks it the same way as if you had explicitly specified that it’s a remote branch. From the git-checkout man page of Git

If <branch> is not found but there does exist a tracking branch in
exactly one remote (call it <remote>) with a matching name, treat as
equivalent to

$ git checkout -b <branch> --track <remote>/<branch>



$ git checkout -b experimental origin/experimental


$ git checkout -t origin/experimental

or the more verbose but easier to remember

$ git checkout --track origin/experimental

might be better, in terms of tracking a remote repository.


The fetch that you are doing should get all the remote branches, but it won’t create local branches for them. If you use gitk, you should see the remote branches described as “remotes/origin/dev” or something similar.

To create a local branch based on a remote branch, do something like:

git checkout -b dev refs/remotes/origin/dev

Which should return something like:

Branch dev set up to track remote branch refs/remotes/origin/dev.
Switched to a new branch "dev"

Now, when you are on the dev branch, “git pull” will update your local dev to the same point as the remote dev branch. Note that it will fetch all branches, but only pull the one you are on to the top of the tree.


When you do “git clone git://location”, all branches and tags are fetched.

In order to work on top of a specific remote branch, assuming it’s the origin remote:

git checkout -b branch origin/branchname


Use aliases. Though there aren’t any native Git one-liners, you can define your own as

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

and then use it as

git clone-branches


Why you only see “master”

git clone downloads all remote remote branches but still considers them “remote”, even though the files are located in your new repository. There’s one exception to this, which is that the cloning process creates a local branch called “master” from the remote branch called “master”. By default, git branch only shows local branches, which is why you only see “master”.

git branch -a shows all branches, including remote branches.

How to get local branches

If you actually want to work on a branch, you’ll probably want a “local” version of it. To simply create local branches from remote branches (without checking them out and thereby changing the contents of your working directory), you can do that like this:

git branch branchone origin/branchone
git branch branchtwo origin/branchtwo
git branch branchthree origin/branchthree

In this example, branchone is the name of a local branch you’re creating based on origin/branchone; if you instead want to create local branches with different names, you can do this:

git branch localbranchname origin/branchone

Once you’ve created a local branch, you can see it with git branch (remember, you don’t need -a to see local branches).


This isn’t too much complicated, very simple and straight forward steps are as follows;

git fetch origin This will bring all the remote branches to your local.

git branch -a This will show you all the remote branches.

git checkout --track origin/<branch you want to checkout>

Verify whether you are in the desired branch by the following command;

git branch

The output will like this;

*your current branch 
some branch2
some branch3 

Notice the * sign that denotes the current branch.


Better late than never, but here is the best way to do this:

mkdir repo
cd repo
git clone --bare path/to/repo.git .git
git config --unset core.bare
git reset --hard

At this point you have a complete copy of the remote repo with all of it’s branches (verify with git branch). You can use --mirror instead of --bare if your remote repo has remotes of its own.


Just do this:

$ git clone git://example.com/myproject
$ cd myproject
$ git checkout branchxyz
Branch branchxyz set up to track remote branch branchxyz from origin.
Switched to a new branch 'branchxyz'
$ git pull
Already up-to-date.
$ git branch
* branchxyz
$ git branch -a
* branchxyz
  remotes/origin/HEAD -> origin/master

You see, ‘git clone git://example.com/myprojectt’ fetches everything, even the branches, you just have to checkout them, then your local branch will be created.


You only need to use “git clone” to get all branches.

git clone <your_http_url>

Even though you only see master branch, you can use “git branch -a” to see all branches.

git branch -a

And you can switch to any branch which you already have.

git checkout <your_branch_name>

Don’t worry that after you “git clone”, you don’t need to connect with the remote repo, “git branch -a” and “git checkout ” can be run successfully when you close your wifi. So it is proved that when you do “git clone”, it already has copied all branches from the remote repo. After that, you don’t need the remote repo, your local already has all branches’ codes.


A git clone is supposed to copy the entire repository. Try cloning it, and then run git branch -a. It should list all the branches. If then you want to switch to branch “foo” instead of “master”, use git checkout foo.


Use my tool git_remote_branch (you need Ruby installed on your machine). It’s built specifically to make remote branch manipulations dead easy.

Each time it does an operation on your behalf, it prints it in red at the console. Over time, they finally stick into your brain 🙂

If you don’t want grb to run commands on your behalf, just use the ‘explain’ feature. The commands will be printed to your console instead of executed for you.

Finally, all commands have aliases, to make memorization easier.

Note that this is alpha software 😉

Here’s the help when you run grb help:

git_remote_branch version 0.2.6


  grb create branch_name [origin_server] 

  grb publish branch_name [origin_server] 

  grb rename branch_name [origin_server] 

  grb delete branch_name [origin_server] 

  grb track branch_name [origin_server] 

  - If origin_server is not specified, the name 'origin' is assumed 
    (git's default)
  - The rename functionality renames the current branch

  The explain meta-command: you can also prepend any command with the 
keyword 'explain'. Instead of executing the command, git_remote_branch 
will simply output the list of commands you need to run to accomplish 
that goal.

    grb explain create
    grb explain create my_branch github

  All commands also have aliases:
  create: create, new
  delete: delete, destroy, kill, remove, rm
  publish: publish, remotize
  rename: rename, rn, mv, move
  track: track, follow, grab, fetch


all the answers I saw here are valid but there is a much cleaner way to clone a repository and to pull all the branches at once.

When you clone a repository all the information of the branches is actually downloaded but the branches are hidden. With the command

$ git branch -a

you can show all the branches of the repository, and with the command

$ git checkout -b branchname origin/branchname

you can then “download” them manually one at a time.

However, when you want to clone a repo with a lot of branches all the ways illustrated are above are lengthy and tedious in respect to a much cleaner and quicker way that I am going to show, though it’s a bit complicated. You need three steps to accomplish this:

  1. First step

create a new empty folder on your machine and clone a mirror copy of the .git folder from the repository:

$ cd ~/Desktop && mkdir my_repo_folder && cd my_repo_folder
$ git clone --mirror https://github.com/planetoftheweb/responsivebootstrap.git .git

the local repository inside the folder my_repo_folder is still empty, there is just a hidden .git folder now that you can see with a “ls -alt” command from the terminal.

  1. Second step

switch this repository from an empty (bare) repository to a regular repository by switching the boolean value “bare” of the git configurations to false:

$ git config --bool core.bare false
  1. Third Step

Grab everything that inside the current folder and create all the branches on the local machine, therefore making this a normal repo.

$ git reset --hard

So now you can just type the command “git branch” and you can see that all the branches are downloaded.

This is the quick way in which you can clone a git repository with all the branches at once, but it’s not something you wanna do for every single project in this way.


Cloning from a local repo will not work with git clone & git fetch: a lot of branches/tags will remain unfetched.

To get a clone with all branches and tags.

git clone --mirror git://example.com/myproject myproject-local-bare-repo.git

To get a clone with all branches and tags but also with a working copy:

git clone --mirror git://example.com/myproject myproject/.git
cd myproject
git config --unset core.bare
git config receive.denyCurrentBranch updateInstead
git checkout master


OK, when you clone your repo, you have all branches there…

If you just do git branch, they are kind of hidden…

So if you’d like to see all branches name, just simply add --all flag like this:

git branch --all or git branch -a

If you just checkout to the branch, you get all you need.

But how about if the branch created by someone else after you clone?

In this case, just do:

git fetch

and check all branches again…

If you like to fetch and checkout at the same time, you can do:

git fetch && git checkout your_branch_name

Also created the image below for you to simplify what I said:

git branch --all to get all branches


Looking at one of answers to the question I noticed that it’s possible to shorten it:

for branch in  `git branch -r | grep -v 'HEAD\|master'`; do  
 git branch --track ${branch##*/} $branch;

But beware, if one of remote branches is named as e.g. admin_master it won’t get downloaded!

Thanks to bigfish for original idea


for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch

These code will pull all remote branches code to local repo.


For copy-paste into command line:

git checkout master ; remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch -D $brname ; git checkout -b $brname $remote/$brname ; done ; git checkout master

For more readibility:

git checkout master ;
remote=origin ;
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do
    git branch -D $brname ;
    git checkout -b $brname $remote/$brname ;
done ;
git checkout master

This will:

  1. check out master (so that we can delete branch we are on)
  2. select remote to checkout (change it to whatever remote you have)
  3. loop through all branches of the remote except master and HEAD
    1. delete local branch (so that we can check out force-updated branches)
    2. check out branch from the remote
  4. check out master (for the sake of it)

Based on answer of VonC.


I wrote this small Powershell functions to be able to checkout all my git branches, that are on origin remote.

Function git-GetAllRemoteBranches {
     iex "git branch -r"                       <# get all remote branches #> `
     | % { $_ -Match "origin\/(?'name'\S+)" }  <# select only names of the branches #> `
     | % { Out-Null; $matches['name'] }        <# write does names #>

Function git-CheckoutAllBranches {
    git-GetAllRemoteBranches `
        | % { iex "git checkout $_" }          <# execute ' git checkout <branch>' #>

More git functions can be found on my git settings repo


I needed to do exactly the same. Here is my Ruby script.

#!/usr/bin/env ruby

local = []
remote = {}

# Prepare
%x[git reset --hard HEAD]
%x[git checkout master] # Makes sure that * is on master.
%x[git branch -a].each_line do |line|
  if /origin\//.match(line)
     remote[line.gsub(/origin\//, '')] = line
     local << line
# Update 
remote.each_pair do |loc, rem|
  next if local.include?(loc)
  %x[git checkout --track -b #{loc} #{rem}]
%x[git fetch]


None of these answers cut it, except user nobody is on the right track.

I was having trouble with moving a repo from one server/system to another. When I cloned the repo, it only created a local branch for master so when I pushed to the new remote, only master branch was pushed.

So I found these two methods VERY useful. Hope they help someone else.

Method 1:

git clone --mirror OLD_REPO_URL
cd new-cloned-project
mkdir .git
mv * .git
git config --local --bool core.bare false
git reset --hard HEAD
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

Method 2:

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
git clone OLD_REPO_URL
cd new-cloned-project
git clone-branches
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo


Here’s an answer that uses awk. This method should suffice if used on a new repo.

git branch -r | awk -F/ '{ system("git checkout " $NF) }'

Existing branches will simply be checked out, or declared as already in it, but filters can be added to avoid the conflicts.

It can also be modified so it calls an explicit git checkout -b <branch> -t <remote>/<branch> command.

This answer follows Nikos C.‘s idea.

Alternatively we can specify the remote branch instead. This is based on murphytalk‘s answer.

git branch -r | awk '{ system("git checkout -t " $NF) }'

It throws fatal error messages on conflicts but I see them harmless.

Both commands can be aliased.

Using nobody‘s answer as reference, we can have the following commands to create the aliases:

git config --global alias.clone-branches '! git branch -r | awk -F/ "{ system(\"git checkout \" $NF) }"'
git config --global alias.clone-branches '! git branch -r | awk "{ system(\"git checkout -t \" $NF) }"'

Personally I’d use track-all or track-all-branches.


Git usually (when not specified) fetches all branches and/or tags (refs, see: git ls-refs) from one or more other repositories along with the objects necessary to complete their histories. In other words it fetches the objects which are reachable by the objects that are already downloaded. See: What does git fetch really do?

Sometimes you may have branches/tags which aren’t directly connected to the current one, so git pull --all/git fetch --all won’t help in that case, but you can list them by:

git ls-remote -h -t origin

and fetch them manually by knowing the ref names.

So to fetch them all, try:

git fetch origin --depth=10000 $(git ls-remote -h -t origin)

The --depth=10000 parameter may help if you’ve shallowed repository.

Then check all your branches again:

git branch -avv

If above won’t help, you need to add missing branches manually to the tracked list (as they got lost somehow):

$ git remote -v show origin
  Remote branches:
    master      tracked

by git remote set-branches like:

git remote set-branches --add origin missing_branch

so it may appear under remotes/origin after fetch:

$ git remote -v show origin
  Remote branches:
    missing_branch new (next fetch will store in remotes/origin)
$ git fetch
From github.com:Foo/Bar
 * [new branch]      missing_branch -> origin/missing_branch


If you still cannot get anything other than the master branch, check the followings:

  • Double check your remotes (git remote -v), e.g.
    • Validate that git config branch.master.remote is origin.
    • Check if origin points to the right URL via: git remote show origin (see this post).


As of early 2017, the answer in this comment works:

git fetch <origin-name> <branch-name> brings the branch down for you. While this doesn’t pull all branches at once, you can singularly execute this per-branch.


git clone --mirror on the original repo works well for this.

git clone --mirror /path/to/original.git
git remote set-url origin /path/to/new-repo.git
git push -u origin


Here is another short one-liner command which
creates local branches for all remote branches:

(git branch -r | sed -n '/->/!s#^  origin/##p' && echo master) | xargs -L1 git checkout

It works also properly if tracking local branches are already created.
You can call it after the first git clone or any time later.

If you do not need to have master branch checked out after cloning, use

git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout