跟踪所有远程git分支作为本地分支

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

$ 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

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

91663 次浏览

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

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

使用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, elias和Hugo

git 1.9.1之前

注意:下面的代码如果在git (>v1.9.1)的后续版本中使用会导致

  1. (错误)所有创建的分支跟踪主
  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似乎更喜欢本地分支。

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

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

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

2020年Q1更新: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.

. 0
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
  • 它只会从你在remote变量中指定的远程中选择上游分支(它可以是'origin'或你为当前Git回购的一个远程设置的任何名称)。
  • 它将通过awk表达式提取分支的名称:origin/a/Branch/Name => a/Branch/Name
  • 它将设置上游分支通过__ABC0(或-u),而不是--track:
    这样做的好处是,如果分支已经存在,它不会失败,也不会改变分支的起源,它只会配置branch.xxx.(remote|merge)设置

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

That command will create local branches for all remote upstream branches, and set their remote and merge setting to that remote branch.

以防您已经签出了一些分支并想要

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

您可以使用以下兼容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
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

使用这个,你将不会有这样的警告:refname 'origin/dev'是模糊的

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/'作为本地分支的后缀。

for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done

要在Windows上执行与tjmcewan的回答相同的操作,请从批处理文件调用此函数:

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

或者this来自命令行:

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

这里的大多数答案都使解析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,使用grep -vE "HEAD|master"过滤输出中的任何HEAD或主分支。为了只得到分支的名称减去origin/子字符串,我们使用Bash的字符串操作${var#stringtoremove}。这将从变量$var中删除字符串"stringtoremove"。在本例中,我们从变量$i中删除字符串origin/

另外,你也可以使用git checkout --track ...来实现:

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

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

参考文献

  • < a href = " http://tldp.org/LDP/abs/html/string-manipulation.html " > 10.1。操作字符串-高级Bash脚本指南
  • . 3.5 Git分支-远程分支 .

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

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

不需要任何脚本(在空目录中):

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

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


原文(俄语)

以下是我的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
使用bash < p >, 如果你想签出所有分支:

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

需要注意的是,当您获取新的远程跟踪分支时,并不会自动获得它们的本地可编辑副本。

从git 2.23开始:

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

git switch-C标志创建或重置已经存在的-C标志。

git switch文档 .

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

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

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

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