如何撤消git rebase和redo作为git merge

时间:2014-02-14 00:25:57

标签: git git-merge git-rebase undo-redo

我在分支上运行了一个git rebase并修复了所有冲突,然后意识到这个特定的分支我需要运行git merge来保留历史记录。有没有办法“撤消”rebase但在运行git merge时自动重新应用我的修复程序?

1 个答案:

答案 0 :(得分:0)

作为Amber said in a comment,如果你打开rerere,git将“重新”记录你之前的“重新”解决方案(三个re中的两个)。然后,如果你将事物重置为预先重组状态和“git merge”,它应该“重新”使用它们(最后一个“重新”)。

但如果不是,那就不会。

该怎么办?假设你对你的解决方案非常有信心:-)你可以试试这个。

ORIG_HEAD可能仍然指出原始提交链(pre-rebase)。如果没有,请在reflogs中找到旧的branch-tip。给它一个标签(分支或标签名称),同时在post-rebase链上保留一个标签。也就是说,我们希望复活旧的分支尖端,并保留新的分支尖端。 (确切为什么一旦理解了其余部分就应该是显而易见的。)

我会假设您在重新定位时修改了提交CF,并完全删除了DE,因为不再需要。并不是说这真的很重要。 F'是唯一重要的提交。关键是提交F'捕获工作树的“最终,全部解析”版本:

        C - D - E - F   <-- feature_orig
      /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature

以上是您执行git branch feature_orig ORIG_HEAD后可以看到的内容(或从reflog中恢复原始提示并使用该提示创建feature_orig)。

您现在想要的(根据原始问题)是合并:“将功能合并到主线”或“将主线合并到功能中”。除此之外,您希望它发生在/ feature_orig上,而不是重生的feature

另一个问题是:你想保持feature分支吗? (如果你在这里将mainline合并到feature,你可能会这样做。如果将功能合并到主线,可能不会。但最多,我怀疑你会想要保留feature_orig,而不是我们现在再推动一个分支名称了 - 我希望 - 让图片更加清晰:

$ git branch -m feature feature_rebased

现在我们有了这个:

        C - D - E - F   <-- feature_orig
      /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature_rebased

现在进行合并。进入您希望合并提交显示在分支上的分支:

$ git checkout ...

(我不知道这是哪个分支,feature_origmainline!)

然后进行合并,忽略结果而不提交:

$ git merge --no-commit ...

(你合并的任何一个分支)。

现在只需使用从提交F'获取的版本替换每个文件(注意,我假设您在此处位于顶级工作目录中):

$ git rm -rf .; git checkout feature_rebased -- .

rm步骤完全清空索引,包括所有冲突,以及工作树。然后checkout步骤使用提交F'中的任何内容(通过分支名称feature_rebased获得)完全重新填充索引和工作树。

您现在可以在您所在的任何分支上提交合并。为了具体,让我们说你在feature_orig,并要求git合并mainline。在您git commit之后,您应该将此作为提交图表:

        C - D - E - F - M  <-- feature_orig
      /               /
A - B - G - H - I - J   <-- mainline
                      \
                        C' - F'  <-- feature_rebased

我认为值得一提的是,只是提交图的内容 - 当您git checkout任何提交时,您在工作目录中获得的文件 - 由当时的索引/登台区域的内容决定。提交已创建。

这是为什么我们可以git rm一切然后git checkout id -- .来设置合并提交的内容。我们提交合并时所做的就是创建一个提交M,其父项为FJ,其内容为“索引中现在的任何内容”。

(父级FJ顺序,以及写入新提交ID的分支名称,取决于我们在哪个分支上我们开始并完成git merge流程。如果我们“在分支机构feature_orig上,则F是第一个父级,M进入”分支feature_orig“。如果我们“在分支mainline上,则J是第一个父级,M在分支mainline上”。当然,还有准备好的提交文本,您可以在提交发生之前进行编辑,但有点不同。但您可以编辑它以阅读您喜欢的任何内容。)


此时(或者甚至更早),如果您想保留名称,现在可以将feature_orig重命名为feature。您还可以删除分支feature_rebased,因为无需再保存提交C'F'。事实上,我们只是想继续F'以便我们可以git checkout它的树 - 我们可以在完成checkout后立即删除分支。