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

- 54,789
- 12
- 54
- 72
-
161The 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. – Day Davis Waterbury Jun 18 '12 at 22:43
-
6Maybe just copy the entire folder the old fashioned way? `scp some_user@example.com:/home/some_user/project_folder ~` Not sure if that solution works for github though.. – snapfractalpop Sep 26 '12 at 22:51
-
25Rather than saying "I've cloned, pulled, and fetched," much better to show us the *exact commands* that you executed. – Bob Gilmore Nov 22 '13 at 18:17
-
2@DayDavisWaterbury Here in Git 1.8.3.2, the checkouted branch won't be in 'detached HEAD' state, but the checkouted tag will be. – zeekvfu May 18 '14 at 02:55
-
You will be able to checkout all branches (in different path) after cloning a repo, with the new `git checkout --to=
` command coming in Git 2.5+ (Q2 2015): that would support multiple branch checkout. See http://stackoverflow.com/a/30185564/6309. – VonC May 12 '15 at 09:22 -
92It 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 Jul 11 '16 at 06:31
-
34Seeing 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. – Sнаđошƒаӽ Aug 29 '16 at 04:29
-
1@huggie is there less data sent over the wire for only a specific branch? If you're cloning the Linux kernel or some other beast, maybe that's preferable *by default* (though I agree that if you want it **all**, that should be easy too) – Nick T Oct 28 '16 at 14:37
-
1Now that it's been a while since I learned more about git, I realized my confusion then stemmed from the name "remote branches" and "remote tracking branches." Git stores stuff in a tree. Branches (be it remote, remote tracking, or local) are "labels" to the tree. When cloning, everything in the tree gets cloned. And every `origin/XXXX` (remote branches) are labeled. (They are really local labels you keep). A local master branch usually is made to be a "remote-tracking branch" (Notice the dash I added to clarify.) But you can create other local branches which bear the tracking ability. – huggie Apr 08 '19 at 02:46
-
1So, branches are labels. There are really all local to you. A "remote branch" (origin/XXX) is a local label to match the remote (as latest as you've known since the last fetch). A "local branch" is a local label. And a local branch can have the ability to "track" and becomes a "remote-tracking" branch. The ability to track really just means you save a few keystroke, no need to specify which remote branch you're pulling or pushing. That's it. No more, no less. And when you clone, tree gets cloned, and the local `origin/xxx` are labeled. – huggie Apr 08 '19 at 02:56
-
4@DayDavisWaterbury please do not refer to an answer on SO as the one with the "second most upvotes." Consider using poster's name instead. The number of votes changes over time. – Karl Jun 30 '20 at 09:10
-
I believe the key is in https://stackoverflow.com/a/18894949/10020074 It appears that git pull is really pulling ALL branches to local, all you need to do is checkout to the branch you want, and checkout will automaically create that local branch. Is a matter of understanding what pull and fetch do behind the scenes. – Daniel Carrera Jul 28 '20 at 13:40
-
But we don't want to read a long story, we just wanted to copy files. It is fantastic that there is still some uncertainty about copying files in the year 2023 - after git clone, can the original repository become unavailable and we lost something from some branch? that is the question and it should not require a long story about detached heads or any other booze talk – Niklas Rosencrantz May 20 '23 at 12:51
-
For example, after git clone my own repository at github, assume that my account is locked or becomes unavailable. Is it sufficient to git clone, and I have everything I wanted from all branches? – Niklas Rosencrantz May 20 '23 at 12:53
48 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! 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 &

- 7,243
- 6
- 49
- 61

- 60,150
- 6
- 45
- 50
-
147How can someone create automatically all the remote branches, e.g. experimental for origin/experimental? – Cristian Ciupitu Jun 04 '09 at 16:33
-
62Cristian: 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 Jul 20 '09 at 21:44
-
51
-
168Good answer, but kinda misses the question. I was looking for a one-liner to checkout all the remote branches. – cmcginty Oct 19 '10 at 21:01
-
36The 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 Oct 28 '10 at 12:43
-
I ran into a problem where git responded with: "fatal: git checkout: updating paths is incompatible with switching branches". I had to issue a "Git pull" first, then "git checkout -b
origin/ – gmoore Nov 24 '10 at 15:10" -
2Note also that "git fetch" with no arguments will fetch any new remote branches, that appeared after you initially cloned it. Otherwise they might not appear when you run "git branch -a". – J-P Jan 25 '11 at 10:55
-
2how is `$ git checkout -b experimental origin/experimental` different from `$ git branch --track experimental origin/experimental`? I realize checkout will also switch to the branch. – Vaibhav Bajpai Aug 17 '11 at 00:00
-
2@Vaibhav, "I realize checkout will also switch to the branch": therein lies the difference :) – Kevin C. Sep 13 '11 at 21:08
-
1With the `git checkout -b ...` command, do you need to add the --track parameter? From the help documentation for `git checkout [
– milesmeow Jan 09 '12 at 08:26 -
1You may need to 'git remote update' before you 'git checkout -b experimental origin/experimental' for it to find a remote branch that's newer that your local repo. – Parsingphase May 09 '12 at 08:25
-
@milesmeow see my comment on Luuk Paulussen's answer below. You can skip `--track` when you're starting from a remote branch and are using the default setting for the `branch.autosetupmerge` config. – dubiousjim Jul 03 '12 at 13:36
-
2how come `git checkout experimental` is different from `git checkout origin/experimental` – Jürgen Paul Aug 03 '12 at 10:53
-
3It's useful to add verbosity to the `git branch -a` output, by doing `git branch -av` or even `git branch -avv`. With the increased verbosity, you will see each branch's latest commit as well. – MarkDBlackwell Dec 02 '13 at 06:53
-
@PineappleUndertheSea: ``experimental`` is your local branch, ``origin/experimental`` is the remote branch. You shouldn't be making changes directly in the remote branch since when you `git pull` or `git fetch`, the remote branch is expected to be able to update cleanly to reflect upstream changes. – Joe Atzberger Jun 12 '14 at 00:03
-
1If you cloned a bare repository, you may need to look at [Dave's answer](http://stackoverflow.com/a/7216269/1408717). When I cloned a bare repo, it didn't clone all of the branches. Dave's solution allowed me to clone with all of the branches. – Aust Jan 05 '15 at 21:01
-
7Instead of `git checkout -b experimental origin/experimental`, you can write just `git checkout experimental`, it will create the branch and set the tracking information for you (except with very old Git versions). – Matthieu Moy Apr 29 '15 at 15:22
-
1@CristianCiupitu I find it easiest to open my `.git/refs` folder in a file browser and move or copy all the entries in `.git/refs/remotes/origin/*` to `.git/refs/heads/`; things are a bit less convenient when the files have been moved into `.git/packed-refs`, at that point the git command line would be easier to multiplex – ThorSummoner May 20 '15 at 17:03
-
1What do you mean by "other branches hiding in your repository!" Any reason why they are hidden? I don't get this @emk – uday Jul 09 '15 at 15:58
-
1@uDaY by "hiding" he meant that `git branch` does not show remote branches by default, so you need to use `git branch -a` to show all branches. – Katsuke Jul 26 '15 at 19:05
-
**git checkout experimental origin/experimental** here drop "-b" and it will cover your need in one step – SD. Feb 05 '16 at 05:05
-
3@uDaY - ideally, git clone would prompt you with each branch y/n/all instead of 'hiding' them and leaving you to figure out how to get a particular branch on your local machine with yet more commands and switches to decipher. I said "clone" and gave it a remote - not "clone master only" - but git hasn't quite caught up with the level of ease / forethought we had in DOS in the late 80s. – JosephK Jul 26 '16 at 04:51
-
About "But there are other branches hiding in your repository!" This is not exactly true. The remote branches are NOT in your repository, but only in the remote repository. Remove origin to verify. – Gustave Mar 01 '18 at 11:18
-
@Gustave: The `remotes/origin/experimental` tag actually points a local copy of `origin experimental`, updated the last time you ran `git fetch`. If you disconnect from the network, you should still be able access that data using `git checkout origin/experimental`. (To be precise, I haven't checked lately, but this is how it has always worked historically.) – emk Nov 02 '18 at 12:48
-
1I've created this one-liner to checkout and pull all remote branches: `for branch in $(git branch -a); do if echo $branch | grep -q remotes && ! echo $branch | grep -q HEAD; then git checkout "${branch#remotes/origin/}"; git pull; fi; done` Loops through all branches using `git branch -a` then filters the results to only those with `remotes` in the name (skip all local branches) and filters out `HEAD`. Checks out the branch using the part after `remotes/origin/` so if you already have that branch locally it reuses it but does do the `git pull`. (only tested with bash) – Paul Dec 13 '19 at 09:15
-
1too much noise in this question :( just did this and worked like charm `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` – bastami82 Sep 05 '20 at 17:00
-
Alright, I flexed my editorial privileges and updated this answer. – Theodore R. Smith Sep 21 '20 at 17:45
-
You may want to add that a clone pulls all of the history. The main reason I looked up this answer is because I wasn't sure it did. This answer may be a good link: https://stackoverflow.com/a/4658547/1366594 – BrainStorm.exe Mar 25 '21 at 16:50
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

- 30,738
- 21
- 105
- 131

- 16,281
- 5
- 47
- 60
-
13If 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 Jan 27 '12 at 19:07
-
54this only fetch remote branches that have been locally added not *any* remote branch – jujule Feb 10 '12 at 11:45
-
35The first command is redundant. Simply `git pull --all` will do the same – it just won't fetch twice. And infosec812 is right that this does not answer the question anyway. I wonder how this got so many upvotes. – Sven Marnach Apr 06 '12 at 14:03
-
Yeah, I agree with @infosec812... This answer doesn't explain the actual cloning / checking out process, which is done with `git checkout -b
`, where `remotebranch` is the name of the remote as it appears in `git branch -r` (or also `git branch -a`). -
6After 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
` to get the branch I want. -- I landed on this question from a Google search, and this answer solves my problem. – WNRosenberg Jan 31 '13 at 16:47 -
62This is not helpful at all, doesn't pull any remote branches other than that is existing. – Avinash R Apr 11 '13 at 15:02
-
2Git Pull --all is correct. This allowed me to pull in remote branches that existed on github but not in the local repo, I could then move the this branch as normal – McDonnellDean Jun 13 '13 at 11:08
-
1Watch out @Jazzerus. I think `git pull
/ – hobs Apr 09 '15 at 21:38` will merge that branch into whatever branch you currently have checked out. What you want is `git checkout --track / `. And this is what the OP wants, `git checkout --track` on all remote (origin) branches -
4`git pull --all` or `git fetch --all` just does all ***remotes***, not branches. – Geremia Feb 20 '16 at 02:53
-
2@basZero `git pull --all;git push remoteUrl2 --all; cd newDir; git clone remoteUrl2; cd repo; git branch -a` will show *only* the master branch, therefore the question has *not* been answered as dozens of branches have been dropped. – user3338098 Apr 13 '16 at 17:25
-
2Please flag this answer, it does not attempt to answer the original question. – Luís de Sousa Jan 23 '18 at 07:42
-
14It'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 :( – 9ilsdx 9rvj 0lo Apr 10 '18 at 14:43
-
1If you want to pull all local branches, grab [hub](https://github.com/github/hub), then run `hub sync` – Leo Aug 20 '19 at 09:12
-
1This doesn't do anything. If i `git clone`, then run your command, i still only have `master`. – Theodore R. Smith Sep 21 '20 at 17:41
-
I can confirm that this command does not actually pull any additional branches – Bastian Oct 08 '21 at 10:18
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
-
28This 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. – Deven Phillips Oct 27 '11 at 17:15
-
tweaked: `for branch in \`git branch -a | sed -n '\=/HEAD$=d; \=/master$=d;s=
– dubiousjim Jul 03 '12 at 13:13remotes/==p'\`; do ...` -
66"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 Sep 18 '12 at 12:38
-
Per my reading of the docs, you only need a `git pull --all` at the end since it implicitly does the fetch? – Mike Repass Feb 18 '14 at 23:37
-
6This command creates the feature branches from remote as normal branches (not feature branches) - how to fix this? – Alex2php Mar 20 '14 at 14:31
-
6if 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 Jan 12 '15 at 11:54
-
1@Alex2php You'll have to edit the ${branch##*/} portion. I just trimmed off the front instead. ($branch | cut -c 16-) – Trevor Hickey Apr 22 '15 at 20:13
-
14I'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 Jul 02 '15 at 08:33
-
2I see it's in the answer and been repeated in the comments several times, so I've got to mention: `git branch -a | grep remotes` can instead be `git branch -r` (with tweaks to later parts because the "remotes/" part of the branch name isn't in this output) – Izkata Aug 09 '15 at 04:18
-
1`git pull --all` or `git fetch --all` just does all ***remotes***, not branches. Your `bash` script worked, however. – Geremia Feb 20 '16 at 02:53
-
-
1just going to add my flavor of this: `git branch -a | grep remotes | grep -v HEAD | rev | cut -d'/' -f1 | rev | xargs -I% git checkout %` – user2066337 May 13 '20 at 21:37
-
`git checkout "${branch##*/}"` would suffice to create tracking branches instead of `git branch --track "${branch##*/}" "$branch"` – Rakib Aug 06 '20 at 12:54
-
This script breaks the subbranch names. If I have multiple branchs starting with `feature/blabla1` , `feature/blabla2` it only gets the `blabla1` and `blabla2` so you can not see the parent name. – abdullah cinar Mar 12 '21 at 06:55
-
1To make this an alias, simply add: `pull-branches = "!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 #"` (some characters had to be escaped) as an alias in your `.gitconfig` – Matias May 06 '21 at 19:15
-
-
I feel like OP asked this question because of a misunderstanding of how Git works. That being said, this answer provides a solution for what many people seem to want, but I'm curious to know what the use case would be for this. @DevenPhillips I realize your comment is over 10 years old, but do you remember what your use case was? Would you still have that use case today knowing that you can just wait to checkout the branch until you need to do something with it? – TTT Mar 04 '22 at 22:16
-
-
I don't know about them buy my use case is backing up a git repo that may be threatened by a DMCA takedown. F* Nintendo. – majinnaibu May 06 '23 at 04:52
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?
-
8You 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 Jan 12 '12 at 04:25
-
1Agree with @test - I found this answer very useful. I had problems with a repository where I had a replace which broke the history, but it worked with this method. Thanks a lot for mention this method Dave ! – oanoss Jun 18 '12 at 03:13
-
43This 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 Sep 11 '12 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 Sep 18 '12 at 07:37
-
4@Dave: Hm. I'm having second thoughts: --mirror does more than just setting up all branches as being tracked. It copies all refs from the origin and subsequent `git remote update` will do that again. Behaviour of pulls change. I'm back to believing the full copy requires a one-line script. – cfi Sep 18 '12 at 11:53
-
8`git clone --mirror` is very good for backing up your git repositories ^_^ – TrinitronX May 20 '13 at 21:19
-
3For reference, https://git.wiki.kernel.org/index.php/Git_FAQ#How_do_I_clone_a_repository_with_all_remotely_tracked_branches.3F – michael Aug 05 '14 at 07:16
-
If your intent is to create a backup (not a mirror), I would instead use `git-bundle` – onionjake Jul 02 '15 at 17:51
-
I wanted a repo that is identical to the source with its origin pointing to the same place. So I added: `cp path/to/original/.git/config path/to/dest/.git/config` This seems to fix some other problems related to starting with a bare repo as well. – Tongfa Apr 26 '16 at 20:40
-
5When 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! – Max Cascone Aug 15 '17 at 20:15
-
1I got confused by the `path/to/dest/.git` part and left it out. Had to `mkdir x; mv x.git x/.git; cd x; git config --bool core.bare false` to recover. Else, yes, this is the solution. Thanks. – Giszmo Sep 01 '17 at 01:30
-
1
-
1Warning, it doesn't clone merged branches. But other than that, it does the work! – Kusan Oct 23 '18 at 13:49
-
In my case, I also need to run `git config --bool core.logallrefupdates true` because core.logallrefupdates is false by default in a bare repository (or a mirror repo). reference: https://git-scm.com/docs/git-config – halfmoonhalf Apr 23 '20 at 10:46
-
1I found another difference between clone and clone --mirror (https://stackoverflow.com/a/3960063/4336225), so if I want to work on this mirrored cloned repo. I also 1) need to run `git config --bool core.logallrefupdates true` because core.logallrefupdates is false by default in a bare repository (or a mirror repo). reference: https://git-scm.com/docs/git-config. 2) the fetch section in config file also needs to be changed, from "fetch = +refs/*:refs/*", to "fetch = +refs/heads/*:refs/remotes/origin/*". otherwise the `git fetch` does not work in the same way in as normally cloned repo. – halfmoonhalf Apr 23 '20 at 11:15
-
I had to do [this](https://stackoverflow.com/a/49339040/4414935) to be able to push back to origin. – jarno Oct 12 '20 at 21:16
-
correction: `git config --bool core.logAllRefUpdates true` (capitalization) – Devin Rhode Jun 26 '21 at 20:03
-
@Devin Rhode: What do you mean by "capitalization"? An option related to that? Something wrong in the literal command in the answer? Something else? What would this correct? Is it instead of the third command line? Or in addition to the third command line? What is the consequence of it not being corrected? Can you elaborate, perhaps with some references? – Peter Mortensen Dec 08 '21 at 21:56
-
StackOverflow doesn't let me edit comments. My `git config` snippet in a previous comment does not have correct letter casing/capitalization. I capitalized the letters A, R and U in `logAllRefUpdates`. Not using correct casing/capitalization may be totally OK, but I see no point in finding out the hard way. – Devin Rhode Dec 08 '21 at 23:44
-
This is only correct answer. Which needs more votes over wrong ones. – Phyo Arkar Lwin Jul 16 '22 at 04:29
-
Note the need to create `.git` as a directory in the path before you clone the repo. We're used to seeing `git clone` create the .git directory for us. If you don't create it and then you run `git checkout`, you may see the error "fatal: this operation must be run in a work tree." In that case, create the .git directory, move all other directories into it, then run the other commands. – Kay V Dec 07 '22 at 23:07
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>
-
1So, 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. – Gerard Roche Jun 14 '12 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 Jul 03 '12 at 13:05
-
4@dubiousjim: Actually, this is in the manual. git-checkout(1) says: "If
is not found but there does exist a tracking branch in exactly one remote (call it – sleske Feb 27 '13 at 09:01) with a matching name, treat as equivalent to 'git checkout -b --track / ' " (Git V.1.8.1.1). -
1What we need is $ git pull *
/* - 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 Feb 19 '17 at 05:27 -
Most importantly to me if it doesn't exist it doesn't create one. – Joe Johnston Dec 03 '20 at 01:07
-
-
@reducingactivity It does. All branches are already cloned. The issue is the OP didn't know how to check out those branches. – Nikos C. Jan 17 '22 at 09:28
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.

- 30,738
- 21
- 105
- 131

- 1,297
- 1
- 9
- 14
-
So you mean the second form is only easier to remember and there's no other difference? – aderchox Jul 18 '19 at 15:09
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

- 30,738
- 21
- 105
- 131

- 917
- 6
- 3
-
2Thanks. This actually clones all remote branches unlike several of the other answers – FearlessHyena May 14 '20 at 10:22
-
1Note 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. – Steve Barnes Nov 08 '22 at 05: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 Mar 05 '23 at 09:11
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.

- 30,738
- 21
- 105
- 131

- 909
- 1
- 6
- 7
-
16You don't need refs/remotes here. git checkout -b dev origin/dev will work fine. – emk Sep 17 '08 at 13:10
-
4This 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 Jul 03 '12 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 Sep 19 '16 at 22:14
-
2
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.

- 30,738
- 21
- 105
- 131

- 951
- 6
- 7
-
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 Mar 05 '14 at 13:11
-
1taking from Dave's answer below. Using 'git config --bool core.bare false' instead of 'git config unset core.bare' seems to do the job. – Confused Vorlon Oct 28 '14 at 12:25
-
I have the `error: key does not contain a section: unset`. The [Dave's answer](http://stackoverflow.com/a/7216269/938111) works better. – oHo Oct 19 '15 at 09:24
-
1It'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... – Dirk Hillbrecht May 10 '17 at 08:05
-
It worked for me ... @olibre try `git config --bool core.bare false` instead of `git config --unset core.bare` – Chris Sim Jun 29 '17 at 07:02
-
1Thanks @ChrisSim I agree for `git config --bool core.bare false`. This is why I recommend instead the [Dave's answer](http://stackoverflow.com/a/7216269/938111). What do you think about the [Dave's answer](http://stackoverflow.com/a/7216269/938111)? Cheers – oHo Jun 29 '17 at 08:24
-
3This is **absolutely the best answer**, except that [@FedericoCapaldo gave an answer](https://stackoverflow.com/a/34122093/5088075) that goes into a little more detail about exactly what these commands are doing. – unrivaledcreations Aug 05 '17 at 13:59
-
-
-
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).

- 3,433
- 3
- 20
- 18

- 2,087
- 2
- 21
- 33
-
1If `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 May 15 '20 at 20:38
-
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

- 31,633
- 21
- 64
- 68
-
4I 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. – Jan Vlcinsky Nov 17 '13 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. – lacostenycoder Dec 08 '18 at 15:39
-
1Can you explain to me what's the difference between `git checkout -b master origin/master` and `git checkout --track origin/master` please ? – aderchox Jul 18 '19 at 15:08
-
2
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.

- 30,738
- 21
- 105
- 131

- 1,623
- 1
- 19
- 31
-
1Thanks suraj. The reason because its not been voted much. And the ans is not accepted by the questioner. – Sam Jun 08 '15 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 May 02 '16 at 06:12
-
1Just 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/
". Hope this helps. :-) – Sam Jun 09 '16 at 04:24 -
5Suraj, 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 Feb 19 '17 at 07:38
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.
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.

- 30,738
- 21
- 105
- 131

- 12,577
- 3
- 50
- 36
-
2
-
1I'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 Feb 28 '19 at 13:32
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.

- 30,738
- 21
- 105
- 131

- 1,696
- 22
- 29
-
2I 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 Feb 28 '19 at 13:35
-
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
.

- 3,682
- 2
- 20
- 16
-
1You can run git commands with or without the hyphen. Both "git-branch" and "git branch" will work. – Peter Boughton Sep 15 '08 at 22:55
-
28Maybe 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 Mar 05 '14 at 13:05
-
2Thank 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? – Adam Hughes Oct 26 '16 at 14:27
-
1
-
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? – John Little Jan 23 '18 at 10:47
-
-
@AdamHughes Apologies for responding 6 years later, but this behavior has always been sensible. If the remote has hundreds of branches, you probably are only going to care about a few. If `git branch` constantly showed all of them, it would be incredibly distracting. Suppressing the branches makes good sense as default behavior. – William Pursell Nov 05 '22 at 14:27
-
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://user@repo.url
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,873
- 20
- 17
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

- 30,738
- 21
- 105
- 131

- 58,466
- 12
- 54
- 59
-
7Word 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 Apr 27 '11 at 21:53
-
@bradheintz check this answer, it sets up a git alias: https://stackoverflow.com/a/16563327/151841 – user151841 Apr 19 '19 at 15:06
#!/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.

- 30,738
- 21
- 105
- 131

- 4,220
- 4
- 37
- 49
-
ref. https://coderwall.com/p/0ypmka/git-clone-all-remote-branches-locally – arcseldon Apr 15 '17 at 15:13
-
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

- 8,777
- 5
- 67
- 76
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!

- 30,738
- 21
- 105
- 131

- 3,176
- 8
- 40
- 60
-
You can improve the regex, or maybe use Awk instead of `grep`, to improve the filter to avoid false positives. – tripleee Nov 04 '15 at 12:37
-
all the branches are 'origin\my_branch_name', which is not definitely what I want. – Sнаđошƒаӽ Sep 01 '16 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 May 07 '17 at 11:44
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.

- 30,738
- 21
- 105
- 131

- 1,372
- 17
- 24
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:

- 100,211
- 27
- 269
- 172
-
6There 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 Mar 01 '18 at 11:23
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

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

- 23,026
- 8
- 58
- 72
-
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). – Peter Mortensen Dec 08 '21 at 23:38
-
3As this is a new directory with a fresh clone, I don't see how it's scary. – Devin Rhode Dec 08 '21 at 23:55
-
1I 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 – Francesco Orsi Feb 20 '22 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: https://git-scm.com/docs/git-reset – Scopperloit Oct 07 '22 at 08:19
-
Why not instead of reset do `git checkout --recurse-submodules`? Isn't it more "full" backup than just reset a single repo? – Andry Feb 01 '23 at 08:34
-
I'm not sure how this approach would be modified to account for submodules. Speaking of `--recurse-submodules`, you can also pass this same cli option into `git clone`, however, the option is ignored if you are using `--mirror`. (see docs: https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---recurse-submodulesltpathspecgt) Maybe this approach could use some sort of `git submodule foreach 'do clone --mirror' --recursive` script to do a recursive mirror clone? https://git-scm.com/docs/git-submodule#Documentation/git-submodule.txt-foreach--recursiveltcommandgt – Devin Rhode Feb 01 '23 at 20:56
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

- 30,738
- 21
- 105
- 131

- 8,723
- 16
- 64
- 91
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
.

- 72,135
- 12
- 99
- 105
-
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 Dec 16 '19 at 16:27
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 grep
ed 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.

- 30,738
- 21
- 105
- 131

- 576
- 8
- 10
-
this solution did the trick for me, it retrieves the branches with the original folder structure – DanielV Oct 17 '22 at 22:30
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:
- check out master (so that we can delete branch we are on)
- select remote to checkout (change it to whatever remote you have)
- 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
- check out master (for the sake of it)
It is based on the answer of VonC.

- 30,738
- 21
- 105
- 131

- 491
- 4
- 13
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://username@bitbucket.org/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

- 30,738
- 21
- 105
- 131

- 206
- 3
- 4
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 the 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
Troubleshooting
If you still cannot get anything other than the master branch, check the following:
- Double check your remotes (
git remote -v
), e.g.- Validate that
git config branch.master.remote
isorigin
. - Check if
origin
points to the right URL via:git remote show origin
(see this post).
- Validate that

- 30,738
- 21
- 105
- 131

- 155,785
- 88
- 678
- 743
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|
line.strip!
if /origin\//.match(line)
remote[line.gsub(/origin\//, '')] = line
else
local << line
end
end
# Update
remote.each_pair do |loc, rem|
next if local.include?(loc)
%x[git checkout --track -b #{loc} #{rem}]
end
%x[git fetch]

- 30,738
- 21
- 105
- 131

- 1,456
- 3
- 17
- 21
-
See answer I posted further down to avoid having to run this script at all. – lacostenycoder Dec 08 '18 at 15:41
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

- 3,297
- 17
- 31
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.
-
3This requires that you fetch each branch one at a time. Not very good if you have a lot of branches. – lacostenycoder Dec 08 '18 at 15:37
This variation will clone a remote repo with all branches available locally without having to checkout each branch one by one. No fancy scripts needed.
Make a folder with the same name of the repo you wish to clone and cd into for example:
mkdir somerepo
cd somerepo
Now do these commands but with actual repo usersname/reponame
git clone --bare git@github.com:someuser/somerepo.git .git
git config --bool core.bare false
git reset --hard
git branch
Voiala! you have all the branches there!

- 10,623
- 4
- 31
- 48
-
-
1`git rev-parse --abbrev-ref --symbolic-full-name '@{u}'` shows `fatal: no upstream configured for branch 'master'`. Should be `origin/master`. – konsolebox Jun 20 '19 at 14:30
-
@konsolebox I suppose the answer has been updated, and your comment is now outdated – Devin Rhode Feb 21 '22 at 21:20
-
@DevinRhode Without reviewing I would guess I implied here that the solution mentioned here brings inconsistent results. Not my problem to elaborate. – konsolebox Feb 23 '22 at 06:42
How to create a local branch for each branch on remote origin
matching pattern
.
#!/bin/sh
git fetch --all
git for-each-ref --format='%(refname:short)' refs/remotes/origin/pattern |\
sed 's@\(origin/\)\(.*\)@\2\t\1\2@' |\
xargs -n 2 git branch --track
All remote references (branches/tags) are fetched and then local references are created. Should work on most systems, fast, without checking out the index or relying on bashisms.

- 3,306
- 28
- 25
I think this does the trick:
mkdir YourRepo
cd YourRepo
git init --bare .git # create a bare repo
git remote add origin REMOTE_URL # add a remote
git fetch origin refs/heads/*:refs/heads/* # fetch heads
git fetch origin refs/tags/*:refs/tags/* # fetch tags
git init # reinit work tree
git checkout master # checkout a branch
So far, this works for me.

- 30,738
- 21
- 105
- 131

- 5,108
- 3
- 26
- 37
-
According to Note #2 under the refspec section of `git fetch` (http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html), this probably needs to be adjusted. – Andy Sep 12 '12 at 15:25
-
Do you mean the note beginning, "You never do your own development on branches that appear on the right hand side of a
colon"? And, adjusted, for what reason? – MarkDBlackwell Jul 18 '13 at 15:48 -
I was trying to find out how to pull down a remote branch I had deleted locally. Origin was not mine, and I didn't want to go through the hassle of re-cloning everything.
This worked for me:
assuming you need to recreate the branch locally:
git checkout -b recreated-branch-name
git branch -a (to list remote branches)
git rebase remotes/remote-origin/recreated-branch-name
So if I forked from gituser/master to sjp and then branched it to sjp/mynewbranch, it would look like this:
$ git checkout -b mynewbranch
$ git branch -a
master
remotes/sjp/master
remotes/sjp/mynewbranch
$ git fetch (habit to always do before)
$ git rebase remotes/sjp/mynewbranch

- 30,738
- 21
- 105
- 131

- 426
- 3
- 7
This solution worked for me to "copy" a repository to another one:
git merge path/to/source.git --mirror
cd source.git
git remote remove origin
git remote add origin path/to/target.git
git push origin --all
git push origin --tags
On target repository I can see the same branches and tags than the origin repo.

- 406
- 3
- 9
Here, I wrote you a nice function to make it easily repeatable
gitCloneAllBranches() { # clone all git branches at once easily and cd in
# clone as "bare repo"
git clone --mirror $1
# rename without .git extension
with_extension=$(basename $1)
without_extension=$(echo $with_extension | sed 's/.git//')
mv $with_extension $without_extension
cd $without_extension
# change from "bare repository" to not
git config --bool core.bare false
# check if still bare repository if so
if [[ $(git rev-parse --is-bare-repository) == false ]]; then
echo "ready to go"
else
echo "WARNING: STILL BARE GIT REPOSITORY"
fi
# EXAMPLES:
# gitCloneAllBranches https://github.com/something/something.git
}

- 12,047
- 89
- 66
-
What programming language/shell? [Bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29)? [Z shell](https://en.wikipedia.org/wiki/Z_shell)? [PowerShell](https://en.wikipedia.org/wiki/Windows_PowerShell)? Version? What platform was it tested on? – Peter Mortensen Dec 08 '21 at 23:33
This is what I do whenever I need to bring down all branches. Credits to Ray Villalobos from Linkedin Learning. Try cloning all branches including commits:
mkdir -p -- newproject_folder
cd newproject_folder
git clone --mirror https://github.com/USER_NAME/RepositoryName.git .git
git config --bool core.bare false
git reset --hard

- 23,026
- 8
- 58
- 72

- 534
- 4
- 8
-
1Few months later, how to update this mirror with all latest changes? – Devin Rhode Jun 26 '21 at 19:30
-
Seems like `git remote update` will apparently give you a "fresh" mirror if I'm understanding this right. I think it may also reflect cleanup done on the remote repo. So if refs/branches/tags/etc were deleted remotely, it'll delete them locally. But, I'm not 100% certain. – Devin Rhode Jun 26 '21 at 19:59
I could not edit Bigfish answer's. He proposes a bash script which I offer to update and give a better git integration. egrep is outdated and should be replaced by grep -E.
#!/bin/bash
for branch in $(git branch --all | grep '^\s*remotes' | grep -E --invert-match '(:?HEAD|master)$'); do
git branch --track "${branch##*/}" "$branch"
done
You can extend git by adding this bash file as a git custom subcommand:
$ mkdir ~/.gitbin; touch ~/.gitbin/git-fetchThemAll
$ chmod u+x ~/.gitbin/git-fetchThemAll
Put the content of the bash script in git-fetchThemAll
.
$ echo 'export PATH="$HOME/.gitbin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc # update PATH in your current shell
$ git fetchThemAll
If you prefer, you could use a shell alias for this oneliner by user cfi
alias fetchThemAll=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

- 317
- 1
- 14
A better alternative solution for developers using Visual Studio Code is to use Git Shadow Extension.
This Visual Studio Code extension allows cloning repository content and directories, that can be filtered by branch name or commit hash. That way, branches or commits can be used as boilerplates/templates for new projects.

- 30,738
- 21
- 105
- 131

- 528
- 3
- 11
Here's a cross-platform PowerShell 7 function adapted from the previous answers.
function Invoke-GitCloneAll($url) {
$repo = $url.Split('/')[-1].Replace('.git', '')
$repo_d = Join-Path $pwd $repo
if (Test-Path $repo_d) {
Write-Error "fatal: destination path '$repo_d' already exists and is not an empty directory." -ErrorAction Continue
} else {
Write-Host "`nCloning all branches of $repo..."
git -c fetch.prune=false clone $url -q --progress &&
git -c fetch.prune=false --git-dir="$(Join-Path $repo_d '.git')" --work-tree="$repo_d" pull --all
Write-Host "" #newline
}
}
Note: -c fetch.prune=false
makes it include stale branches that would normally be excluded. Remove that if you're not interested in it.
You can make this work with PowerShell 5.1 (the default in Windows 10) by removing &&
from the function, but that makes it try to git pull
even when the previous command failed. So, I strongly recommend just using the cross-platform PowerShell it's always bugging you about trying.

- 30,738
- 21
- 105
- 131

- 662
- 6
- 11
Do a bare clone of the remote repository, save the contents to a .git directory
git clone --bare remote-repo-url.git localdirname/.git
(A bare git repository, created using git clone --bare or git init --bare, is a storage repository, it does not have a working directory, you cannot create or modify files there.)
Change directory to your local directory
cd localdirname
Make your git repository modifiable
git config --bool core.bare false
Restore your working directory
git reset --hard
List all your branches
git branch -al

- 1,677
- 17
- 16
What I used is:
1)$ git clone url
2)$ git branch -a //lists down all branches
* master
remotes/origin/HEAD -> origin/master
remotes/origin/feature/remote_branch_name1
remotes/origin/master
3)$ git checkout origin/feature/remote_branch_name1
git checkout origin/feature/remote_branch_name1
Note: switching to 'origin/feature/remote_branch_name1
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 14e5377 Updated the Folder Structure
4)$ git switch -c remote_branch_name1
Switched to a new branch 'remote_branch_name1'
Working directory got changed by above command.
5)$ git branch
* remote_branch_name1
master

- 4,944
- 10
- 53
- 89
allBranches
Script to download all braches from a Git project
Installation:
sudo git clone https://github.com/marceloviana/allBranches.git && sudo cp -rfv allBranches/allBranches.sh /usr/bin/allBranches && sudo chmod +x /usr/bin/allBranches && sudo rm -rf allBranches
Ready! Now just call the command (allBranches) and tell the Git project directory that you want to download all branches
Use
Example 1:
~$ allBranches /var/www/myproject1/
Example 2:
~$ allBranches /var/www/myproject2/
Example 3 (if already inside the project directory):
~$ allBranches ./
or
~$ allBranches .
View result:
git branch
Reference:
Repository allBranches GitHub: https://github.com/marceloviana/allBranches

- 13
- 2
-
2Additionally, you need to disclose your affiliation to any links provided. – LittleBobbyTables - Au Revoir Oct 03 '19 at 14:27
If you use Bitbucket, you can use import Repository. This will import all Git history (all the branches and commits).

- 30,738
- 21
- 105
- 131

- 617
- 10
- 27
-
Is "Repository" literal? In what context is "import Repository" used? In a web interface? Or something else? Can you elaborate? – Peter Mortensen Dec 08 '21 at 23:27