通过重命名其中一个文件解决 git 合并冲突
Resolve git merge conflict by renaming one of the files
我使用 Flyway 来跟踪数据库更改,git 用于版本控制。
Flyway 依赖于迁移脚本,这些脚本在每次迁移时以递增的数字命名。
现在我遇到以下情况:两个功能是在两个独立的分支(我们称它们为 A 和 B)上开发的,都需要更改数据库。两位开发人员都为他们的分支机构创建了一个数据库迁移脚本。当他们大约在同一时间从 master 分支出来时,他们都为迁移脚本分配了相同的文件名:V42__migration.sql
.
现在分支A已经合并到master了。合并分支 B 时,由于 V42__migration.sql
文件,我陷入了合并冲突。解决这个冲突的正确方案是将分支 B 的迁移脚本重命名为 V43__migration.sql
。然而,在合并时 git 试图将两个文件合并为一个,我实际上需要两个文件都保持不变,但一个重命名。
解决这种与 git 的合并冲突的最佳方法是什么?
一旦 git 报告冲突,您将收到提示并完全能够以您需要的任何方式编辑索引以解决冲突。因此,如果您要合并 feature_x
,您可以:
1) 获取分支的脚本并将其命名为V43
git checkout feature_X -- V42__migration.sql
mv V42__migration.sql V43__migration.sql
2) 从之前合并的commit中获取V42脚本
git checkout HEAD -- V42__migration.sql
3) 确保索引正确更新并完成合并
git add .
git commit
下一步要考虑的另一件事是,您真的不希望 git 尝试合并这些文件。因此,您可以使用 .git 属性将文件标记为二进制文件,或将自定义合并类型应用于它们。我假设像 whatever/path/to/V*__migration.sql
这样的模式可以识别文件。
这个想法是,如果 git 认为它必须合并这样的路径,它应该自动标记冲突并且它应该选择一个或另一个版本作为暂定解决方案。解决冲突的人只需将另一个版本放在适当的位置。
从逻辑上讲,在合并期间保留 "ours" 是有意义的,因为这是最终将获得该文件名的版本。如果将路径标记为二进制,就会发生这种情况。
但如果保持 "theirs".
,实用的解决方案会更简单
mv conflicted_file next_filename
git checkout HEAD -- conflicted_file
所以您可能想在 gitattributes
文档中查找如何创建自定义合并驱动程序。 (这并不像听起来那么难;驱动程序可以类似于 cp %B %A && false
。所以只需几个配置命令。)
您有分支 A
和 B
,它们都包含一个同名文件,但在 master
中不存在。将 A
合并到 master
工作正常,当您合并 B
时,您会遇到合并冲突。
$ git checkout master
$ git merge A # OK
$ git merge B # CONFLICT (add/add): Merge conflict in file
这样的合并冲突如下所示。
<<<<<<< HEAD
AAA
=======
BBB
>>>>>>> B
现在您可以再次拆分这些文件并将文件从分支 B
重命名为 V43__migrate.sql
,而不是合并这些文件。要删除模式之间的线条,可以使用 sed
,如下所示。
$ 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
*NIX Tricks: [sed] Delete the lines lying in between two patterns
如果您不依赖未合并分支上的拆分提交,squash 分支上的所有提交都将合并为一个提交。
您必须强制推送到您的分支 git push -f
(旧提交被新提交覆盖并替换)。
重命名未合并分支中的文件并修改 git commit --ammend
您的更改。修改也需要强推.
如果您不压缩提交,这可能会更棘手。
我使用 Flyway 来跟踪数据库更改,git 用于版本控制。
Flyway 依赖于迁移脚本,这些脚本在每次迁移时以递增的数字命名。
现在我遇到以下情况:两个功能是在两个独立的分支(我们称它们为 A 和 B)上开发的,都需要更改数据库。两位开发人员都为他们的分支机构创建了一个数据库迁移脚本。当他们大约在同一时间从 master 分支出来时,他们都为迁移脚本分配了相同的文件名:V42__migration.sql
.
现在分支A已经合并到master了。合并分支 B 时,由于 V42__migration.sql
文件,我陷入了合并冲突。解决这个冲突的正确方案是将分支 B 的迁移脚本重命名为 V43__migration.sql
。然而,在合并时 git 试图将两个文件合并为一个,我实际上需要两个文件都保持不变,但一个重命名。
解决这种与 git 的合并冲突的最佳方法是什么?
一旦 git 报告冲突,您将收到提示并完全能够以您需要的任何方式编辑索引以解决冲突。因此,如果您要合并 feature_x
,您可以:
1) 获取分支的脚本并将其命名为V43
git checkout feature_X -- V42__migration.sql
mv V42__migration.sql V43__migration.sql
2) 从之前合并的commit中获取V42脚本
git checkout HEAD -- V42__migration.sql
3) 确保索引正确更新并完成合并
git add .
git commit
下一步要考虑的另一件事是,您真的不希望 git 尝试合并这些文件。因此,您可以使用 .git 属性将文件标记为二进制文件,或将自定义合并类型应用于它们。我假设像 whatever/path/to/V*__migration.sql
这样的模式可以识别文件。
这个想法是,如果 git 认为它必须合并这样的路径,它应该自动标记冲突并且它应该选择一个或另一个版本作为暂定解决方案。解决冲突的人只需将另一个版本放在适当的位置。
从逻辑上讲,在合并期间保留 "ours" 是有意义的,因为这是最终将获得该文件名的版本。如果将路径标记为二进制,就会发生这种情况。
但如果保持 "theirs".
,实用的解决方案会更简单mv conflicted_file next_filename
git checkout HEAD -- conflicted_file
所以您可能想在 gitattributes
文档中查找如何创建自定义合并驱动程序。 (这并不像听起来那么难;驱动程序可以类似于 cp %B %A && false
。所以只需几个配置命令。)
您有分支 A
和 B
,它们都包含一个同名文件,但在 master
中不存在。将 A
合并到 master
工作正常,当您合并 B
时,您会遇到合并冲突。
$ git checkout master
$ git merge A # OK
$ git merge B # CONFLICT (add/add): Merge conflict in file
这样的合并冲突如下所示。
<<<<<<< HEAD
AAA
=======
BBB
>>>>>>> B
现在您可以再次拆分这些文件并将文件从分支 B
重命名为 V43__migrate.sql
,而不是合并这些文件。要删除模式之间的线条,可以使用 sed
,如下所示。
$ 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
*NIX Tricks: [sed] Delete the lines lying in between two patterns
如果您不依赖未合并分支上的拆分提交,squash 分支上的所有提交都将合并为一个提交。
您必须强制推送到您的分支 git push -f
(旧提交被新提交覆盖并替换)。
重命名未合并分支中的文件并修改 git commit --ammend
您的更改。修改也需要强推.
如果您不压缩提交,这可能会更棘手。