How can I convert all the remote branches in a local git repo into local tracking branches, without one by one checking each one out.
One reason why you might want to do this (the reason I want to do this) is so that you can take a clone of the local repo and have in that new clone all the branches from the original remote origin.
Because "clone" only clones local branches.
Edit: a couple of scripted answers have been provided (for which - thanks!) ... I was really hoping for an in-git way, so that it is completely portable (I have users who are "windows only", and so far have survived without having to use a bash (git-bash or otherwise)).
The best way to do this probably is with a script:
#!/bin/bash
IFS=$'\n'
for branch in `git branch -r`; do
if [[ ${branch} =~ ^\ *(.+)/(.+)$ ]]; then
git show-branch "${BASH_REMATCH[2]}" > /dev/null 2>&1
if [ $? -ne 0 ]; then
git branch ${BASH_REMATCH[2]} ${BASH_REMATCH[1]}/${BASH_REMATCH[2]}
fi
fi
done
This answer was supplied to me by jast on #git at freenode:
git push . refs/remotes/origin/*:refs/heads/*
Note: as mentioned in the comment below, this does not create tracking branches, though it does at least make the branchs in the local repo be "local" and note "remote".
I think that @cforbish's answer could only be improved by saying that with that script you should produce commands like this:
# git branch <local-branch-name> <remote-name>/<remote-branch-name>
For example, if you have the following remote branches:
# git remote -v
remote-repo <repo-directory> (fetch)
remote-repo <repo-directory> (push)
# git branch -r
remote-repo/branch1
remote-repo/branch2
remote-repo/branch3
You could have your local tracking branches by running:
# git branch branch1 remote-repo/branch1
# git branch branch2 remote-repo/branch2
# git branch branch3 remote-repo/branch3
# git branch
branch1
branch2
branch3
I like shell-command-builders for stuff like this. This is uglier than the earlier version but it also works on bare-bones shells, and has the added advantage of getting the args on branch commands it builds in the right order so they actually work.
One thing -- scriplets like this are "in-git solutions".
git-track-all-remote-branches ()
{
awk '
$0=="////"{doneloading=1;next}
!doneloading {drop[$0]=1;next}
!drop[$0] {
print "b='\''"$0"'\''; git branch -t ${b##*/} $b"
}' <<///EOD///
$(git for-each-ref --format="%(upstream:short)" refs/heads)
////
$(git for-each-ref --format="%(refname:short)" refs/remotes)
///EOD///
}
A fairly recent checkout
feature is, if you checkout a bare name that isn't currently a branch, but matches exactly one remote branch, it'll automatically set up a tracking branch for it:
$ git branch
master
$ git branch -r
origin/notyet
origin/master
$ git checkout notyet
Checking out files: 100% (2/2), done.
Branch notyet set up to track remote branch notyet from origin.
Switched to a new branch 'notyet'