1776

I cloned a Git repository, which contains about five branches. However, when I do git branch I only see one of them:

$ git branch
* master

I know that I can do git branch -a to see all the branches, but how would I pull all the branches locally so when I do git branch, it shows the following?

$ git branch
* master
* staging
* etc...
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
David542
  • 96,524
  • 132
  • 375
  • 637
  • 1
    Also discussed at http://stackoverflow.com/questions/67699/how-do-i-clone-all-remote-branches-with-git – gliptak Sep 25 '12 at 14:40
  • 2
    This question shows how to get all branches after using the `--single-branch` setting when cloning: http://stackoverflow.com/questions/17714159/how-do-i-undo-a-single-branch-clone (`git fetch --all` will never work if you've specified only one branch!) – Matthew Wilcoxson May 21 '15 at 17:10
  • 2
    You will not see that output ever because the asterisk represents the branch that is currently checkout out. Since you can only have one branch checked out at once, you can have only one asterisk on the left of your branch listing. – Robino Dec 07 '15 at 15:09
  • 1
    The top-ranked answer below misses the OP's intent. I recommend that you look at http://stackoverflow.com/a/72156/342839 instead. `git checkout -b ` seems like the most likely answer. – Reece May 25 '16 at 20:53
  • 5
    I saw a lot of answers but none of them mentioned what I think is probably the easiest way to do what you want: `git clone --bare .git ` (notice you need to add "--bare" and ".git" at the end to clone the repo as a "bare" repo), then `git config --bool core.bare false` (sets the "bare" flag to false), then `git reset --hard` (moves the HEAD to current HEAD on the repo). Now if you `git branch` you should see all branches from the repo you cloned. – Gabriel Ferraz Mar 25 '17 at 17:37
  • Possible duplicate of [How to clone all remote branches in Git?](http://stackoverflow.com/questions/67699/how-to-clone-all-remote-branches-in-git) – Eliran Malka May 07 '17 at 09:44
  • @GabrielFerraz Why don't you write this as an answer? – pipe Sep 06 '17 at 12:42
  • 1
    @pipe: I could but there is already an accepted answer with 912 upvotes, plus another 20 answers. I think it is more likely that someone would read my comment than an answer all the way on the bottom of this thread. If you like the comment you can upvote it so other people would be more likely to read it too. – Gabriel Ferraz Sep 07 '17 at 13:46
  • 5
    @GabrielFerraz Then you are abusing the comment functionality on Stack Overflow. Users can upvote your comment but not downvote. – pipe Sep 07 '17 at 14:40
  • `git fetch origin` will do. – Tzury Bar Yochay Oct 10 '17 at 17:06
  • `git pull origin '*:*'` – Anssi May 21 '21 at 09:11

32 Answers32

2417

You can fetch all branches from all remotes like this:

git fetch --all

It's basically a power move.

fetch updates local copies of remote branches so this is always safe for your local branches BUT:

  1. fetch will not update local branches (which track remote branches); if you want to update your local branches you still need to pull every branch.

  2. fetch will not create local branches (which track remote branches), you have to do this manually. If you want to list all remote branches: git branch -a

To update local branches which track remote branches:

git pull --all

However, this can be still insufficient. It will work only for your local branches which track remote branches. To track all remote branches execute this oneliner BEFORE git pull --all:

git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

TL;DR version

git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all

(It seems that pull fetches all branches from all remotes, but I always fetch first just to be sure.)

Run the first command only if there are remote branches on the server that aren't tracked by your local branches.

P.S. AFAIK git fetch --all and git remote update are equivalent.



Kamil Szot's comment, which folks have found useful.

I had to use:

for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done

because your code created local branches named origin/branchname and I was getting "refname 'origin/branchname' is ambiguous whenever I referred to it.

Honey
  • 24,125
  • 14
  • 123
  • 212
Wookie88
  • 27,279
  • 4
  • 24
  • 32
  • 44
    Sorry. I can't imagine that this is what the OP actually wants. The 'pull' command is 'fetch+merge' and the merge part will overlay all the branches on top of one another - leaving one giant mess. – GoZoner Apr 25 '12 at 14:06
  • 12
    that fetch wouldn't create a new remote branch you still need to check it out with `git checkout -b localname remotename/remotebranch` – Learath2 Oct 20 '12 at 17:06
  • does git fetch, fetches changes from all branches I track ? or I need to be on that branch that I want to fetch from, and other changes won't be fetched for other tracked branches ? (if that makes sense) – Cosmin Cosmin Jan 24 '13 at 10:52
  • 132
    I had to use `for remote in \`git branch -r\`; do git branch --track ${remote#origin/} $remote; done` because your code created local branches named origin/branchname and I was getting "refname 'origin/branchname' is ambiguous whenever I referred to it. – Kamil Szot Sep 22 '13 at 23:46
  • 24
    I don't know if I'm using a different version of GIT, but I had to amend the script to `git pull --all; for remote in \`git branch -r | grep -v \>\`; do git branch --track ${remote#origin/} $remote; done`. The change strips out HEAD. – kim3er Sep 29 '13 at 13:16
  • 18
    For the Windows folks: `for /F %remote in ('git branch -r') do ( git branch --track %remote) && git fetch --all && git pull --all` – Max Dec 20 '13 at 06:03
  • 2
    This does not work at all for my version of git: 1.8.1.2 The effect was to create a dozen branches named "origin/$x" which were all tracking the local branch "master". – dataless Aug 22 '14 at 19:42
  • There is a slight difference between `git fetch --all` and `git remote update` First is that git fetch --all was added in v1.6.6. Second fetch --all will pull from all remote repos. see the commit 9c4a036b3 on github. https://github.com/git/git/commit/9c4a036b34acef63ab754f0e27e5e54bd9d9a210 – JeffCharter Oct 02 '14 at 16:06
  • 5
    The solution of @kim3er worked for me. The problem with all snippets is that they don't work when you have slashes or spaces in the branch names. When you need to write bulletproof bash scripts you should use the `while read` trick as this `git branch -r | while read remote; do git branch --track "${remote#origin/}" "$remote"; d` and quote the variable expansions! – pinkeen Nov 06 '14 at 13:30
  • 7
    @Max: had to make a small tweak `for /F %r in ('git branch -r') do ( git branch --track %r) && git fetch --all && git pull --all` – u01jmg3 Aug 26 '15 at 16:13
  • 1
    It creates branches with 'origin/' – Sandeep Giri Sep 18 '15 at 10:50
  • 3
    Please update your answer with the comments. It is misleading and creates branches with `origin/` – kartsims Dec 03 '15 at 08:35
  • 1
    I had an issue with the color output in my terminal for the various `git branch -r` commands to find all the various branches. Use `git branch -r --no-color` to prevent not valid branch names on terminals supporting color codes. – Keith Bentrup Jan 14 '16 at 21:37
  • 1
    `git pull --all` just does nothing: *"You asked to pull from the remote '--all', but did not specify a branch"* – m0skit0 Feb 10 '16 at 15:47
  • 4
    Stupid to execute the command before checking the comments, I believed the accept mark and the upvotes ... stupid. Now have to delete the repo and clone from scratch. – Vladimir F Feb 21 '16 at 12:48
  • 1
    I've fixed now the answer as per comments, as I was badly burned by this as well. We'll see how it goes. – eis Mar 30 '16 at 12:54
  • 3
    isn't `fetch --all` meant to fetch all remotes? at least it does not work for me (does not fetch new remote branches) – user85421 Jun 30 '16 at 15:47
  • 4
    `git pull` only merges into the current branch, even with `--all`. So it won't update other tracking branches besides the current. – Andy Jul 26 '16 at 16:06
  • 2
    @CarlosHeuberger fetch all remotes is not the same as fetch all branches. Most people only have one remote (origin) so fetch --all rarely does anything different. – Ted Bigham Aug 05 '16 at 14:31
  • 3
    @TedBigham exactly why I _asked_ since the question was to fetch all branches, not all remotes! – user85421 Aug 05 '16 at 14:58
  • my Powershell script for updating all new untracked branches and pulling them: `git branch -r | grep -v "\->" | foreach {git branch --track $_.Substring($_.IndexOf("/") + 1)}; git pull --all` – BigDru Sep 22 '16 at 16:13
  • Regarding "it seems that pull fetches all branches...". It's practically on the front cover of any git manual that pull does a fetch/merge. Why don't you confirm this and remove the parenthetical guess? Might throw in a mention that you can configure "pull" to "fetch rebase". – Rick O'Shea Apr 20 '17 at 04:12
  • 6
    The question was very clear: fetch five branches from one remote, not fetch one branch from five remotes. I don't understand how this answer was accepted. – patricktokeeffe Aug 26 '17 at 18:09
  • This variation excludes tracked branches and master branch : `for remote in $(git branch -r | grep -v -e "\->" -e master); do git branch --track ${remote#origin/} $remote; done` – Daishi Dec 04 '17 at 23:57
  • Yet again goes to show just how _hostile_ the Git command line frontend is towards its users. And it goes to show that Git was never designed with cross-platform use in mind, as evidenced by the ridiculous use of shell commands, which will of course vary by shell. Originally being a concoction of binary executables and shell scripts the target audience is clear and has never changed. Even nearly 13 years since initial release. – 0xC0000022L Feb 14 '18 at 18:42
  • Read this and never write and suggest others `git fetch` followed by git pull` https://stackoverflow.com/a/292359/1114926 – Green Jun 20 '18 at 06:33
  • `git fetch --all` and `git remote update` are almost the same. However, `git remote update` by default fetches the remote specified by `remotes.default`. If this is not set (which I believe by default it is not) then it will fetch all. Best to just use `git fetch --all` as its behavior is consistent. – Nateowami Jun 23 '18 at 16:46
  • Is it possible to have a git alias for that one liner? If I put it in my .gitconfig file i get "fatal: bad config line X" – André Mantas Aug 01 '18 at 09:47
  • I am trying to do the same, `git config --global alias.fa 'branch -r | grep -v ">" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done'` does just display git branch command definition – Curios Dec 06 '18 at 10:58
  • As a casual Git user, this answer was just a teeny bit too advanced for me. I really appreciated the distinction its author was trying to make, but the details were lost on me. For anyone else like me, the [Atlassian Git Tutorial on `git fetch`](https://www.atlassian.com/git/tutorials/syncing/git-fetch) explains the background information really well, so now this answer makes sense to me. +1! – jvriesem Feb 09 '19 at 19:39
  • No pull is required to update tracked branches. It could be done via index update. At least we achieve this by `git fetch origin master:master`, for example. This allows to update index without checking branches out. – 0andriy May 21 '19 at 22:51
  • 2
    What do you mean by the words "power move" linking to the docs for `git fetch`? (Serious question, I don't understand how it is one...) – Sixtyfive Feb 10 '20 at 10:00
871

To list remote branches:
git branch -r

You can check them out as local branches with:
git checkout -b LocalName origin/remotebranchname

Will
  • 3,930
  • 1
  • 13
  • 25
Learath2
  • 15,755
  • 2
  • 18
  • 30
  • 106
    This is exactly what I was looking for when I found the question above. I suspect many people looking for how to pull a remote branch definitely don't want to merge the branch into their current working copy, but they do want a local branch identical to the remote one. – Frug Oct 19 '12 at 16:03
  • 15
    Even if the branch is not visible locally, I can do `git checkout remotebranchname`and it works. what's the difference with your solution? – François Romain Nov 06 '14 at 10:43
  • 16
    Its default behaviour now. Wasn't the case on older git versions. Using `git checkout remotebranchname` used to just create a new **unrelated** branch that is named _remotebranchname_. – Learath2 Nov 15 '14 at 13:10
  • 15
    The accepted answer does something fundamentaly different and to be frank I don't even understand why its the accepted answer – Learath2 Jul 23 '15 at 16:28
  • 11
    The OP asked for all branches. This answer only does one. – Ted Bigham Aug 05 '16 at 15:19
  • 2
    That's perfect for one branch at a time. Just if someone can edit it with the new command (but the old one is still working ;) – Dam Nov 15 '16 at 09:08
  • A co-worker created a branch and made a PR. I was tasked with updating the PR and was having issues checking out the remote branch with its work onto my local machine. This solution worked for me. Thank you! – Yuschick Sep 20 '17 at 06:26
  • `fatal: Cannot update paths and switch to branch 'develop' at the same time. Did you intend to checkout 'origin/temp' which can not be resolved as commit?`.That's result when I run answer script, what's the problem? – kittygirl Jan 23 '19 at 09:07
  • Not my script, idk. Leave a comment under the answer? – Learath2 Jan 23 '19 at 16:42
  • What if I want to merge, not checkout? `git checkout -b LocalName origin/remotebranchname` – U. Windl May 14 '19 at 09:28
  • Merge what? A remote branch? – Learath2 May 15 '19 at 19:30
  • I think in the main question is written how to fetch all git branches, not a single one, one by one, maybe, therefore, this is not the selected answer – FantomX1 Aug 27 '19 at 09:14
  • It is best practice to update the origin with `git remote update` and then list the remote branches with `git branch -r` – mountainLion Oct 21 '20 at 15:37
201

You will need to create local branches tracking remote branches.

Assuming that you've got only one remote called origin, this snippet will create local branches for all remote tracking ones:

for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

After that, git fetch --all will update all local copies of remote branches.

Also, git pull --all will update your local tracking branches, but depending on your local commits and how the 'merge' configure option is set it might create a merge commit, fast-forward or fail.

Undo
  • 25,204
  • 37
  • 102
  • 124
Michael Renner
  • 2,848
  • 3
  • 18
  • 16
  • 5
    This robustifies the solution against branch names containing shell metacharacters (as per pinkeen's comment on the other answer), and avoids spurious error output: git branch -r | grep -v -- ' -> ' | while read remote; do git branch --track "${remote#origin/}" "$remote" 2>&1 | grep -v ' already exists'; done – Daira Hopwood Aug 11 '15 at 23:28
  • 9
    Are you sure that `git pull --all` will update all local tracking branches? As far as I can tell it only updates the current branch from all remotes. – Andy Jul 26 '16 at 16:07
  • 3
    Did this. Local branches matching remote branches were not created. What is the git command that simply says "pull all remote branches creating local ones if they do not exist?" – JosephK Feb 11 '17 at 10:47
  • @JosephK perhaps your remote is not called `origin`? See [this answer](https://stackoverflow.com/a/52335346/5353461) which will work on all remote names. – Tom Hale Sep 14 '18 at 15:53
  • @TomHale It was "origin," but thanks for your answer - though crazy that much is necessary to do what should be one or maybe two flags. I am now trying gitless, to try to avoid the insanity of some aspects of git. – JosephK Dec 10 '18 at 07:33
128

If you do:

git fetch origin

then they will be all there locally. If you then perform:

git branch -a

you'll see them listed as remotes/origin/branch-name. Since they are there locally you can do whatever you please with them. For example:

git diff origin/branch-name 

or

git merge origin/branch-name

or

git checkout -b some-branch origin/branch-name
GoZoner
  • 59,252
  • 19
  • 87
  • 137
  • 5
    Just found this page on google... this was the actual type of answer I was seeking. I tried the first command but received an error: [$ git fetch --all origin fatal: fetch --all does not take a repository argument] --- Using "git fetch --all" seems to do the trick. Thanks for the lead! – longda Mar 29 '13 at 18:26
  • 1
    Fixed (eliminated `--all`) – GoZoner Mar 29 '13 at 19:47
  • 14
    `git fetch -all` fetches all branches of all remotes. `git fetch origin` fetches all branches of the remote `origin`. The later is what the OP was asking. – GoZoner Apr 24 '13 at 19:37
  • 3
    `--all` means "all remotes", not "all branches of a given remote". The latter is implied by any fetch from a remote. – spacediver Jun 03 '13 at 14:58
  • 1
    OP asked for a solution enabling "branch", not "branch -a". – Ted Bigham Aug 05 '16 at 15:22
  • 2
    This is not the way to pull all branches into local repo, from remote repo. – Vladimir Despotovic Nov 20 '16 at 23:41
  • Actually I have a case where a clones repository was lacking some (unmerged) branches, and your solution did not add the missing branches. `git branch -r` displays them, however. – U. Windl May 14 '19 at 09:31
  • This does not bring down the branches – ProsperousHeart Mar 26 '20 at 13:57
78
$ git remote update
$ git pull --all

This assumes all branches are tracked.

If they aren't you can fire this in Bash:

for remote in `git branch -r `; do git branch --track $remote; done

Then run the command.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Johnno Nolan
  • 27,849
  • 17
  • 105
  • 158
  • 3
    When I try that I still get the same result as above. – David542 Apr 25 '12 at 09:10
  • 4
    Same as @JacobLowe, I got the error, but it worked anyway; 'fatal: A branch named 'origin/master' already exists.' – AnneTheAgile Jul 21 '14 at 20:15
  • This is ugly as it will try to create a branch for `->` which will likely exist in the output of `git branch -r` as ` origin/HEAD -> origin/master` – Tom Hale Sep 14 '18 at 15:57
  • Moreover, it doesn't work. I get output: `Branch 'origin/quote-filenames' set up to track local branch 'master'.` The desired output is: `Branch 'quote-filenames' set up to track remote branch 'quote-filenames' from 'origin'.` This is **backwards**, setting the origin to track the remote. See [this answer](https://stackoverflow.com/a/52335346/5353461) for a fix. – Tom Hale Sep 14 '18 at 16:00
  • just what I needed. Since I switched Mac's, even after I cloned the repo I wasn't able to checkout other remote branches and `git fetch` wouldn't work. So the lesson here is that you need to track the remote branches. Gracias! – Victor Ramos Nov 09 '18 at 17:25
  • A small improvement to exclude error on HEAD branch: **for REMOTE in `git branch -r | grep -v HEAD`; do git branch --track ${REMOTE}; done** . – Antonio Petricca Apr 24 '20 at 07:26
66

The Bash for loop wasn't working for me, but this did exactly what I wanted. All the branches from my origin mirrored as the same name locally.

git checkout --detach
git fetch origin '+refs/heads/*:refs/heads/*'

See Mike DuPont's comment below. I think I was trying to do this on a Jenkins Server which leaves it in detached head mode.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Tim Lum
  • 839
  • 8
  • 13
  • 6
    That produces `fatal: Refusing to fetch into current branch refs/heads/master of non-bare repository` after a simple clone. Have to detach head first. I did this with `git checkout ` – brannerchinese Apr 15 '15 at 17:28
  • 6
    My Solution using this is ```git checkout --detach # detach the head``` and then ```git fetch origin \'+refs/heads/*:refs/heads/* ``` – Mike DuPont Jun 29 '15 at 15:09
  • 1
    This one worked for me, except I also use the --tags parameter. I wish there was a standard, simple front end for git, the number of simple things in git that need 10-plus stack overflow answers is ridiculous! – kristianp Feb 18 '16 at 23:13
  • 1
    @kristianp Have you checked out Ungit or GitKraken? – dragon788 Apr 27 '16 at 20:33
  • @dragon788 I've been using SourceTree for a git GUI, but I was really talking about a simpler command-line for scripting tasks. – kristianp Apr 29 '16 at 04:28
  • @kristianp ahh, I get you. You might look at something like easygit, https://people.gnome.org/~newren/eg/ – dragon788 Apr 30 '16 at 17:32
  • You could also probably do a `git clone .git` to just setup a bare repo without content. Then execute the OPs command: `git fetch origin '+refs/heads/*:refs/heads/*`. – ingyhere Jan 01 '17 at 17:47
  • @kristianp maybe try ungit - the philosophy is exactly what you've mentioned! – Bernardo Dal Corno Mar 01 '18 at 04:21
  • This is the only answer that works even when `remote..fetch` is setting to something restrictive. – Tgr Mar 10 '18 at 23:30
  • This helped after unshallowing - other answers didn't work for my repository which I originally pulled in a shallow mode. – Dan Oak Dec 13 '19 at 12:57
  • ***This does not track the remote branches. This is a wrong answer: Do not use this. This answer only copies the remote branches to your local repo.*** – basickarl Feb 04 '20 at 12:38
53

Use git fetch && git checkout RemoteBranchName.

It works very well for me...

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Regis Zaleman
  • 2,744
  • 5
  • 26
  • 30
  • 6
    This is the new best answer, y'all. I don't know if maybe this wasn't possible before, but recent versions of Git at least will notice that you are trying to checkout a remote branch and will automatically set up the local tracking branch for you (and you don't need to specify `origin/branch`; it suffices to say only `branch`). – Neil Traft Jun 27 '14 at 18:12
  • 9
    This does not answer the original question: "How would I pull all the branches locally?" It is pulling them one-by-one, which isn't scalable. – ingyhere Jan 01 '17 at 17:39
  • This was the only answer which allowed me to pull remote branches in every situation I've encountered – Emmanuel Buckshi Apr 19 '17 at 22:07
