How to Clone All Remote Branches in Git

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.

13

45 Answers

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

$ git clone git://
$ 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
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

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'

Here, "new branch" simply means that the branch is taken from the index and created locally for you. As the previous line tells you, 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
  master

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

$ git remote add win32 git://
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental
  remotes/win32/master
  remotes/win32/new-widgets

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

$ gitk --all &
28

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.


Note: This will not create working copies of any non-checked out branches, which is what the question was asking. For that, see

15

This Bash script helped me out:

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

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

17

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?

19

You can easily switch to a branch without using the fancy "git checkout -b somebranch origin/somebranch" syntax. You can 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 1.8.2.1:

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

Regarding,

git checkout -b experimental origin/experimental

using

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.

1

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.

4

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
1

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 repository with all of its branches (verify with git branch). You can use --mirror instead of --bare if your remote repository has remotes of its own.

9

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
4

Why you only see "master"

git clone downloads all 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.


Sophia Al-Mansoor

Sophia Al-Mansoor

Global Business & E-Commerce Reporter

Sophia analyzes international trade, startup ecosystems, retail transformation, and supply chain logistics for modern digital publications.