如何在git中合并具有不同目录层次结构的两个分支?


77

我开始将Maven与Web应用程序项目一起使用,因此目录层次结构发生了变化。我为Maven集成创建了一个新分支。现在,我有两个分支,一个分支具有旧目录层次结构,另一个分支具有maven目录层次结构。两个分支都有新的提交(错误修复和新功能)。

我想摆脱旧分支并将其更改合并到Maven分支。Git合并产生了无数无法解决的冲突。我相信这是因为文件路径已更改。

进行此合并的最佳方法是什么?


10
就像其他读者知道的那样:这些问题的典型错误消息是too many files skipping inexact rename detection
Nils Werner

Answers:


165

尝试merge.renameLimit为此合并设置较高的值。git尝试检测重命名,但仅在文件数量低于此限制时才进行,因为它需要O(n ^ 2)处理时间:

git config merge.renameLimit 999999

然后完成时:

git config --unset merge.renameLimit

8
请注意,在增加了renameLimit之后,我必须运行“ git merge --abort”,以便可以重试拉。否则,这就是窍门。
leontx 2012年

27

博客文章“ Confluence,git,重命名,合并哦,我的…… ”添加了一些有趣的信息,这些信息说明了Robie答案(已推荐):

尝试检测重命名时,git使用以下命令区分精确重命名和不精确重命名

  • 前者是重命名而不更改文件的内容,并且
  • 后者的重命名可能包括对文件内容的更改(例如,重命名/移动Java类)。

这种区别很重要,因为用于检测精确重命名的算法是线性的,并且将始终执行,而用于不精确重命名检测的算法是二次方(O(n^2)),并且如果更改的文件数超过某个阈值(1000个,则git不会尝试执行此操作)默认)。

如果未明确设置,则merge.renameLimit默认为1000个文件或将diff.renameLimitif设置为该值。
diff.renameLimit影响git diffgit showgit log同时merge.renameLimit适用于合并的尝试(git mergegit cherry-pick)只。

这是一个好主意来改变merge.renameLimit,而不是改变diff.renameLimit,这样Git并不试图找到在喜欢仰望常见的操作重命名git diff输出。

要显示重命名,类似git show或的命令git log可以与-M启用重命名检测的选项一起使用。

Linus提到

是的,对于内核,我有

    [diff]
            renamelimit=0

完全禁用该限制,因为默认限制确实非常低。Git非常擅长重命名检测。

但是,默认值偏低的原因并不是因为它不够灵敏-是因为它最终可能会占用大量内存(如果内存不足,则交换将意味着它会从“相当快”变为“像糖蜜一样慢”-但它仍然不受CPU的限制,就像疯狂的分页一样。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.