198

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

$ 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

我已经用谷歌搜索和 RTM,但到目前为止已经出现了铺位。

4

16 回答 16

194

Otto给出的答案很好,但是所有创建的分支都会以“origin/”作为名称的开头。如果您只想将最后一部分(最后一个 / 之后)作为结果分支名称,请使用以下命令:

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

它还有一个好处是不会给你任何关于模棱两可的参考的警告。

于 2010-06-23T07:15:08.623 回答
136

使用 bash:

在 git 1.9.1 之后
for i in `git branch -a | grep remote | grep -v HEAD | grep -v master`; do git branch --track ${i#remotes/origin/} $i; done

学分: Val Blant、埃利亚斯和雨果

在 git 1.9.1 之前

注意:以下代码如果用在更高版本的 git (>v1.9.1) 中会导致

  1. (bug)所有创建的分支来跟踪master
  2. (烦恼)所有创建的本地分支名称都以origin/
for remote in `git branch -r `; do git branch --track $remote; done

更新分支,假设您的本地跟踪分支没有更改:

for remote in `git branch -r `; do git checkout $remote ; git pull; done

忽略模棱两可的 refname 警告,git 似乎更喜欢本地分支。

于 2008-12-19T01:03:15.847 回答
27

这里的大多数答案都过于复杂化输出的解析git branch -r。您可以使用以下for循环针对远程上的所有分支创建跟踪分支,如下所示。

例子

假设我有这些远程分支。

$ git branch -r
  origin/HEAD -> origin/master
  origin/development
  origin/integration
  origin/master
  origin/production
  origin/staging

确认我们没有在本地跟踪除 master 以外的任何内容:

$ git branch -l    # or using just git branch
* master

您可以使用这一行来创建跟踪分支:

$ for i in $(git branch -r | grep -vE "HEAD|master"); do 
    git branch --track ${i#*/} $i; done
Branch development set up to track remote branch development from origin.
Branch integration set up to track remote branch integration from origin.
Branch production set up to track remote branch production from origin.
Branch staging set up to track remote branch staging from origin.

现在确认:

$ git branch
  development
  integration
* master
  production
  staging

要删除它们:

$ git br -D production development integration staging 
Deleted branch production (was xxxxx).
Deleted branch development (was xxxxx).
Deleted branch integration (was xxxxx).
Deleted branch staging (was xxxxx).

如果您使用-vv开关,git branch您可以确认:

$ git br -vv
  development xxxxx [origin/development] commit log msg ....
  integration xxxxx [origin/integration] commit log msg ....
* master      xxxxx [origin/master] commit log msg ....
  production  xxxxx [origin/production] commit log msg ....
  staging     xxxxx [origin/staging] commit log msg ....

for循环的分解

循环基本上调用命令git branch -r,过滤掉输出中的任何 HEAD 或 master 分支grep -vE "HEAD|master"。为了只得到分支的名称减去origin/子字符串,我们使用 Bash 的字符串操作${var#stringtoremove}。这将从变量中删除字符串“stringtoremove” $var。在我们的例子中,我们origin/从变量中删除字符串$i

注意:或者,您也可以使用它git checkout --track ...来执行此操作:

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

但我并不特别关心这种方法,因为它会在执行结帐时在分支之间切换。完成后,它会将您留在它创建的最后一个分支上。

参考

于 2014-12-01T18:29:21.830 回答
24

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

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 中,使用 msysgit1.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
  • 它只会从您在remote变量中指定的远程选择上游分支(它可以是 ' origin' 或您为当前 Git 存储库的远程之一设置的任何名称)。
  • 它将提取分支的名称:origin/a/Branch/Name => a/Branch/Name通过awk表达式。
  • 它将通过--set-upstream-to(or -u)设置上游分支,而不是--track
    优点是,如果分支已经存在,它不会失败并且不会更改该分支来源,它只会配置branch.xxx.(remote|merge)设置。

    branch.aBranchName.remote=origin
    branch.aBranchName.merge=refs/heads/a/Branch/Name
    

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

于 2011-06-09T23:18:23.250 回答
15

你可以很容易地编写脚本,但我不知道它什么时候有价值。这些分支很快就会落后,你必须一直更新它们。

远程分支会自动保持最新,因此最简单的方法是在您实际想要处理的地方创建本地分支。

于 2008-12-18T20:48:39.057 回答
14

没有任何脚本(在一个空目录中):

$ git clone --bare repo_url .git
$ git config core.bare false
$ git checkout

之后,所有远程分支都将被视为本地分支。


原文(俄文)

于 2016-05-20T12:03:27.133 回答
10
for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done
于 2014-05-07T21:14:17.910 回答
8

如果您想使用 powershell 并且您的遥控器称为 origin。然后这行得通。

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}
于 2016-03-24T15:20:26.397 回答
4
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

使用这个,你不会有这样的警告: refname 'origin/dev' is ambiguous

于 2013-01-21T05:17:02.243 回答
4

这是我对@tjmcewan 引用的 BASH 命令的解决方案:

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
于 2017-05-05T08:17:49.367 回答
4

从 git 2.23 开始:

for branch in `git branch -r | grep origin/`; do git switch -t -C ${branch#origin/} $branch; git pull; done

如果-C标志git switch已经存在,则创建或重置。

git 切换文档

于 2020-02-07T13:51:17.913 回答
3

要与tjmcewan 的答案相同,但在 Windows 上,请从批处理文件中调用它:

for /f "delims=" %%r in ('git branch -r ^| grep -v master') do git checkout --track %%r

或者从命令行

for /f "delims=" %r in ('git branch -r ^| grep -v master') do git checkout --track %r
于 2014-09-04T19:38:10.417 回答
2

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

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

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

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

于 2020-12-18T20:12:40.507 回答
1

如果您已经签出一些分支机构并想要

  • 从远程检查所有剩余的分支
  • 确保所有本地分支都跟踪远程分支

您可以使用以下 bash 和 zsh 兼容的脚本:

git branch -r | while read b; do if git branch | grep -q " ${b##*/}$"; then git branch --set-upstream ${b##*/} $b; else git branch --track ${b##*/} $b; fi; done
于 2012-06-26T10:19:55.487 回答
1
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/' 成为本地分支的后缀。

于 2013-10-15T11:57:55.420 回答
1

使用 bash,如果要检查所有分支:

for remote in `git branch -r`; do git checkout $(echo $remote | cut -d'/' -f 2); done

重要的是要注意,当您执行 fetch 会关闭新的远程跟踪分支时,您不会自动拥有它们的本地、可编辑副本。

于 2018-09-04T01:05:36.820 回答