[git] How to fetch all Git branches

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

This question is related to git branch git-branch

The answer is

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

|?????????????fetch/clone?????????????   |????????????checkout???????????   
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

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:

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

This line should be replaced by:

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

Then run git fetch etc...

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

After you clone the master repository, you just can execute

git fetch && git checkout <branchname>

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

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

You can fetch all the branches by:

git fetch --all


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.

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

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

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

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

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

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

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:


# 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)
echo $clone_output
if [[ $retval != 0 ]] ; then
    exit 1
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
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.

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.

Use git fetch && git checkout RemoteBranchName.

It works very well for me...

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.

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.

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 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
git push --all
git push --tags

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

git checkout --track origin/%branchname%

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.

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.

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/::')
  git checkout "$branch"
  git pull

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 


git merge origin/branch-name


git checkout -b some-branch origin/branch-name

To list remote branches:
git branch -r

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

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

How to Fetch All Git Branches Tracking Single Remote.

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


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


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 [email protected]


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;


Check local branches include remote(s) branches.

$ git branch
* preprod

For Visual Studio Users, On Package Manager console:

git branch | %{ git fetch upstream; git merge upstream/master}

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";
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.

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.

Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to branch

Get git branch name in Jenkins Pipeline/Jenkinsfile Why do I have to "git push --set-upstream origin <branch>"? Your configuration specifies to merge with the <branch name> from the remote, but no such ref was fetched.? When does Git refresh the list of remote branches? Fix GitLab error: "you are not allowed to push code to protected branches on this project"? Git push: "fatal 'origin' does not appear to be a git repository - fatal Could not read from remote repository." Git: Merge a Remote branch locally git pull from master into the development branch Depend on a branch or tag using a git URL in a package.json? How can I copy the content of a branch to a new local branch?

Examples related to git-branch

How do I rename both a Git local and remote branch name? How do I create a master branch in a bare Git repository? git switch branch without discarding local changes Git: Merge a Remote branch locally Why call git branch --unset-upstream to fixup? Create a remote branch on GitHub How can I display the current branch and folder path in terminal? Git merge master into feature branch Delete branches in Bitbucket Creating a new empty branch for a new project