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'