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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/379081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:02:30  来源:igfitidea点击:

Track all remote git branches as local branches

gitbranch

提问by Janson

Tracking a single remote branch as a local branch is straightforward enough.

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

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

Pushing all local branches up to the remote, creating new remote branches as needed is also easy.

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

$ git push --all origin

I want to do the reverse. If I have X number of remote branches at a single source:

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

$ git branch -r 
branch1
branch2
branch3
.
.
.

Can I create local tracking branches for all those remote branches without needed to manually create each one? Say something like:

我可以为所有这些远程分支创建本地跟踪分支而无需手动创建每个分支吗?像这样说:

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

I've googled and RTMs, but have come up bunk thus far.

我已经用谷歌搜索过和 RTM,但到目前为止还没有找到。

采纳答案by Otto

Using bash:

使用 bash:

after git 1.9.1git 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

credits:Val Blant, elias, and Hugo

学分:瓦尔布兰特、埃利亚斯和雨果

before git 1.9.1在 git 1.9.1 之前

Note:the following code if used in later versions of git (>v1.9.1) causes

  1. (bug) All created branches to track master
  2. (annoyance) All created local branch names to be prefixed with origin/

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

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

Update the branches, assuming there are no changes on your local tracking branches:

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

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

Ignore the ambiguous refname warnings, git seems to prefer the local branch as it should.

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

回答by tjmcewan

The answer given by Otto is good, but all the created branches will have "origin/" as the start of the name. If you just want the last part (after the last /) to be your resulting branch names, use this:

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

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

It also has the benefit of not giving you any warnings about ambiguous refs.

它还具有不给您任何关于不明确引用的警告的好处。

回答by slm

Most of the answers here are over complicating the parsing of the output of git branch -r. You can use the following forloop to create the tracking branches against all the branches on the remote like so.

这里的大多数答案都使git branch -r. 您可以使用以下for循环针对远程上的所有分支创建跟踪分支,如下所示。

Example

例子

Say I have these remote branches.

假设我有这些远程分支。

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

Confirm that we're not tracking anything other than master already, locally:

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

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

You can use this one liner to create the tracking branches:

您可以使用这个衬垫来创建跟踪分支:

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

Now confirm:

现在确认:

$ git branch
  development
  integration
* master
  production
  staging

To delete them:

要删除它们:

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

If you use the -vvswitch to git branchyou can confirm:

如果您使用-vvswitch 到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 ....

Breakdown of for loop

for循环分解

The loop basically calls the command git branch -r, filtering out any HEAD or master branches in the output using grep -vE "HEAD|master". To get the names of just the branches minus the origin/substring we use Bash's string manipulation ${var#stringtoremove}. This will remove the string, "stringtoremove" from the variable $var. In our case we're removing the string origin/from the variable $i.

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

NOTE:Alternatively you can use git checkout --track ...to do this as well:

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

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

But I don't particularly care for this method, since it's switching you among the branches as it performs a checkout. When done it'll leave you on the last branch that it created.

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

References

参考

回答by VonC

Update Q1 2020: Mohsen Abasiproposes in the comments, based on the 2014 slm's answer, the simpler alternative:

更新Q1 2020:穆赫辛·阿巴西提出的意见的基础上,2014年SLM答案,更简单的选择:

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

And it uses $()instead of obsolete backticks.

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

As I mention in another old answer, using git for-each-refis probably faster.
And I would use the new (Git 2.23+) git switchcommand, which replaces the confusing git checkout.

正如我在提到另一个老答案,使用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

That way, no grepneeded.

这样,就grep不需要了。



Old (2011) original answer:

旧(2011)原始答案:

Here is my one-liner I use (in a bash shell, tested with msysgit1.7.4):

这是我使用的单行(在 bash shell 中,使用 msysgit1.7.4 测试):

For copy-paste:

对于复制粘贴:

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

For more readability:

为了提高可读性:

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(/^[^\/]+\//,"",); print }'
`; do 
    git branch --set-upstream-to $remote/$brname $brname; 
done
  • it will only select upstream branches from the remote you specify in the remotevariable (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/Namethrough the awkexpression.
  • 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
    
  • 它只会从您在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
    

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

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

回答by Dustin

You could script that easily enough, but I don't know when it'd be valuable. Those branches would pretty quickly fall behind, and you'd have to update them all the time.

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

The remote branches are automatically going to be kept up to date, so it's easiest just to create the local branch at the point where you actually want to work on it.

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

回答by aleksandr barakin

without any scripting (in an empty directory):

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

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

after that, all remote branches will be seen as local.

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



original (in russian).

原文(俄文)

回答by Val Blant

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

回答by BigMiner

If you want to use powershell and your remote is called origin. Then this works.

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

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

回答by Nick Tsai

Here is my solution of BASH command referring by @tjmcewan:

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

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


My goal is to solve the problem that all the created branches will have "origin/" as the start of the name, because I tested that $remote variables are still include "origin/":

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

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

回答by bruziuz

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

Use this and you will not have such warning as: refname 'origin/dev' is ambiguous

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