41

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, there is a much cleaner and quicker way, though it's a bit complicated. You need three steps to accomplish this:

  1. First step

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

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

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

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

    $ git reset --hard
    

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

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

unor
  • 82,883
  • 20
  • 183
  • 315
FedericoCapaldo
  • 1,270
  • 17
  • 28
32

You can fetch all the branches by:

git fetch --all

or:

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

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


To pull all the branches, use:

git pull --all

If above won't work, then precede the above command with:

git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'

as the remote.origin.fetch could support only a specific branch while fetching, especially when you cloned your repo with --single-branch. Check this by: git config remote.origin.fetch.

After that you should be able to checkout any branch.

See also:


To push all the branches to the remote, use:

git push --all

eventually --mirror to mirror all refs.


If your goal is to duplicate a repository, see: Duplicating a repository article at GitHub.

kenorb
  • 118,428
  • 63
  • 588
  • 624
26

I usually use nothing else but commands like this:

git fetch origin
git checkout --track origin/remote-branch

A little shorter version:

git fetch origin
git checkout -t origin/remote-branch
marioosh
  • 24,528
  • 42
  • 132
  • 181
24

You don't see the remote branches because you are not tracking them.

  1. Make sure you are tracking all of the remote branches (or whichever ones you want to track).
  2. Update your local branches to reflect the remote branches.

