How can I convert all the remote branches in a loc

2019-04-11 02:35发布

问题:

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

回答1:

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


回答2:

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



回答3:

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


回答4:

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'