4813

My master and development branches are tracked remotely on GitHub. How do I clone both these branches?

14
  • 163
    The accepted answer here (git branch -a) shows you the branches in the remote, but if you attempt to check any of those out you will be in a 'detached HEAD' state. The next answer down (second most upvotes) answers a different question (to wit: how to pull all branches, and, again, this only works for those you're tracking locally). Several of the comments point out that you could parse the git branch -a results with a shell script that would locally track all the remote branches. Summary: There's no git native way to do what you want and it might not be all that great an idea anyway. Commented Jun 18, 2012 at 22:43
  • 6
    Maybe just copy the entire folder the old fashioned way? scp [email protected]:/home/some_user/project_folder ~ Not sure if that solution works for github though.. Commented Sep 26, 2012 at 22:51
  • 26
    Rather than saying "I've cloned, pulled, and fetched," much better to show us the exact commands that you executed. Commented Nov 22, 2013 at 18:17
  • 99
    It always boggles me why "clone" isn't in the sense of an exact copy. If it's an exact clone, shouldn't all the branches be part of the local repository? I mean isn't that one of the point of being distributed? So when something repository is gone you still have a complete copy of everything. Or is it the so called "remote" really are part of the local repository already?
    – huggie
    Commented Jul 11, 2016 at 6:31
  • 38
    Seeing all the upvotes, answers, comments on answers and the mind-boggling number of views, I think it is time git added a command for doing this. And right you are @huggie, my thoughts exactly. Commented Aug 29, 2016 at 4:29

50 Answers 50

5214

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! See these using the -a flag:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

To take a quick peek at an upstream branch, check it out directly:

$ git checkout origin/experimental

To work on that branch, create a local tracking branch, which is done automatically by:

$ git checkout experimental

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.

Your local branches should now show:

$ git branch
* experimental
  master

You can 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
  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
  • 158
    How can someone create automatically all the remote branches, e.g. experimental for origin/experimental? Commented Jun 4, 2009 at 16:33
  • 64
    Cristian: I used to always create a branch 'foo' for every branch 'origin/foo', but this led to two problems: (1) I wound up with lots of really stale tracking branches that were many commits behind the corresponding remote branch, and (2) in older versions of git, running 'git push' would attempt to push all my local branches to a remote, even when those branches were stale. So now I only keep local branches for things that I'm actively developing, and access the origin/* branches directly if I need information about them. (That said, you could use a shell script to parse 'git branch -a'.)
    – emk
    Commented Jul 20, 2009 at 21:44
  • 52
    "git fetch <origin-name> <branch-name>" brings the branch down locally for you.
    – user67627
    Commented Feb 7, 2010 at 17:10
  • 176
    Good answer, but kinda misses the question. I was looking for a one-liner to checkout all the remote branches.
    – cmcginty
    Commented Oct 19, 2010 at 21:01
  • 36
    The question was about cloning all remote branches, not checking them out. And, as I noted above, you really don't want to make any more local tracking branches than necessary, because when they get really stale, they can cause headaches.
    – emk
    Commented Oct 28, 2010 at 12:43
941

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

14
  • 13
    If I do git clone, I have the master branch locally and 10 branches "remote". So THIS answer by Gabe was very helpful and answers the question.
    – basZero
    Commented Jan 27, 2012 at 19:07
  • 57
    this only fetch remote branches that have been locally added not any remote branch
    – jujule
    Commented Feb 10, 2012 at 11:45
  • 6
    After I did git remote update, then tried git branch, I only see local branches. But if I do git branch -a I can now see the remote branches and I can do a git pull <branchname> to get the branch I want. -- I landed on this question from a Google search, and this answer solves my problem. Commented Jan 31, 2013 at 16:47
  • 68
    This is not helpful at all, doesn't pull any remote branches other than that is existing.
    – Avinash R
    Commented Apr 11, 2013 at 15:02
  • 15
    It's not the first time when an answer that is simply wrong because it doesn't answer the question gets hundreds of upvotes from people who either didn't understood questions and/or answer, or landed by google for searching something other as the original OPs problem and such 'answer' have accidentally answered their problem. Unfortunately there's no valid flag for answer that do not answer the question, the only way is downvoting, which obviously doesn't work in some cases, so such noise is about to stay forever :(
    – user5479362
    Commented Apr 10, 2018 at 14:43
565

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

22
  • 28
    This is really close to being a perfect solution.. The only thing that would make it better is if this functionality were built-in as an option in git. Commented Oct 27, 2011 at 17:15
  • 68
    "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
    – cfi
    Commented Sep 18, 2012 at 12:38
  • 7
    This command creates the feature branches from remote as normal branches (not feature branches) - how to fix this?
    – Alex2php
    Commented Mar 20, 2014 at 14:31
  • 6
    if you run into issues with "/" in branch names there is a solution below using a git alias. see answer by "nobody" on "answered May 15 '13 at 11:02"
    – wemu
    Commented Jan 12, 2015 at 11:54
  • 14
    I'm trimming just remotes/origin/ to preserve namespaces: for BRANCH in $(git branch -a | grep remotes | grep -v HEAD | grep -v master); do git branch --track "${BRANCH#remotes/origin/}" "${BRANCH}"; done
    – kgadek
    Commented Jul 2, 2015 at 8:33
524

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?

21
  • 8
    You know this actually seems to be a pretty good answer even though it has no votes. Are there any pitfalls to doing it that way? I had to explicitly checkout a branch after running those commands.
    – loop
    Commented Jan 12, 2012 at 4:25
  • 49
    This combined with git push --mirror are exactly what I needed to create an exact duplicate of a remote git repo when moving from github.com to a github enterprise install. Thanks!
    – Jacob Fike
    Commented Sep 11, 2012 at 22:59
  • 7
    @Dave: Add a final git checkout as last command to finally checkout the head of the current branch on the cloned repo. This is a great answer, by far the best. Be brave, eventually we'll get you to the top :-)
    – cfi
    Commented Sep 18, 2012 at 7:37
  • 9
    git clone --mirror is very good for backing up your git repositories ^_^
    – TrinitronX
    Commented May 20, 2013 at 21:19
  • 5
    When using these steps, my CLI changes from [master] to [GIT_DIR!], and the final checkout doesn't work. UPDATE: I made a mistake. I cloned into /path/to/dest.git - it should have been /path/to/dest/.git. Then when I unconfig'd bare mode, my CLI said [master +0 ~0 -116 ~] but upon git checkout master, it did a bunch of work, but came out the other side as [master], so it looks like success! Commented Aug 15, 2017 at 20:15
248

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
  • 2
    So, if the name of the branch you checkout is the identical to the name of the remote branch, everything after the "/", then git will create a branch of the same name, everything after the "/", "tracking" that remote? And by tracking, we mean: git push, git pull, etc. will be done on that remote? If this is correct, then expand on your answer with more information, because I aggree with @Daniel, this answer deserves more rep. Commented Jun 14, 2012 at 22:08
  • 5
    @BullfrogBlues, the answer to all your questions appears to be yes (I'm using git v1.7.7.4). I agree this behavior should be better known. (It's not in the manual for this version of git.) I actually don't like this behavior, I'd rather get an error and have to say git checkout --track origin/somebranch explicitly.
    – dubiousjim
    Commented Jul 3, 2012 at 13:05
  • 4
    @dubiousjim: Actually, this is in the manual. git-checkout(1) says: "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 V.1.8.1.1).
    – sleske
    Commented Feb 27, 2013 at 9:01
  • 1
    What we need is $ git pull * <remote>/* - where "*" is a wildcard, so it pulls all branches, including those not yet on the local system. How to do this? Are we really supposed to checkout/pull every branch just to get the code pulled to our local system?
    – JosephK
    Commented Feb 19, 2017 at 5:27
  • 1
    This does not answer the question at all. Commented Jan 16, 2022 at 21:56
102

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.

0
96

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
3
  • 3
    Thanks. This actually clones all remote branches unlike several of the other answers Commented May 14, 2020 at 10:22
  • 1
    Note that Windows users will need to set the alias in the git bash shell but that once set it will work in cmd & ps shells. This is due to the differences in quoting, escaping and the availability of sed in Windows. It works once set because all git commands are actually executed in the bash environment. Commented Nov 8, 2022 at 5:04
  • This worked for me when several other answers didn't. Afteward, git branch shows all the PRs that are in the original git repository
    – fivestones
    Commented Mar 5, 2023 at 9:11
83

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
  • 16
    You don't need refs/remotes here. git checkout -b dev origin/dev will work fine.
    – emk
    Commented Sep 17, 2008 at 13:10
  • 4
    This will always work: git checkout -b newlocaldev --track origin/dev. If you want the local branch has the same name as the remote one, and the remote one doesn't have a tricky name, you can omit the -b newlocaldev. With the default branch.autosetupmerge config setting, and assuming you don't have a local branch named dev, these two commands may do the same thing: git checkout -b dev origin/dev and just plain git checkout dev. Finally, git checkout origin/dev doesn't create a new branch, but just puts you in detached HEAD state.
    – dubiousjim
    Commented Jul 3, 2012 at 13:27
  • What happens when the remote no longer exists but Git is too stupid to acknowledge its been deleted? This assumes you updated and git branch -a continues to lists it as a remote branch.
    – jww
    Commented Sep 19, 2016 at 22:14
  • 2
    And we do this for dozens of branches?
    – JosephK
    Commented Feb 19, 2017 at 5:28
77

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.

10
  • Something went wrong during the edits here. Now this answer doesn't make sense. The "--bare" mentioned in the last sentence doesn't exist in the given command list.
    – Cerran
    Commented Mar 5, 2014 at 13:11
  • 1
    taking from Dave's answer below. Using 'git config --bool core.bare false' instead of 'git config unset core.bare' seems to do the job. Commented Oct 28, 2014 at 12:25
  • 1
    It's git config --unset core.bare actually... To me, this seems the cleanest solution of all presented in the answers here. A pity it has so few upvotes... Commented May 10, 2017 at 8:05
  • 1
    Thanks @ChrisSim I agree for git config --bool core.bare false. This is why I recommend instead the Dave's answer. What do you think about the Dave's answer? Cheers
    – oHo
    Commented Jun 29, 2017 at 8:24
  • 4
    This is absolutely the best answer, except that @FedericoCapaldo gave an answer that goes into a little more detail about exactly what these commands are doing. Commented Aug 5, 2017 at 13:59
63

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
  • 4
    I appreciate your note "all branches and tags are fetched". I was going to comment on your answer being wrong, but then I checked it and found, you are perfectly right. So in a way, you have provided the shortest answer - if you cloned, you already have it. Nice. One could try to add: try $ git branch -a to learn, what remote branches are already available. Commented Nov 17, 2013 at 22:39
  • Have a look at the answer I posted as well. This might be helpful if you know you'll want to be working locally on many of the remote branches and not have to check them out one by one. Commented Dec 8, 2018 at 15:39
  • 1
    Can you explain to me what's the difference between git checkout -b master origin/master and git checkout --track origin/master please ?
    – aderchox
    Commented Jul 18, 2019 at 15:08
  • 2
    @aderchox Nowadays, I think none.
    – elmarco
    Commented Aug 2, 2019 at 10:05
63

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.


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

2
  • 1
    If origin/branchone exists, you can also just use git checkout branchone to create a local branch with the same name and set it to track remote.
    – Evan
    Commented May 15, 2020 at 20:38
  • only answer which worked
    – afsara_ben
    Commented Nov 8, 2022 at 21:24
54

This isn't too complicated. Very simple and straightforward 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.

4
  • 1
    Thanks suraj. The reason because its not been voted much. And the ans is not accepted by the questioner.
    – Sam
    Commented Jun 8, 2015 at 11:03
  • The "git fetch origin" did not bring any of the remote branches to my local - or are they hidden somewhere? Reading all the answers above gave me a headache. We are looking for "git fetch all branches to local". There must be a way aside from bash-scripts to do this.
    – JosephK
    Commented May 2, 2016 at 6:12
  • 1
    Just after you execute "git fetch origin", it will show the output like this in your terminal - "* [new branch] branch_name -> origin/branch_name", but when you run "git branch" it will show you only your local branches instead, so to see all the branches you can do "git branch -a" and then to switch to the remote branch you need to run " git checkout --track origin/<branch you want to checkout>". Hope this helps. :-)
    – Sam
    Commented Jun 9, 2016 at 4:24
  • 5
    Suraj, because the question was, how to "clone all remote branches" - not how to manually update one at a time. It appears there is no answer to the actual question - just ways to do a whole lot of typing if you have a lot of branches.
    – JosephK
    Commented Feb 19, 2017 at 7:38
47

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
  master

$ git branch -a
* branchxyz
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchxyz
  remotes/origin/branch123

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.

0
35

You only need to use "git clone" to get all branches.

git clone <your_http_url>

Even though you only see the 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 repository. "git branch -a" and "git checkout <your_branch_name>" can be run successfully when you don't have an Internet connection. So it is proved that when you do "git clone", it already has copied all branches from the remote repository. After that, you don't need the remote repository. Your local already has all branches' code.

2
  • 2
    Very clear response here. Lots of folks confused about this topic.
    – XMAN
    Commented Oct 20, 2018 at 23:12
  • 1
    I'd like to second your statement "can be run successfully when you close your wifi". "git clone" really does result in a repo containing all branches.
    – bvgheluwe
    Commented Feb 28, 2019 at 13:32
31

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.

8
  • 1
    You can run git commands with or without the hyphen. Both "git-branch" and "git branch" will work. Commented Sep 15, 2008 at 22:55
  • 29
    Maybe this answer was given a long time ago when git worked differently, but I think it's misleading today. git clone does download all the remote branches, but it only makes a local branch of master. Since git branch only shows local branches, you need git branch -a to see remote branches, too.
    – Cerran
    Commented Mar 5, 2014 at 13:05
  • 2
    Thank you. This is kind of strange default behavior IMO. I'll just chalk it up to more cryptic gitness. If it downloaded the branches, why would it hide them when calling git branch? Commented Oct 26, 2016 at 14:27
  • 1
    @Cerran, thanks; I've updated my answer accordingly. Commented Oct 28, 2017 at 15:34
  • 2
    "does download all the remote branches, but it only makes a local branch of master". I need help understanding this. It seems git clone does NOT clone any branches except master, as when you do "git branch -a" it shows that the "develop" branch is only at "remotes/origin/develop". This must be saying that you dont have this branch anywhere locally, it only exists currently on the origin right? Commented Jan 23, 2018 at 10:47
29

All the answers I saw here were 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 repository with a lot of branches, all the ways illustrated in previous answers 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, and there is just a hidden .git folder now that you can see with a "ls -alt" command from the terminal.

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

3. Third Step

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

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 want to do for every single project in this way.

2
  • 2
    I don't like your usage of the word "download" in ... "download" them manually one at a time. All info is, in fact, already downloaded after having cloned the repo. The only thing one needs to do is creating local tracking branches (which is also possible when offline, which proves that all the information is in the repo).
    – bvgheluwe
    Commented Feb 28, 2019 at 13:35
  • @bvgheluwe that's why it is in quotes.
    – Fed
    Commented Mar 5, 2019 at 16:21
21

Self-Contained Repository

If you’re looking for a self-contained clone or backup that includes all remote branches and commit logs, use:

git clone http://[email protected]
git pull --all

The accepted answer of git branch -a only shows the remote branches. If you attempt to checkout the branches you'll be unable to unless you still have network access to the origin server.

Credit: Gabe Kopley's for suggesting using git pull --all.

Note:
Of course, if you no longer have network access to the remote/origin server, remote/origin branches will not have any updates reflected in your repository clone. Their revisions will reflect commits from the date and time you performed the two repository cloning commands above.


Checkout a *local* branch in the usual way with `git checkout remote/origin/` Use `git branch -a` to reveal the remote branches saved within your `clone` repository.

To checkout ALL your clone branches to local branches with one command, use one of the bash commands below:

$ for i in $(git branch -a |grep 'remotes' | awk -F/ '{print $3}' \ 
| grep -v 'HEAD ->');do git checkout -b $i --track origin/$i; done

OR

If your repo has nested branches then this command will take that into account also:

for i in $(git branch -a |grep 'remotes' |grep -v 'HEAD ->');do \
basename ${i##\./} | xargs -I {} git checkout -b {} --track origin/{}; done

The above commands will checkout a local branch into your local git repository, named the same as the remote/origin/<branchname> and set it to --track changes from the remote branch on the remote/origin server should you regain network access to your origin repo server once more and perform a git pull command in the usual way.

1
  • 3
    This is what I came her for! Commented Jul 15, 2020 at 21:32
19

Use my tool git_remote_branch (grb). 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

  Usage:

  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]



  Notes:
  - 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.

  Example:
    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
2
  • 7
    Word to the wise: It looks like this project was abandoned around the time this answer was posted. I can't find any updates after 2008. Caveat emptor and all that. If I'm wrong, I hope someone will edit and provide a current pointer, because I'd love to have a tool like this handy.
    – bradheintz
    Commented Apr 27, 2011 at 21:53
  • @bradheintz check this answer, it sets up a git alias: stackoverflow.com/a/16563327/151841
    – user151841
    Commented Apr 19, 2019 at 15:06
17
#!/bin/bash
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done

These code will pull all remote branches code to the local repository.

2
15

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
14

I'm cloning a repository from the Udemy course Elegant Automation Frameworks with Python and Pytest, so that I can later go over it OFFLINE. I tried downloading the zip, but this only comes for the current branch, so here are my 2 cents.

I'm working on Windows and, obviously, I resorted to the Ubuntu shell from the Windows Subsystem for Linux. Immediately after cloning, here's my branches:

$ git clone https://github.com/BrandonBlair/elegantframeworks.git

$ git branch -a

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/config_recipe
  remotes/origin/functionaltests
  remotes/origin/master
  remotes/origin/parallel
  remotes/origin/parametrize
  remotes/origin/parametrize_data_excel
  remotes/origin/unittesting
  remotes/origin/unittesting1

Then — and after hitting a few git checkout brick walls —, what finally worked for me was:

$ for b in `git branch -a | cut -c18- | cut -d\  -f1`; do git checkout $b; git stash; done

After this, here are my branches:

$ git branch -a

  config_recipe
  functionaltests
  master
  parallel
  parametrize
  parametrize_data_excel
  unittesting
* unittesting1
  remotes/origin/HEAD -> origin/master
  remotes/origin/config_recipe
  remotes/origin/functionaltests
  remotes/origin/master
  remotes/origin/parallel
  remotes/origin/parametrize
  remotes/origin/parametrize_data_excel
  remotes/origin/unittesting
  remotes/origin/unittesting1

Mine goes physical, cutting out the initial remotes/origin/ and then filtering for space delimiters. Arguably, I could just have greped out HEAD and be done with one cut, but I'll leave that for the comments.

Please notice that your current branch is now the last on the list. If you don't know why that is, you're in a tight spot there. Just git checkout whatever you want now.

1
  • 1
    this solution did the trick for me, it retrieves the branches with the original folder structure
    – DanielV
    Commented Oct 17, 2022 at 22:30
13

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

2
  • 6
    There is a difference between "you have it" and "you see it". git branch -all will NOT list the remote branches any more when you remove the remote repository.
    – Gustave
    Commented Mar 1, 2018 at 11:23
  • @Gustave Why oh why would someone expect or want to use branches from old remotes? If you still need these branches..... maybe just don't remove that remote? Commented Sep 4 at 12:51
13

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
1
  • The simplest way of cloning all branches! Commented Jul 22, 2021 at 7:59
13

Looking at one of the 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;
done

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

3
  • You can improve the regex, or maybe use Awk instead of grep, to improve the filter to avoid false positives.
    – tripleee
    Commented Nov 4, 2015 at 12:37
  • all the branches are 'origin\my_branch_name', which is not definitely what I want. Commented Sep 1, 2016 at 17:49
  • I've not seen the construct ${branch##*/} before - looks really useful - any idea where I can find out more on that? can't seem to find under bash anywhere. Thx.
    – SaminOz
    Commented May 7, 2017 at 11:44
