由于冲突,使用--preserve-merges的Git rebase无法重新应用合并提交

3
假设以下是 git 历史记录:
 M (master) <- merge that required resolving a conflict, e.g. coming from F and G
 | \
 |  |
 F  G
 |  | 
 C  D  <- commit to edit (D), unrelated to the merge conflict (e.g. adding a new file)
 |  |
 | /
 B
 |
 A  <- initial commit

我想要做的是编辑提交 D(重写历史记录)。我使用命令git rebase --interactive --preserve-merges A master,标记提交D进行编辑,在重新定位停止时进行编辑,修改提交并执行git rebase --continue
M提交之前,我收到了解决冲突的请求。这些冲突已经在将分支合并到M时解决,因此我希望重新定位可以顺利进行。
$ git rebase --continue
Auto-merging yet-another-test.txt
CONFLICT (content): Merge conflict in yet-another-test.txt
Automatic merge failed; fix conflicts and then commit the result.
Error redoing merge d01ffb203aae9ef450ae7a863de5fce2ed5184bb

您可以在这里找到示例,您可以尝试使用git rebase -i -p 8b58 master命令并编辑30c7提交。
我询问的原因是因为我的真实存储库的Git历史记录相当复杂,沿途有很多合并(总共约300个提交),而我需要编辑的提交靠近最初的提交,因此我想保留历史记录(避免压缩),但我不想再次解决所有冲突。
有更好的方法吗?
已在Git for Windows 2.17.1(最新版)上测试。

1
以这种方式进行重写将会很复杂,如果不是不可能的话。为什么不在一个分支上修复您需要修复的内容,然后再合并呢?最终结果不是一样吗? - Liam
原因是我希望重写历史记录 - 隐藏最初提交中放入的数据,但仍保留完整的更改历史记录。 - patryk
非常复杂,有很多合并操作,并且我需要编辑的提交接近初始提交。当你进行重写时,你需要重新应用所有上游的更改,而不仅仅是你正在重写的修订版本。所以那300个提交都需要重新做。这真的不太实际。 - Liam
我知道,如果它不起作用,我将需要另一种方法来摆脱变更历史。然而,这个问题的关键是:为什么 Git 无法重新应用包含已解决冲突的合并提交? - patryk
1个回答

2
Git默认不记录先前的合并决策,这就是为什么当rebase必须重新创建一个合并提交时,您会看到完全相同的冲突的原因。
Error redoing merge d01ffb203aae9ef450ae7a863de5fce2ed5184bb

这就是git-rerere(重用记录的解决方案)发挥作用的地方:
该命令通过在初始手动合并时记录冲突自动合并结果和对应的手动解决结果,并将先前记录的手动解决方案应用于其相应的自动合并结果,来协助开发人员完成此过程。
为了让Git开始记录合并解决方案,您需要首先通过以下命令在您的存储库(或全局)中启用rerere
git config rerere.enabled true

或者

git config --global rerere.enabled true

很不幸,在这种特定情况下它不能帮助你节省时间,因为在此期间你已经解决了各种合并提交中的冲突,但是以后会有所不同。
编辑:实际上,似乎有一种方法可以通过运行一个名为rerere-train的shell脚本记录现有合并提交中的先前解决方案。不过我自己还没有尝试过,所以可能会有所不同。

让整个代码库正常工作需要什么条件?所有贡献者都需要在自己的机器上启用rerere吗?在远程服务器(例如GitHub)上合并又如何呢? - patryk
rerere记录的冲突解决方案被存储在本地(.git/rr-cache目录中),并且不会传输到远程仓库。所以,是的,每个贡献者都需要在他们的机器上启用它,而且不会自动与团队的其他成员共享已记录的解决方案。然而,有一些解决方法可供参考。 - Enrico Campidoglio
如果没有这样的解决方法,例如在 GitHub 上进行远程合并将会被阻止,对吗? - patryk
我不确定我理解了 - 你所说的“discouraged”是什么意思? - Enrico Campidoglio
如果我在GitHub上合并拉取请求,rerere数据会被记录吗? - patryk
我会说不,尽管我找不到任何文件来确认这一点。无论如何,我不会指望GitHub在他们的服务器端存储库上启用rerere功能。 - Enrico Campidoglio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接