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

Solution 1:

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

Solution 2:

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