如何一次对多个分支(具有相同的基础提交)进行变基?

发布于 2024-07-20 10:00:46 字数 568 浏览 8 评论 0原文

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

我的问题是:有没有办法让我将新的更改拉入我的主控中,然后立即将我的所有主题分支重新设置为基础?

情况是这样的:

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

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

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

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

如果手动完成此操作(多次变基),既累人又容易出错。

有更容易的方法吗?

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?

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) :

               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?

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

Is there an easier way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

野味少女 2024-07-27 10:00:47
git branch | sed 's/\*/ /g' | xargs -n1 git rebase master
git branch | sed 's/\*/ /g' | xargs -n1 git rebase master
记忆之渊 2024-07-27 10:00:46

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

不过,您可以相当轻松地跟踪哪些分支需要更新。 嗯,对于任何分支,如果该分支不是最新的(即仅在 master 之上提交),“git rev-listbranch..master”将生成输出。 因此,您需要循环遍历除 master 之外的所有本地头来生成报告(注意“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

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

当然,如果没有冲突,那就很容易......它生成的东西在不容易的情况下也能工作,这就是问题所在:p

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

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.

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

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

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?

时光磨忆 2024-07-27 10:00:46

你总是可以像这样编写一个 shell 语句:

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

由于你想要变基的主题分支可能会随着时间的推移而改变,这是一个快速和 dir^H^H^H 灵活的解决方案:-)

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

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 :-)

十六岁半 2024-07-27 10:00:46

如果您想将所有本地分支重新设置为master,您可以尝试以下操作:

git branch | cut -c 3- | for branch in $(cat); do git rebase master $branch; done

If you would like to rebase all local branches onto master, you could try this:

git branch | cut -c 3- | for branch in $(cat); do git rebase master $branch; done
独自唱情﹋歌 2024-07-27 10:00:46

我已将其变成一个强大的脚本,维护在 我的 git-扩展存储库

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

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

$ 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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文