【问题标题】:rebase reverted merged branch变基还原合并分支
【发布时间】:2013-08-30 01:01:49
【问题描述】:

背景:我最近将一个相当大的主题分支合并到master。几天后,我发现这个主题分支包含错误。所以我git revert -m 1 <merge-commit>了它。

问题:现在我想查看主题分支并将其重新设置为当前的master,以便我可以 1)修复错误和 2)(再次)合并已修复与主的主题分支。创建新分支fixedtopic 是很容易的部分,但每次我都这样做

git checkout fixedtopic
git rebase master

git 决定它不愿意重放旧的提交,因为它们已经合并到 master 中。相反,它只是做一个快进变基。

问题:如何使用rebase 强制将提交重播到fixedtopic?我可以吗?我宁愿不使用cherry-pick,因为它有点麻烦。

补充:

  • git reseting 合并提交它不是一个选项,因为我已将 master 推送到上游。
  • 我宁愿不从master 创建一个新分支并还原我的还原。这样做的原因是我想使用交互式 rebase 重写一些主题分支的历史。
  • 这里是该场景的 github 要点:https://gist.github.com/JensRantil/6352495 请注意,我希望将 e8df5ec 和 ee16464 应用于 master(或基于 master 的分支)。

【问题讨论】:

  • 我和一位同事最近在功能分支上遇到了同样的问题。我们的解决方案或多或少与接受的解决方案相同,但我们选择将分支中的所有提交压缩为单个提交。这在功能上等同于还原还原,这最终更简单。只是给那些将来面临这个问题的人的注意事项。
  • git revert 和 git rebase 都引用了描述如何处理此问题的 [revert-a-faulty-merge How-To][1]

标签: git merge


【解决方案1】:

您需要使用--onto 来防止 Git 表单尝试自行确定适当的未合并提交。

例如(已签出主题分支):

git rebase --onto master <id-of-branch-point>

对于&lt;id-of-branch-point&gt;,您需要主题分支的git merge-base,并在您还原的合并之前在master 上提交。

编辑

再次重新阅读您的情况,如果您将主题分支快进到恢复合并的点,然后恢复恢复并从中修复主题分支,可能会更好观点。这样,您将不会重复原始主题分支中的所有提交,而是在 master 的最终历史记录中使用新的 id。无论你做什么,你最终都会得到一个涉及“做、撤消、重做”的历史,但是这样可能被认为是一个更干净的历史。

【讨论】:

  • 查尔斯,感谢您的回答。即使使用--onto,我仍然无法完成这项工作。我已经用 Github gist 更新了我的问题,以提供我所处情况的工作示例。
【解决方案2】:

实现此目的的一种方法是交互式地重新设置主题分支并在分支出主分支后重新编写第一个提交(例如,git rebase -i HEAD~10,如果您在分支中有 10 个提交)。这将重写主题分支内所有提交的 sha。因此,您将能够使用 git rebase master 以通常的方式变基。

【讨论】:

  • 为了帮助澄清:“reword the first commit”是指提交message
  • 你也可以使用 --no-ff 选项,它做同样的事情。
  • 谢谢,这是唯一对我有用的方法(Git 2.15)。 --no-ff 什么也没做,但更改提交消息就像一个魅力。
  • 这对我不起作用,即使提交消息已被修改(git 2.22),它在尝试重新设置基准时仍在尝试执行 noop。
【解决方案3】:

似乎最好的办法是检查一个新分支,然后通过还原 revert 来恢复以前的工作分支。

我尝试过的所有其他方法都过于复杂和/或不起作用。

【讨论】:

    【解决方案4】:

    文档(git help rebase)建议“git rebase --force-rebase”这样做——但(Git 1.9.1)它没有。文档也建议“git rebase -i --no-ff”等同于该命令——但它不是:它确实工作。

    克隆了你的要点,命令:

      git checkout topic
      git rebase -i --no-ff --onto master 7b3af topic
    

    产生期望的结果,新版本的“第三”和“第四”提交在主之上,topic 指向新版本的“第四”。在第二个命令中,SHA 7b3af 是“第二个”提交,topic 的分支点。

    【讨论】:

      【解决方案5】:

      对于git merge(即不是最初要求的git rebase),按照7.8 Git Tools - Advanced Merging(参见“撤销提交”部分):

      解决此问题的最佳方法是取消还原原始合并,因为现在您想要引入已还原的更改,然后创建一个新的合并提交:

      $ git revert ^M

      &lt;...&gt;

      $ git merge topic

      图 142. 重新合并还原合并后的历史记录

      【讨论】:

        【解决方案6】:

        使用git 2.22,jurglic 建议的解决方案似乎不再有效。

        让我们从状态开始,以确保我们谈论的是同一件事:

        P---o---o---M---o---o---o---o---o---W---o---o---master
         \         /     \                /
          A---B---C       D (revert A-B-C)
        

        我创建了一个带有A-B-C 提交的开发分支,它被合并到M,但我们立即注意到有一个错误,所以它被恢复到W。我想在 master 上重新设置 A-B-C 并在再次合并之前修复该问题。

        这是我所做的:

        git checkout C          (detached HEAD) 
        git checkout -b redo
        git rebase -i master
        

        但在这一点上,git 只提供了以下内容:

        noop
        
        # Rebase A..C onto X (1 command)
        

        这意味着它发现我正在尝试重新应用完全相同的提交并且它们已经被合并。

        为了解决这个问题,jurglic 建议修改A 的提交消息,但似乎git 2.22 足够聪明,可以解决这个问题,并且仍然为我提供完全相同的noop。我尝试了其他解决方案,使用--force-rebase 和/或--no-ff,但我一直回到noop。

        最后,我在rebase -i 选择编辑器中手动输入一个简单的快捷方式,并将noop 替换为:

        pick A
        pick B
        pick C
        

        或者,如果您想节省更多击键次数:

        p A
        p B
        p C
        

        这终于奏效了。

        【讨论】:

        • 这是唯一适用于当前(截至 2020 年 1 月 21 日)版本的 git 的答案。
        • 非常感谢。解决同一问题的最简单和最好的方法
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-29
        • 2021-10-16
        • 2017-03-09
        • 1970-01-01
        • 2013-06-03
        • 2013-05-23
        相关资源
        最近更新 更多