How do I fetch all Git branches?

Asked 2023-09-20 20:34:49 View 155,966

I cloned a Git repository containing many branches. However, git branch only shows one:

$ git branch
* master

How would I pull all the branches locally so when I do git branch, it shows the following?

$ git branch
* master
* staging
* etc...
  • Also discussed at stackoverflow.com/questions/67699/… - anyone
  • This question shows how to get all branches after using the --single-branch setting when cloning: stackoverflow.com/questions/17714159/… (git fetch --all will never work if you've specified only one branch!) - anyone
  • 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. - anyone
  • 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 <repo url> .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. - anyone
  • @GabrielFerraz Then you are abusing the comment functionality on Stack Overflow. Users can upvote your comment but not downvote. - anyone

Answers

TL;DR answer

git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | 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.

Complete answer

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 '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

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.

Answered   2023-09-20 20:34:49

  • 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. - anyone
  • that fetch wouldn't create a new remote branch you still need to check it out with git checkout -b localname remotename/remotebranch - anyone
  • 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. - anyone
  • 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. - anyone
  • For the Windows folks: for /F %remote in ('git branch -r') do ( git branch --track %remote) && git fetch --all && git pull --all - anyone

To list remote branches:

git branch -r

To checkout a remote branch as a local branch:

git checkout -b local_branch_name origin/remote_branch_name

Answered   2023-09-20 20:34:49

  • 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. - anyone
  • Even if the branch is not visible locally, I can do git checkout remotebranchnameand it works. what's the difference with your solution? - anyone
  • 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. - anyone
  • The accepted answer does something fundamentaly different and to be frank I don't even understand why its the accepted answer - anyone
  • The OP asked for all branches. This answer only does one. - anyone

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.

Answered   2023-09-20 20:34:49

  • 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 - anyone
  • 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. - anyone
  • 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?" - anyone
  • @JosephK perhaps your remote is not called origin? See this answer which will work on all remote names. - anyone
  • @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. - anyone

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

Answered   2023-09-20 20:34:49

  • 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! - anyone
  • Fixed (eliminated --all) - anyone
  • 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. - anyone
  • --all means "all remotes", not "all branches of a given remote". The latter is implied by any fetch from a remote. - anyone
  • This is not the way to pull all branches into local repo, from remote repo. - anyone
$ 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.

Caution: mind the warnings below (all remotes will track the same local branch main).

Answered   2023-09-20 20:34:49

  • When I try that I still get the same result as above. - anyone
  • Same as @JacobLowe, I got the error, but it worked anyway; 'fatal: A branch named 'origin/master' already exists.' - anyone
  • 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 for a fix. - anyone
  • A small improvement to exclude error on HEAD branch: for REMOTE in git branch -r | grep -v HEAD; do git branch --track ${REMOTE}; done . - anyone
  • The command to track remote branches does not work at all. It created a bunch of branches that all pointed to the last master commit. - anyone

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.

Answered   2023-09-20 20:34:49

  • 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 <SHA> - anyone
  • My Solution using this is git checkout --detach # detach the head and then git fetch origin \'+refs/heads/*:refs/heads/* - anyone
  • 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! - anyone
  • @kristianp Have you checked out Ungit or GitKraken? - anyone
  • @Pegues I think a lot of confusion resides in how tracking works and it's role in updating your local repo. You are by all means correct, the command in this post does do a fetch, but if you are not tracking the branches it won't fetch them. I guess my comment for more for beginners. - Also the way you mentioned to update a branch is 100% legit, but there are other ways of doing it aswell^^ - anyone

Use git fetch && git checkout RemoteBranchName.

It works very well for me...

Answered   2023-09-20 20:34:49

  • 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). - anyone
  • 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. - anyone
  • This was the only answer which allowed me to pull remote branches in every situation I've encountered - anyone

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.

Answered   2023-09-20 20:34:49

  • Upvoted for mention of hidden branches. helped me understand the local branch tracking immensely. - anyone
  • Its a good answer, but the question implies something for every day use. Its not practical to clone the repository everytime. - anyone
  • Why the reset creates all the branches locally? - anyone
  • @Z.Khullah it's not the reset that creates all the branches, but the clone --mirror. Unfortunately for us, that also creates a bare repo, which is what steps 2 and 3 change. - anyone

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.

Answered   2023-09-20 20:34:49

  • Awesome...I tried everything else before your solution in this page. Thanks a lot! - anyone
  • I used shallow cloning (depth=1) and the config also specified one specific branch for fetch - the depth=1000 parameter was the fix that helped me to checkout a specific remote branch - anyone
  • pull --all doesn't pull all the branches, but all the remotes - anyone
  • Nice trick with the config, though! Would fetch them all, all the time - anyone
  • I checked config as you wrote, still only works with current branch. Looks like all answers here do not work for me... - anyone

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

