跟踪单个远程分支作为本地分支非常简单。

$ git checkout --track -b ${branch_name} origin/${branch_name}

将所有本地分支推到远程,根据需要创建新的远程分支也很容易。

$ git push --all origin

我想做相反的事情。如果我在一个源上有X个远程分支:

$ git branch -r 
branch1
branch2
branch3
.
.
.

我是否可以为所有这些远程分支创建本地跟踪分支,而不需要手动创建每个分支?可以这样说:

$ git checkout --track -b --all origin

我用谷歌搜索了一下,但到目前为止都是胡扯。


当前回答

VonC的解决方案可以通过改变sed进一步简化(我缺乏代表点直接评论他的帖子):

for branch in $(git branch -r | sed 's,[^/]*/,,g'); do git switch $branch; done

通过替换所有非斜杠直到最后一个斜杠的内容,剩余的分支名称适合本地使用;重复切换到同一个分支并不是错误(这可能效率较低,但可能比在管道中使用grep:->更有效)。

switch命令足够智能,可以根据需要跟踪每个远程分支。

其他回答

for rembranch in `git remote update 2>&1 > /dev/null ; git branch -r|egrep -wv "HEAD|master"`
do 
    git checkout --track -b `echo $rembranch|awk -F\/ '{print $2}'` $rembranch; 
done

解释:

第1行:'git branch -r'(后面跟着'git remote update'来更新远程更改的信息)列出所有远程分支;'egrep -vw'用于敲除结果中有HEAD和master的条目。

第3行:在本地签出时跟踪已命名的远程分支。使用一个简单的awk来避免'origin/'作为本地分支的后缀。

2020年第一季度更新:Mohsen Abasi在评论中提出了一个更简单的替代方案,基于2014年slm的答案:

for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); 

它使用$()而不是过时的反引号。

正如我在另一个旧答案中提到的,使用git for-each-ref可能更快。 我将使用新的(Git 2.23+) Git switch命令,它取代了令人困惑的Git签出。

for i in $(git for-each-ref --format=%(refname:short) \
  --no-merged=origin/HEAD refs/remotes/origin); do \
    git switch --track $i; \
done

这样就不需要grep了。


旧的(2011年)原始答案:

下面是我使用的一行程序(在bash shell中,用mssysgit1.7.4测试):

复制粘贴:

remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream-to $remote/$brname $brname; done

为了提高可读性:

remote=origin ; // put here the name of the remote you want
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do 
    git branch --set-upstream-to $remote/$brname $brname; 
done

it will only select upstream branches from the remote you specify in the remote variable (it can be 'origin' or whatever name you have set for one of the remotes of your current Git repo). it will extract the name of the branch: origin/a/Branch/Name => a/Branch/Name through the awk expression. it will set the upstream branch through --set-upstream-to (or -u), not --track: The advantage is that, if the branch already exists, it won't fail and it won't change that branch origin, it will only configure the branch.xxx.(remote|merge) setting. branch.aBranchName.remote=origin branch.aBranchName.merge=refs/heads/a/Branch/Name

该命令将为所有远程上游分支创建本地分支,并将它们的远程和合并设置设置为该远程分支。

Otto给出的答案很好,但是所有创建的分支都将“origin/”作为名称的开头。如果你只是想让最后一部分(在最后一个/之后)作为你的分支名称,使用这个:

for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done

它还有一个好处,就是不会给你任何关于模糊引用的警告。

以下是我的BASH命令引用@tjmcewan的解决方案:

for remote in `git branch -r | grep -v /HEAD `; do git branch --track ${remote/"origin/"/""}; done

我的目标是解决所有创建的分支都以“origin/”作为名称开头的问题,因为我测试了$remote变量仍然包括“origin/”:

for remote in `git branch -r | grep -v /HEAD`; do echo $remote ; done

如果你想使用powershell,你的遥控器叫做origin。这样就行了。

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}