]> git.ipfire.org Git - thirdparty/git.git/commit - t/t6423-merge-rename-directories.sh
t6423: more involved directory rename test
authorElijah Newren <newren@gmail.com>
Thu, 15 Oct 2020 20:46:28 +0000 (20:46 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 16 Oct 2020 19:29:27 +0000 (12:29 -0700)
commit902c521a35ccf479a99253918346baa9a1011c22
treedb59ce41c802703671956acf021dc5a5a8a35c96
parentb9718d0cc98dcdf0012ba0bef8112068c6b2e1e4
t6423: more involved directory rename test

Add a new testcase modelled on a real world repository example that
served multiple purposes:
  * it uncovered a bug in the current directory rename detection
    implementation.
  * it is a good test of needing to do directory rename detection for
    a series of commits instead of just one (and uses rebase instead
    of just merge like all the other tests in this testfile).
  * it is an excellent stress test for some of the optimizations in
    my new merge-ort engine

I can expand on the final item later when I have submitted more of
merge-ort, but the bug is the main immediate concern.  It arises as
follows:

  * dir/subdir/ has several files
  * almost all files in dir/subdir/ are renamed to folder/subdir/
  * one of the files in dir/subdir/ is renamed to folder/subdir/newsubdir/
  * If the other side of history (that doesn't do the renames) adds a
    new file to dir/subdir/, where should it be placed after the merge?

The most obvious two choices are: (1) leave the new file in dir/subdir/,
don't make it follow the rename, and (2) move the new file to
folder/subdir/, following the rename of most the files.  However,
there's a possible third choice here: (3) move the new file to
folder/subdir/newsubdir/.  The choice reinforce the fact that
merge.directoryRenames=conflict is a good default, but when the merge
machinery needs to stick it somewhere and notify the user of the
possibility that they might want to place it elsewhere.  Surprisingly,
the current code would always choose (3), while the real world
repository was clearly expecting (2) -- move the file along with where
the herd of files was going, not with the special exception.

The problem here is that for the majority of the file renames,
   dir/subdir/ -> folder/subdir/
is actually represented as
   dir/ -> folder/
This directory rename would have a big weight associated with it since
most the files followed that rename.  However, we always consult the
most immediate directory first, and there is only one rename rule for
it:
   dir/subdir/ -> folder/subdir/newsubdir/
Since this rule is the only one for mapping from dir/subdir/, it
automatically wins and that directory rename was followed instead of the
desired dir/subdir/ -> folder/subdir/.

Unfortunately, the fix is a bit involved so for now just add the
testcase documenting the issue.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t6423-merge-rename-directories.sh