13

To create a "full" backup of all branches+refs+tags+etc stored in your git host (github/bitbucket/etc), run:

mkdir -p -- myapp-mirror
cd myapp-mirror
git clone --mirror https://git.myco.com/group/myapp.git .git
git config --bool core.bare false
git config --bool core.logAllRefUpdates true
git reset --hard # restore working directory

This is compiled from everything I've learned from other answers.

You can then use this local repo mirror to transition to a different SCM system/git host, or you can keep this as a backup. It's also useful as a search tool, since most git hosts only search code on the "main" branch of each repo, if you git log -S"specialVar", you'll see all code on all branches.

Note: if you want to use this repo in your day-to-day work, run:

git config --unset remote.origin.mirror

WARNING: you may run into strange issues if you attempt to use this in your day-to-day work. If your ide/editor is doing some auto-fetching, your local master may update because, you did git clone --mirror. Then those files appear in your git staging area. I actually had a situation where I'm on a local feature branch.. that branch has no commits, and all files in the repo appear in the staging area. Just nuts.

6
  • 1
    git reset --hard looks scary. What is all this supposed to do? An explanation would be in order. E.g., what is the idea/gist? Please respond by editing your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today). Commented Dec 8, 2021 at 23:38
  • 3
    As this is a new directory with a fresh clone, I don't see how it's scary. Commented Dec 8, 2021 at 23:55
  • 1
    I admit I'm not really understanding how it works, but compared with the other solutions, it is the only one working, it downloads all the branches locally in few lines of commands, thanks Commented Feb 20, 2022 at 21:51
  • If the intention is to create a full copy of the repository with all branches locally, this should be considered the correct answer. A git reset ---hard is nothing more than discarding any changes since last commit, then setting HEAD to that commit. Not really scary at all. Ref: git-scm.com/docs/git-reset Commented Oct 7, 2022 at 8:19
  • Why not instead of reset do git checkout --recurse-submodules? Isn't it more "full" backup than just reset a single repo?
    – Andry
    Commented Feb 1, 2023 at 8:34
12

I wrote these 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 in my Git settings repository.

11

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.

1
  • Just wanted to thank you. This worked perfectly and it doesn't suffer from various problems related to cloning a bare repo such as some pull behaviour changing etc.
    – mahonya
    Commented Dec 16, 2019 at 16:27
11

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

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

So I found these two methods very useful.

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

Use commands that you can remember

I'm using Bitbucket, a repository hosting service of Atlassian. So I try to follow their documentation. And that works perfectly for me. With the following easy and short commands you can checkout your remote branch.

At first clone your repository, and then change into the destination folder. And last, but not least, fetch and checkout:

git clone <repo> <destination_folder>
cd <destination_folder>
git fetch && git checkout <branch>

That's it. Here a little more real-world example:

git clone https://[email protected]/team/repository.git project_folder
cd project_folder
git fetch && git checkout develop

You will find detail information about the commands in the documentation: Clone Command, Fetch Command, Checkout Command

10

For copy-pasting into the 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 higher readability:

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 0. delete local branch (so that we can check out force-updated branches) 0. check out branch from the remote
  4. check out master (for the sake of it)

It is based on the answer of VonC.

Not the answer you're looking for? Browse other questions tagged or ask your own question.