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...
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.
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 &
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
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 itCredits 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 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>
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.
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.
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
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.
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
Must Read
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.