Answered   2023-09-20 20:34:49

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|main/{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>

Answered   2023-09-20 20:34:49

  • 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! - anyone
  • 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. - anyone
  • I removed the antipattern of running grep then awk and condensed the grep commands into the awk command. Thanks tripleee! - anyone
  • Read this and never write git fetch git pull stackoverflow.com/a/292359/1114926 - anyone
  • 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. - anyone

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

Answered   2023-09-20 20:34:49

  • Single character variables are confusing. I suggest for remoteBranch in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${remoteBranch#*/} $remoteBranch; done - anyone
  • By using xargs instead of a for loop you won't need any variable at all. - anyone
  • @bjhend Could you write an example and I'll be happy to update! - anyone
  • @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. - anyone
  • This seems to have created a mess for me. I believe what needs to be mentioned is that before each round of commands one needs to checkout an appropriate branch. - anyone

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

  • To inspect: git config --get remote.origin.fetch and then to (destructively) set it: git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*' - anyone
  • or modify config text file in .git directory, worked for me - anyone

After you clone the master repository, you just can execute

git fetch && git checkout <branchname>

Answered   2023-09-20 20:34:49

  • simple. and worked to get a branch from remote origin - anyone
  • 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. - anyone

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

Answered   2023-09-20 20:34:49

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

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

  • 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! - anyone
  • A stylistic improvement to avoid the grep | awk antipattern: git branch -r | awk -F 'origin/' '!/HEAD|master/{ ... - anyone

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

Answered   2023-09-20 20:34:49

  • 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" } } - anyone

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.

Answered   2023-09-20 20:34:49

  • I'm trying to replicate this in another scripting language (Typescript) but don't understand the bash syntax ${b#*/} - can someone explain the meaning please? - anyone
  • Found a useful resource devhints.io/bash which shows ${STR#*/} expands to the full path of STR (i.e. b in the above code). - anyone
  • Also note that from a Windows cmd prompt, git branch -r --format='%(refname:short)' will output quote marks ('), so use double-quotes : git branch -r --format="%(refname:short)" - anyone

Be careful while playing with git, go step by step.

$ git remote update  //This will update your local
$ git branch -a      //This will list all the branches(After updating you can now 
see the new branch in the list)
$ git checkout your_branch_name

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

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.

Answered   2023-09-20 20:34:49

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

git checkout --track origin/%branchname%

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

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

Answered   2023-09-20 20:34:49

TLDR It is likely a bad idea to create a local branch for each remote tracking branch. These different types of branches serve different purposes and local branches are normally created based on their need. git branch shows local branches git branch -r shows the remote tracking branches. git branch -a shows both. You can update all remote tracking branches with an appropriate fetch command. That should usually be all you need.


After scrolling through the existing answers I see two kinds: those simply answering the question asked, rather than suggesting a different approach. And those suggesting a different approach without explaining why. Here is my attempt to explain a bit more.

There are actually three kinds of branches a usual git repository needs to deal with. These three kinds of branches serve different purposes. In short:

  • remote branches: These are the branches as they exist in the remote repository. You will never read from remote branches directly. All reading of remote branches happens through gits so called "remote tracking branches"

  • remote tracking branches: git keeps local snapshots of the remote branches which are most accurately called "remote tracking branches". They are updated when you call git fetch or git pull (which does a fetch). You can often get away with using the remote tracking branches without creating local branches out of them.

    For example:

    git merge origin/master
    

    will merge the remote tracking branch origin/master into the current local branch without requiring you to create a local copy of it first. This means: there is a remote tracking branch called origin/master which is a snapshot of the branch called master as it exists on the remote repository called origin. And this command will merge it into the current checked-out local branch. You may want to do a fetch before performing operations like this.

  • local branches: these are manually created snapshots of certain points in history (often based on remote tracking branches, at least at first). They are much more static than the other kinds and will really only change when you manually change them. One by one. You will likely want a local branch if you want to view its contents in your working-tree (project directory) or when you want to add commits to it.

Once you are done with a local branch (and published its contents) you may consider deleting it. That way you do not need to keep it up to date. After all, a fetch will not update the current local branch, and a pull will only update the current checked-out local branch. In other words: you should only create local branches when you need them, and you should probably delete them when you no longer do.

It is probably not accurate to say that 'some branches are hidden by default'. Rather the git branch command was created to show you the "local branches". You can use git branch -r to list the remote tracking branches and git branch -a to show both the local branches and the remote tracking branches. These two different types of branches serve a different purpose and you are not likely to need a local branch for each remote tracking one.

Also note that is is generally a bad idea to create local branches whose names begin with the name of a remote followed by a slash (eg creating a local branch called "origin/master" tends to be a bad idea since its name conflicts with the name of the remote tracking branch).

In the context of updating branches, it does make sense to discuss different flavours of fetch commands:

  • git fetch: updates only the remote tracking branches whose remote matches the one used in the "upstream" of the current checked out branch. If the checked out branch does not have an upstream set, this falls back to fetching from a remote called "origin" if it exists. This command is the easiest, and is sufficient most of the time.
  • git fetch --all: updates all remote tracking branches regardless of the remote they belong are snapshotting from.

I am especially fond of

git fetch -tf --all

Which will also always update (and override if needed) all tags, including tags not reachable from the remote branches.

Answered   2023-09-20 20:34:49