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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4722423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:53:06  来源:igfitidea点击:

How to merge two branches with different directory hierarchies in git?

gitmergegit-merge

提问by anssias

I started using Maven with a web application project so the directory hierarchy changed. I created a new branch for the Maven integration. Now I have two branches one with the old directory hierarchy and one with the maven directory hierarchy. Both branches have new commits (bugfixes and new features).

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

I would like to get rid of the old branch and merge it's changes to the Maven branch. Git merge gives countless conflicts that feels like impossible to resolve. I believe that this is because file paths have changed.

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

What is the best way to approach this merge?

处理这种合并的最佳方法是什么?

回答by Robie Basak

Try setting merge.renameLimitto something high for this merge. git tries to detect renames, but only if the number of files is below this limit, since it requires O(n^2) processing time:

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

git config merge.renameLimit 999999

then when done:

然后完成后:

git config --unset merge.renameLimit

回答by VonC

The blog post "Confluence, git, rename, merge oh my… " adds some interesting information which illustrates Robie's answer(upvoted):

博客文章“ Confluence,git,rename,merge oh my...”添加了一些有趣的信息来说明Robie答案(已投票):

When trying to detect renames git distinguishes between exact and inexact renameswith:

  • the former being a rename without changing the content of the file and
  • the latter a rename that might include changes to the content of the file (e.g. renaming/moving a Java Class).

This distinction is important because the algorithm for detecting exact renames is linear and will always be executed while the algorithm for inexact rename detection is quadratic ( O(n^2)) and git does not attempt to do this if the number of files changed exceeds a certain threshold (1000 by default).

When not explicitly set, merge.renameLimitdefaults to 1000 files or uses the value for diff.renameLimitif set.
The diff.renameLimitaffects git diff, git showand git logwhile merge.renameLimitapplies to merge attempts (git merge, git cherry-pick) only.

It's a good idea to change the merge.renameLimitas opposed to changing the diff.renameLimitso that git does not attempt to find renames during common operations like looking at the git diffoutput.

To show renames, commands like git showor git logcan be used with the -Moption that turns rename detection on.

当尝试检测重命名时,git 区分精确和不精确的重命名

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

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

如果未明确设置,则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 mentions:

莱纳斯提到

Yeah, for the kernel, I have

是的,对于内核,我有

    [diff]
            renamelimit=0

to disable the limit entirely, because the default limit is very low indeed. Git is quite good at the rename detection.

However, the reason for the low default is not because it's not snappy enough - it's because it can end up using a lot of memory (and if you're low on memory, the swapping will mean that it goes from "quite snappy" to "slow as molasses" - but it still will not be CPU limited, it's just paging like crazy).

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

然而,低默认值的原因并不是因为它不够活泼——而是因为它最终可能会使用大量内存(如果内存不足,交换将意味着它从“非常活泼”到“像糖蜜一样慢” - 但它仍然不会受到 CPU 限制,它只是像疯了一样分页)。