Git:如何一次重新设置多个分支(具有相同的基本提交)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/866218/
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-19 03:40:52  来源:igfitidea点击:

Git: How to rebase many branches (with the same base commit) at once?

gitrebasegit-rebase

提问by malvim

I have a master branch in my project, that I use to pull changes from other people. From that, I usually have several topic branches on which I'm currently working.

我的项目中有一个主分支,我用来从其他人那里提取更改。从那以后,我通常有几个我目前正在研究的主题分支。

My question is: Is there a way for me to pull new changes into my master and then rebase ALL of my topic branches onto that at once?

我的问题是:有没有办法让我将新更改拉入我的 master 中,然后立即将我的所有主题分支变基到它上面?

This is the situation:

情况是这样的:

        D--E topic1
       /
A--B--C  master
       \
        F--G topic2

And I want to accomplish this with one single command (H came from upstream) :

我想用一个命令来完成这个(H 来自上游):

               D'--E' topic1
              /
    A--B--C--H  master
              \
               F'--G' topic2

Now, I know I can accomplish this by rebasing topic1 and topic2 onto master, and I could even write a script to automate this. But what if I have several other branches, create new ones and delete others frequently and I receive upstream changes all the time?

现在,我知道我可以通过将 topic1 和 topic2 重新设置为 master 来实现这一点,我什至可以编写一个脚本来自动执行此操作。但是,如果我有几个其他分支,经常创建新分支并删除其他分支并且我一直收到上游更改怎么办?

This operation (several rebases), when done by hand, is both tiring and error-prone.

这个操作(几个 rebases),当手工完成时,既累人又容易出错。

Is there an easier way?

有更容易的方法吗?

Thanks!

谢谢!

采纳答案by araqnid

I'm fairly sure that there isn't a way to automatically do this. Remember that "git rebase master" can also drop you back to the shell needing you to resolve merge conflicts, so if you want to write a script to automate all this you need to take that into account.

我相当确定没有办法自动执行此操作。请记住,“git rebase master”也可以让您回到需要您解决合并冲突的 shell,因此如果您想编写一个脚本来自动化所有这些,您需要考虑到这一点。

You can fairly easily track which branches need updating, though. Hmm, for any branch, "git rev-list branch..master" will produce output if the branch is not up-to-date wrt (i.e. just commits on top of) master. So you need to loop through all the local heads except master to produce a report (nb "git show-branch" will approximately do this):

不过,您可以相当轻松地跟踪哪些分支需要更新。嗯,对于任何分支,“git rev-list branch..master”如果分支不是最新的wrt(即只是在master之上提交)将产生输出。因此,您需要遍历除 master 之外的所有本地 head 以生成报告(nb "git show-branch" 大约会执行此操作):

git for-each-ref 'refs/heads/*' | \
  while read rev type ref; do
    branch=$(expr "$ref" : 'refs/heads/\(.*\)' )
    revs=$(git rev-list $rev..master)
    if [ -n "$revs" ]; then
      echo $branch needs update
      git diff --summary --shortstat -M -C -C $rev master
    fi
  done

So if you were feeling brave, you could replace that "git diff" with something like "git checkout $branch && git rebase master" (or maybe just "git pull --rebase" if you've set that up). I think you'd then have to check for the existence of a ".git/rebase-apply" directory or check the index for unmerged files ("git ls-files -u") to test if we've been left waiting to do a merge.

因此,如果您感到勇敢,可以将“git diff”替换为“git checkout $branch && git rebase master”之类的内容(或者,如果您已设置,则可能只是“git pull --rebase”)。我想你然后必须检查“.git/rebase-apply”目录的存在或检查未合并文件的索引(“git ls-files -u”)来测试我们是否一直在等待做一个合并。

Of course, if there are no conflicts, then it's easy... it's producing something that also works when it's not easy that's the problem :p

当然,如果没有冲突,那么这很容易......它产生的东西在不容易的时候也可以工作,这就是问题:p

And this doesn't necessarily address what happens if one of your branches is based on something else... that's why I mentioned using "git pull --rebase" instead, because that would rebase according to the branch configuration, not blindly from master. Although the detection isn't based on the branch configuration... maybe it would be easiest just to check out each branch and do "git pull" and let the branch configuration handle everything, including whether to rebase or merge?

这不一定解决如果你的一个分支基于其他东西会发生什么......这就是为什么我提到使用“git pull --rebase”来代替,因为这会根据分支配置重新定位,而不是盲目地从主. 虽然检测不是基于分支配置......也许最简单的方法是检查每个分支并执行“git pull”并让分支配置处理所有事情,包括是变基还是合并?

回答by flacs

You can always just write a shell one-liner like this:

你总是可以像这样写一个 shell one-liner:

for branch in topic1 topic2 topic3;do git rebase master $branch;done

Since the topic branches you would like to rebase will probably change over time, this is a quick-and-dir^H^H^Hflexible solution :-)

由于您想要重新定位的主题分支可能会随着时间的推移而改变,这是一个快速而直接的^H^H^Hflexible 解决方案:-)

回答by Ingo Karkat

I have turned this into a robust script, maintained in my git-extensions repository:

我已经把它变成了一个健壮的脚本,在我的 git-extensions 存储库中维护:

$ git-urebaselocalbr --help
Rebase all / the last committed N local branches (except for the current branch
and master) to the updated upstream head.
Usage: git-urebaselocalbr [--continue|--skip|--abort] [--branches "<branch1> ..."] [N] [-i|--interactive] [options]