Git Merge vs Rebase - 解决冲突

时间:2016-04-18 10:00:30

标签: git merge workflow rebase git-merge-conflict

这有点长,但我认为这可能是一个有趣的问题。

我们刚刚开始在我们公司使用git,尽管有很多人不愿意在小项目中开始使用git,现在我们实际上正在使用它更相关的项目。

我总是尝试在合并之前做一个rebase,但就在最近我们发现了这种方法的问题。

想象一下,你有一个文件F,你有以下git历史记录:

(master)       F -- F''1
                \
(feature)        \- F'1 -- ... -- F'X

现在,如果你对功能分支做了一个rebase,并且在解决了第一个冲突时,你实际上保留了F''1和F'1的变化,你将不得不手动解决文件F的X冲突,因为git无法自动解决它们。 相反,如果您刚刚进行了合并(没有重新定位),则必须解决一个(“大”)冲突。这让我质疑变基的实际价值,因为这可能是一项非常繁琐的工作。

我错过了什么,或者这就是它的方式?如果您在一个文件上有30个提交,则必须通过每个提交并手动解决任何冲突。有没有更合适的方法来处理这种情况?

我很抱歉,如果我没有很好地解释,但你可以尝试复制我在虚拟存储库中提到的步骤,我想你会得到什么在困扰我。

1 个答案:

答案 0 :(得分:7)

你是对的:你必须保持重新解决冲突,通常是一样的。

然而,有一个自动化旋钮用于执行此操作,称为git rerere。三个重新 -s代表重新使用重新有线重新解决方案。

这种方式的工作方式是每次遇到冲突时,以及git add解析后的版本,git都会保存原始冲突(减去行号)和某些文件中的分辨率(实际上只是blob)存储库中的对象)。然后,在宣布冲突之前,合并代码检查原始冲突是否已经与解决方案相关联。如果是,则用该分辨率替换冲突区域。

由于在记录冲突之前删除了行号,因此通常 - 虽然并非总是 - 处理重复冲突。 (当周围的上下文发生变化时,它会失败,因为这会更改冲突/解决方案对的哈希ID。)

这有点危险,因为有时冲突看起来相同但远在文件中发生,并不是真正相同的冲突(这往往会发生在模板代码中)。由于记录了每个冲突和分辨率,您可以积累大量分辨率并获得错误匹配。 Git尝试通过在60天内到期记录的分辨率(以及仅在15天内未解决的冲突)来处理此问题。

您必须在创建第一个冲突之前启用rerere,并在git add分辨率时启用它。这有点令人讨厌,因为通常你(我,我)发现我可能应该早些时候启用rerere,现在为时已晚。我一直试图编写一个脚本,使用我现有的分辨率重复我之前已经解决的先前合并或变换,以进行重新重放以填充重新引擎。 (此脚本的明显名称是git-rererere ... :-))