Track all remote branches:

Track all branches that exist in the remote repo.

Manually do it:

You would replace <branch> with a branch that is displayed from the output of git branch -r.

git branch -r
git branch --track <branch>

Do it with a bash script:

for i in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${i#*/} $i; done

Lazy way (this can create a mess due to merge conflicts, be careful):

git checkout master
git pull

Update information about the remote branches on your local computer:

This fetches updates on branches from the remote repo which you are tracking in your local repo. This does not alter your local branches. Your local git repo is now aware of things that have happened on the remote repo branches. An example would be that a new commit has been pushed to the remote master, doing a fetch will now alert you that your local master is behind by 1 commit.

git fetch --all

Update information about the remote branches on your local computer and update local branches:

Does a fetch followed by a merge for all branches from the remote to the local branch. An example would be that a new commit has been pushed to the remote master, doing a pull will update your local repo about the changes in the remote branch and then it will merge those changes into your local branch. This can create quite a mess due to merge conflicts.

git pull --all
basickarl
  • 25,903
  • 43
  • 172
  • 270
  • Single character variables are confusing. I suggest `for remoteBranch in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${remoteBranch#*/} $remoteBranch; done` – A. Rick Sep 24 '20 at 12:31
  • By using `xargs` instead of a `for` loop you won't need any variable at all. – bjhend Jan 20 '21 at 00:15
  • @bjhend Could you write an example and I'll be happy to update! – basickarl May 28 '21 at 07:29
  • @basickarl I'd replace the loop with something like `git branch -r | grep -vE "HEAD|master" | xargs -I remoteBranch -n 1 echo ...remoteBranch...` with `echo` replaced by the `git branch` command but I see now that the removal of the remote in remoteBranch will require some sort of `sed` command maybe making it more complicated. – bjhend May 28 '21 at 19:04
18

I believe you have cloned the repository by:

git clone https://github.com/pathOfrepository

Now go to that folder using cd:

cd pathOfrepository

If you type git status you can see all:

   On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

To see all hidden branch types:

 git branch -a

It will list all the remote branchs.

Now if you want to checkout on any particular branch just type:

git checkout -b localBranchName origin/RemteBranchName
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Abhinav bhardwaj
  • 2,205
  • 19
  • 21
16

If you are here seeking a solution to get all branches and then migrate everything to another Git server, I put together the below process. If you just want to get all the branches updated locally, stop at the first empty line.

git clone <ORIGINAL_ORIGIN>
git branch -r | awk -F'origin/' '!/HEAD|master/{print $2 " " $1"origin/"$2}' | xargs -L 1 git branch -f --track 
git fetch --all --prune --tags
git pull --all

git remote set-url origin <NEW_ORIGIN>
git pull
<resolve_any_merge_conflicts>
git push --all
git push --tags
<check_NEW_ORIGIN_to_ensure_it_matches_ORIGINAL_ORIGIN>
ingyhere
  • 8,842
  • 3
  • 28
  • 41
  • 3
    Very helpful; exactly what I needed. The only thing I had to change was in the second line, added single quotes around 'HEAD' and 'master'; probably because I'm using zsh. Thanks! – sockmonk Apr 15 '14 at 16:10
  • This is basically doing the following: (1) Obtaining the actual names of remote branches [not head, not master]; (2) Completely telling Git to track them [not all solutions do this]; (3) Fetching and pulling everything from these branches [including tags]; (4) Setting a new origin and walking through pushing absolutely everything up. Again, most of the other solutions fail to move all pieces. This does it all. – ingyhere Nov 23 '15 at 23:37
  • 1
    I removed the antipattern of running grep then awk and condensed the grep commands into the awk command. Thanks [tripleee](http://stackoverflow.com/users/874188/tripleee)! – ingyhere Jan 31 '17 at 20:29
  • Read this and never write `git fetch git pull` https://stackoverflow.com/a/292359/1114926 – Green Jun 20 '18 at 06:32
  • Git `pull` does indeed do a `fetch` first but it's easier to tell if the problem is from the `fetch` part of `pull` or the subsequent `merge` part of `pull` when `fetch` is executed independently. – ingyhere Aug 07 '18 at 23:00
13

Make sure all the remote branches are fetchable in .git/config file.

In this example, only the origin/production branch is fetchable, even if you try to do git fetch --all nothing will happen but fetching the production branch:

[origin]
fetch = +refs/heads/production:refs/remotes/origin/production

This line should be replaced by:

[origin]
fetch = +refs/heads/*:refs/remotes/origin/*

Then run git fetch etc...

Ahmad
  • 448
  • 5
  • 10
  • 3
    To inspect: `git config --get remote.origin.fetch` and then to (destructively) set it: `git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'` – qneill Sep 21 '17 at 22:00
  • or modify config text file in .git directory, worked for me – FDIM Oct 26 '17 at 09:13
12

After you clone the master repository, you just can execute

git fetch && git checkout <branchname>
eebbesen
  • 4,760
  • 7
  • 46
  • 67
Davidacce
  • 195
  • 1
  • 4
  • 1
    simple. and worked to get a branch from remote origin – sirvon Sep 21 '15 at 04:26
  • 3
    This does not answer the original question: "How would I pull all the branches locally?" It is pulling them one-by-one, which isn't scalable. Consider the case of 100 branches. – ingyhere Jan 01 '17 at 17:41
10

How to Fetch All Git Branches Tracking Single Remote.

This has been tested and functions on Red Hat and Git Bash on Windows 10.


TLDR:

for branch in `git branch -r|grep -v ' -> '|cut -d"/" -f2`; do git checkout $branch; git fetch; done;

Explanation:

The one liner checks out and then fetches all branches except HEAD.

List the remote-tracking branches.

git branch -r

Ignore HEAD.

grep -v ' -> '

Take branch name off of remote(s).

cut -d"/" -f2

Checkout all branches tracking a single remote.

git checkout $branch

Fetch for checked out branch.

git fetch

Technically the fetch is not needed for new local branches.

This may be used to either fetch or pull branches that are both new and have changes in remote(s).

Just make sure that you only pull if you are ready to merge.


Test Setup

Check out a repository with SSH URL.

git clone git@repository.git

Before

Check branches in local.

$ git branch
* master

Execute Commands

Execute the one liner.

for branch in `git branch -r|grep -v ' -> '|cut -d"/" -f2`; do git checkout $branch; git fetch; done;

After

Check local branches include remote(s) branches.

$ git branch
  cicd
  master
* preprod
Greg Weigner
  • 121
  • 1
  • 6
9

Looping didn't seem to work for me and I wanted to ignore origin/master. Here's what worked for me.

git branch -r | grep -v HEAD | awk -F'/' '{print $2 " " $1"/"$2}' | xargs -L 1 git branch -f --track

After that:

git fetch --all
git pull --all
poxion
  • 862
  • 10
  • 13
  • 1
    A variation of this is the correct answer, but this one does not work in all edge cases. Also, the branch names can be funky. So I did the following: git branch -r | grep -v HEAD | grep –v master | awk -F'origin/' '{print $2 " " $1"origin/"$2}' | xargs -L 1 git branch -f --track ; git fetch --all ; git pull --all ; AND THAT DID THE TRICK! – ingyhere Feb 05 '14 at 23:49
  • 3
    A stylistic improvement to avoid the `grep | awk` [antipattern](http://www.iki.fi/era/unix/award.html#grep): `git branch -r | awk -F 'origin/' '!/HEAD|master/{` ... – tripleee Nov 13 '15 at 11:14
9

Just these three commands will get all the branches:

git clone --mirror repo.git  .git     (gets just .git  - bare repository)

git config --bool core.bare false

git reset --hard
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
  • This is actually the root of OP's problem. If cloned right, he wouldn't need to do a `pull --all`. But if still needed, then the other answer bellow, by @Johnno Nola, assuming all branches are tracked, mixed with this answer, is the way to go. – DrBeco Mar 13 '19 at 02:51
4

I wrote a little script to manage cloning a new repo and making local branches for all the remote branches.

You can find the latest version here:

#!/bin/bash

# Clones as usual but creates local tracking branches for all remote branches.
# To use, copy this file into the same directory your git binaries are (git, git-flow, git-subtree, etc)

clone_output=$((git clone "$@" ) 2>&1)
retval=$?
echo $clone_output
if [[ $retval != 0 ]] ; then
    exit 1
fi
pushd $(echo $clone_output | head -1 | sed 's/Cloning into .\(.*\).\.\.\./\1/') > /dev/null 2>&1
this_branch=$(git branch | sed 's/^..//')
for i in $(git branch -r | grep -v HEAD); do
  branch=$(echo $i | perl -pe 's/^.*?\///')
  # this doesn't have to be done for each branch, but that's how I did it.
  remote=$(echo $i | sed 's/\/.*//')
  if [[ "$this_branch" != "$branch" ]]; then
      git branch -t $branch $remote/$branch
  fi
done
popd > /dev/null 2>&1

To use it, just copy it into your git bin directory (for me, that’s C:\Program Files (x86)\Git\bin\git-cloneall), then, on the command line:

git cloneall [standard-clone-options] <url>

It clones as usual, but creates local tracking branches for all remote branches.

tstone2077
  • 484
  • 4
  • 13
4

For Windows users using PowerShell:

git branch -r | ForEach-Object {
    # Skip default branch, this script assumes
    # you already checked-out that branch when cloned the repo
    if (-not ($_ -match " -> ")) {
        $localBranch = ($_ -replace "^.*?/", "")
        $remoteBranch = $_.Trim()
        git branch --track "$localBranch" "$remoteBranch"
    }
}; git fetch --all; git pull --all
ujeenator
  • 18,173
  • 2
  • 19
  • 27
kiewic
  • 14,245
  • 11
  • 71
  • 90
  • This works with branches with / in the name: `git branch -r | ForEach-Object { # Skip default branch, this script assumes # you already checked-out that branch when cloned the repo if (-not ($_ -match " -> ")) { $localBranch = ($_ -replace "^.*?/", "") $remoteBranch = $_.Trim() git branch --track "$localBranch" "$remoteBranch" } }` – Markus Mar 19 '19 at 15:44
4

Here's something I'd consider robust:

  • Doesn't update remote tracking for existing branches
  • Doesn't try to update HEAD to track origin/HEAD
  • Allows remotes named other than origin
  • Properly shell quoted
for b in $(git branch -r --format='%(refname:short)'); do
  [[ "${b#*/}" = HEAD ]] && continue
  git show-ref -q --heads "${b#*/}" || git branch --track "${b#*/}" "$b";
done
git pull --all

It's not necessary to git fetch --all as passing -all to git pull passes this option to the internal fetch.

Credit to this answer.

Tom Hale
  • 25,410
  • 16
  • 132
  • 172
4

Set alias: (based on the top answer)

git config --global alias.track-all-branches '!git fetch --all && for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done && git fetch --all'

Now to track all the branches:

git track-all-branches

Trake Vital
  • 133
  • 5
3

If you have problems with fetch --all then track your remote branch:

git checkout --track origin/%branchname%
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
open-ecommerce.org
  • 1,674
  • 24
  • 38
3
|‾‾‾‾‾‾‾‾‾‾‾‾‾fetch/clone‾‾‾‾‾‾‾‾‾‾‾‾↓   |‾‾‾‾‾‾‾‾‾‾‾‾checkout‾‾‾‾‾‾‾‾‾‾↓   
|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾pull‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾↓
Remote repository (`origin`) <=> Local repository <=> Index <=> Workspace
↑_________________push_______________|   ↑____commit____|  ↑____add_____| 

# 拉取远程仓库所有分支信息 → 本地仓库
# fetch all remote repository branch meta → local repository
git remote set-branches origin '*'
git fetch -v

# 把所有远程分支数据搞到本地
# fetch all remote repository branch data → local repository
git branch -r | grep -v '\->' | while read remote; do git branch "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all
山茶树和葡萄树
  • 1,167
  • 1
  • 12
  • 14
1

We can put all branch or tag names in a temporary file, then do git pull for each name/tag:

git branch -r | grep origin | grep -v HEAD| awk -F/ '{print $NF}' > /tmp/all.txt
git tag -l >> /tmp/all.txt
for tag_or_branch in `cat /tmp/all.txt`; do git checkout $tag_or_branch; git pull origin $tag_or_branch; done
anhlc
  • 11,441
  • 4
  • 28
  • 37
1

Here's a Perl version of the one-liner provided in the accepted answer:

git branch -r | perl -e 'while(<>) {chop; my $remote = $_; my ($local) = ($remote =~ /origin\/(.*)/); print "git branch --track $local $remote\n";}' > some-output-file

You can run the output file as a Shell script if you'd like.

We deleted our Stash project repository by accident. Fortunately someone had created a fork right before the accidental loss. I cloned the fork to my local (will omit the details of how I did that). Once I had the fork fully in my local, I ran one one-liner. I modified the remote's URL (origin in my case) to point to the target repository we were recovering to:

git remote set-url origin <remote-url>

And finally pushed all branches to origin like so:

git push --all origin

and we were back in business.

Jose Quijada
  • 339
  • 1
  • 10
1

To avoid the error message 'fatal: A branch named 'origin/master' already exists.', you may try my solution:

git branch -r | grep -v '\->'  | grep -v `git branch | awk '/\*/ { print $2; }'`| while read remote; do git branch --track "${remote#origin/}" "$remote"; done
ChrisZZ
  • 701
  • 6
  • 15
1

Have tried many ways, only this one is simple and works for me.

for branch in $(git ls-remote -h git@<your_repository>.git | awk '{print $2}' | sed 's:refs/heads/::')
do
  git checkout "$branch"
  git pull
done
bfontaine
  • 14,702
  • 12
  • 64
  • 87
TangHongWan
  • 326
  • 1
  • 3
  • 11
1

you can fetch all braches by this one line command like this:

git fetch --all && git pull --all && git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
dave4jr
  • 676
  • 8
  • 14
Muhammad Numan
  • 12,108
  • 1
  • 25
  • 50
0

Based on the answer by Learath2, here's what I did after doing git clone [...] and cd-ing into the created directory:

git branch -r | grep -v master | awk {print\$1} | sed 's/^origin\/\(.*\)$/\1 &/' | xargs -n2 git checkout -b

Worked for me but I can't know it'll work for you. Be careful.

erikano
  • 9
  • 1
0
git remote add origin https://yourBitbucketLink

git fetch origin

git checkout -b yourNewLocalBranchName origin/requiredRemoteBranch (use tab :D)

Now locally your yourNewLocalBranchName is your requiredRemoteBranch.

Baris Demiray
  • 1,277
  • 22
  • 31
0

For Visual Studio Users, On Package Manager console:

git branch | %{ git fetch upstream; git merge upstream/master}
ppwater
  • 2,277
  • 4
  • 8
  • 25
Jose Ortega
  • 887
  • 11
  • 20