ChatGPT解决这个技术问题 Extra ChatGPT

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

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).

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.

What is the best way to approach this merge?

Just so other readers know: the typical error message for these problems is too many files skipping inexact rename detection.

R
Robie Basak

Try setting merge.renameLimit to 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:

git config merge.renameLimit 999999

then when done:

git config --unset merge.renameLimit

Note after increasing renameLimit, I had to run "git merge --abort" so I could retry the pull. Otherwise, this did the trick.
C
Community

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

When trying to detect renames git distinguishes between exact and inexact renames with: 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.renameLimit defaults to 1000 files or uses the value for diff.renameLimit if set. The diff.renameLimit affects git diff, git show and git log while merge.renameLimit applies to merge attempts (git merge, git cherry-pick) only. It’s a good idea to change the merge.renameLimit as opposed to changing the diff.renameLimit so that git does not attempt to find renames during common operations like looking at the git diff output. To show renames, commands like git show or git log can be used with the -M option that turns rename detection on.

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).