通过重命名其中一个文件来解决git合并冲突

通过重命名其中一个文件来解决git合并冲突,git,merge,merge-conflict-resolution,Git,Merge,Merge Conflict Resolution,我使用Flyway跟踪数据库更改,使用git进行版本控制 Flyway依赖于迁移脚本,每个迁移脚本的名称都是递增的 现在我遇到了以下情况:两个特性是在两个单独的分支上开发的(我们称它们为A和B),都需要更改数据库。两个开发人员都为其分支的数据库创建了迁移脚本。由于它们几乎同时从master分支,所以它们都为迁移脚本分配了相同的文件名:V42\uu migration.sql 现在,分支A被合并为主分支。合并分支B时,由于V42\u migration.sql文件,我陷入了合并冲突。解决此冲突的正

我使用Flyway跟踪数据库更改,使用git进行版本控制

Flyway依赖于迁移脚本,每个迁移脚本的名称都是递增的

现在我遇到了以下情况:两个特性是在两个单独的分支上开发的(我们称它们为A和B),都需要更改数据库。两个开发人员都为其分支的数据库创建了迁移脚本。由于它们几乎同时从master分支,所以它们都为迁移脚本分配了相同的文件名:
V42\uu migration.sql

现在,分支A被合并为主分支。合并分支B时,由于
V42\u migration.sql
文件,我陷入了合并冲突。解决此冲突的正确解决方案是将分支B的迁移脚本重命名为
V43\u migration.sql
。然而,在合并git时,它试图将两个文件合并到一个文件中,实际上我需要两个文件都保持不变,但其中一个文件被重命名


用git解决此类合并冲突的最佳方法是什么?

一旦git报告了冲突,您就可以立即以任何方式编辑索引,以解决冲突。因此,如果要在中合并
功能x
,您可以:

1) 获取分支的脚本并将其命名为V43

git checkout feature_X -- V42__migration.sql
mv V42__migration.sql V43__migration.sql
2) 从先前合并的提交中获取V42脚本

git checkout HEAD -- V42__migration.sql
3) 确保索引已正确更新并完成合并

git add .
git commit

另一件需要考虑的事情是,你不想让Git试图合并这些文件。因此,您可以使用.gittributes将文件标记为二进制文件,或对其应用自定义合并类型。我假设像

这样的模式,无论/path/to/V*\u migration.sql
如何识别文件

其想法是,如果git认为它必须合并这样一条路径,它应该自动标记冲突,并选择一个或另一个版本作为暂定解决方案。解决冲突的人只需将另一个版本放在适当的位置

从逻辑上讲,在合并过程中保留“我们的”是有意义的,因为这是最终获得该文件名的版本。如果将路径标记为二进制,则会发生这种情况

但如果你保留“他们的”,务实的解决方法会更简单


因此,您可能希望在
gittributes
文档中查找如何创建自定义合并驱动程序。(这并不像听起来那么难;驱动程序可能类似于
cp%B%A&&false
。因此只需几个配置命令即可。)

您有分支
A
B
,它们都包含一个同名文件,而
主文件中不存在该文件。将
A
合并到
master
中效果很好,当您合并
B
时,会出现合并冲突

$ git checkout master
$ git merge A             # OK
$ git merge B             # CONFLICT (add/add): Merge conflict in file
这样的合并冲突如下所示

<<<<<<< HEAD
AAA
=======
BBB
>>>>>>> B
$ sed '/<<<<<<< HEAD/,/======/d' V42__migration.sql | sed '/>>>>>>> B/d' > V43__migration.sql
$ sed '/======/,/>>>>>>> B/d' V42__migration.sql | sed '/<<<<<<< HEAD/d' > V42__migration.sql
然后您可以提交这些更改

$ git add V42__migration.sql V43__migration.sql
$ git commit

如果不依赖未合并分支上的拆分提交,则分支上的所有提交都将执行一次提交。 您必须强制推送到您的分支
git push-f
(旧提交将被覆盖并替换为新提交)

重命名未合并分支中的文件,并ammend
git commit--ammend
更改。安眠药也需要用力推


如果没有压缩提交,这可能会更棘手。

我建议不要使用sed或其他技术来“取消合并”文件。Git会根据请求愉快地检查原始文件,这样就不会有弄糟的风险。
squash
ing提交只会丢弃历史
amend
ing分支头将起作用,但在合并期间修复问题更有意义。我完全避免了文件中的冲突。如果您不需要分支上的历史记录(例如,因为您希望对已完成的功能进行一次提交),则它绝对有效。不,告诉某人要解决一个问题,需要创建另一个问题(您认为这无关紧要)是无效的。即使修改是正确的解决方案,挤压也是不必要的。至于为什么
amend
不是正确的解决方案:重命名的目的是解决合并问题。如果合并了不同的内容(顺便说一句,当您继续调整分支中的内容时,可能会发生这种情况),那么重命名将不同。在合并中解决合并冲突,而不是试图预测和“避免”冲突,是更好的解决方案;你不会让我相信合并冲突解决应该发生在合并之外的任何地方。历史是完全可用的;“额外工作量”是
-m
标志。而且,这都不能证明你的虚假陈述是正确的,即OP应该压缩提交——即使
modify
是正确的解决方案,也不需要提交。(说到不能有效保存历史的事情……)
$ git add V42__migration.sql V43__migration.sql
$ git commit