]> granicus.if.org Git - git/commitdiff
Revert "Merge branch 'en/merge-recursive-directory-rename-fixes' into next"
authorJunio C Hamano <gitster@pobox.com>
Wed, 16 Oct 2019 04:02:24 +0000 (13:02 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Oct 2019 04:02:24 +0000 (13:02 +0900)
This reverts commit ebfdc3ff7b20064fc7fab04f761f5095ba5c3a05, reversing
changes made to 93c9949b6a31deba4af5187bf802a751869b687a, to give
the topic a chance to a clean restart.

merge-recursive.c
t/t6043-merge-rename-directories.sh

index 87a4557a13ee520b0e7be2e99a04af36a37a801a..42be7c9960ad5c02f3968a27977203a638d79bbd 100644 (file)
@@ -1951,16 +1951,6 @@ static char *apply_dir_rename(struct dir_rename_entry *entry,
                return NULL;
 
        oldlen = strlen(entry->dir);
-       if (entry->new_dir.len == 0)
-               /*
-                * If someone renamed/merged a subdirectory into the root
-                * directory (e.g. 'some/subdir' -> ''), then we want to
-                * avoid returning
-                *     '' + '/filename'
-                * as the rename; we need to make old_path + oldlen advance
-                * past the '/' character.
-                */
-               oldlen++;
        newlen = entry->new_dir.len + (strlen(old_path) - oldlen) + 1;
        strbuf_grow(&new_path, newlen);
        strbuf_addbuf(&new_path, &entry->new_dir);
@@ -1973,8 +1963,8 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
                                    char **old_dir, char **new_dir)
 {
        char *end_of_old, *end_of_new;
+       int old_len, new_len;
 
-       /* Default return values: NULL, meaning no rename */
        *old_dir = NULL;
        *new_dir = NULL;
 
@@ -1985,74 +1975,43 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
         *    "a/b/c/d" was renamed to "a/b/some/thing/else"
         * so, for this example, this function returns "a/b/c/d" in
         * *old_dir and "a/b/some/thing/else" in *new_dir.
-        */
-
-       /*
-        * If the basename of the file changed, we don't care.  We want
-        * to know which portion of the directory, if any, changed.
+        *
+        * Also, if the basename of the file changed, we don't care.  We
+        * want to know which portion of the directory, if any, changed.
         */
        end_of_old = strrchr(old_path, '/');
        end_of_new = strrchr(new_path, '/');
-       if (end_of_old == NULL || end_of_new == NULL)
-               return; /* We haven't modified *old_dir or *new_dir yet. */
 
-       /* Find the first non-matching character traversing backwards */
+       if (end_of_old == NULL || end_of_new == NULL)
+               return;
        while (*--end_of_new == *--end_of_old &&
               end_of_old != old_path &&
               end_of_new != new_path)
                ; /* Do nothing; all in the while loop */
-
        /*
-        * If both got back to the beginning of their strings, then the
-        * directory didn't change at all, only the basename did.
-        */
-       if (end_of_old == old_path && end_of_new == new_path &&
-           *end_of_old == *end_of_new)
-               return; /* We haven't modified *old_dir or *new_dir yet. */
-
-       /*
-        * If end_of_new got back to the beginning of its string, and
-        * end_of_old got back to the beginning of some subdirectory, then
-        * we have a rename/merge of a subdirectory into the root, which
-        * needs slightly special handling.
-        *
-        * Note: There is no need to consider the opposite case, with a
-        * rename/merge of the root directory into some subdirectory.
-        * Our rule elsewhere that a directory which still exists is not
-        * considered to have been renamed means the root directory can
-        * never be renamed (because the root directory always exists).
+        * We've found the first non-matching character in the directory
+        * paths.  That means the current directory we were comparing
+        * represents the rename.  Move end_of_old and end_of_new back
+        * to the full directory name.
         */
-       if (end_of_new == new_path &&
-           end_of_old != old_path && end_of_old[-1] == '/') {
-               *old_dir = xstrndup(old_path, end_of_old-1 - old_path);
-               *new_dir = xstrndup(new_path, end_of_new - new_path);
-               return;
-       }
+       if (*end_of_old == '/')
+               end_of_old++;
+       if (*end_of_old != '/')
+               end_of_new++;
+       end_of_old = strchr(end_of_old, '/');
+       end_of_new = strchr(end_of_new, '/');
 
        /*
-        * We've found the first non-matching character in the directory
-        * paths.  That means the current characters we were looking at
-        * were part of the first non-matching subdir name going back from
-        * the end of the strings.  Get the whole name by advancing both
-        * end_of_old and end_of_new to the NEXT '/' character.  That will
-        * represent the entire directory rename.
-        *
-        * The reason for the increment is cases like
-        *    a/b/star/foo/whatever.c -> a/b/tar/foo/random.c
-        * After dropping the basename and going back to the first
-        * non-matching character, we're now comparing:
-        *    a/b/s          and         a/b/
-        * and we want to be comparing:
-        *    a/b/star/      and         a/b/tar/
-        * but without the pre-increment, the one on the right would stay
-        * a/b/.
+        * It may have been the case that old_path and new_path were the same
+        * directory all along.  Don't claim a rename if they're the same.
         */
-       end_of_old = strchr(++end_of_old, '/');
-       end_of_new = strchr(++end_of_new, '/');
+       old_len = end_of_old - old_path;
+       new_len = end_of_new - new_path;
 
-       /* Copy the old and new directories into *old_dir and *new_dir. */
-       *old_dir = xstrndup(old_path, end_of_old - old_path);
-       *new_dir = xstrndup(new_path, end_of_new - new_path);
+       if (old_len != new_len || strncmp(old_path, new_path, old_len)) {
+               *old_dir = xstrndup(old_path, old_len);
+               *new_dir = xstrndup(new_path, new_len);
+       }
 }
 
 static void remove_hashmap_entries(struct hashmap *dir_renames,
index b920bb08500430018796e694c6bd504ba6a00441..c966147d5d73ee669321f3efcf57e32a80259076 100755 (executable)
@@ -4051,62 +4051,6 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
        )
 '
 
-# Testcase 12d, Rename/merge of subdirectory into the root
-#   Commit O: a/b/{foo.c}
-#   Commit A: foo.c
-#   Commit B: a/b/{foo.c,bar.c}
-#   Expected: a/b/{foo.c,bar.c}
-
-test_expect_success '12d-setup: Rename (merge) of subdirectory into the root' '
-       test_create_repo 12d &&
-       (
-               cd 12d &&
-
-               mkdir -p a/b/subdir &&
-               test_commit a/b/subdir/foo.c &&
-
-               git branch O &&
-               git branch A &&
-               git branch B &&
-
-               git checkout A &&
-               mkdir subdir &&
-               git mv a/b/subdir/foo.c.t subdir/foo.c.t &&
-               test_tick &&
-               git commit -m "A" &&
-
-               git checkout B &&
-               test_commit a/b/bar.c
-       )
-'
-
-test_expect_success '12d-check: Rename (merge) of subdirectory into the root' '
-       (
-               cd 12d &&
-
-               git checkout A^0 &&
-
-               git -c merge.directoryRenames=true merge -s recursive B^0 &&
-
-               git ls-files -s >out &&
-               test_line_count = 2 out &&
-
-               git rev-parse >actual \
-                       HEAD:subdir/foo.c.t   HEAD:bar.c.t &&
-               git rev-parse >expect \
-                       O:a/b/subdir/foo.c.t  B:a/b/bar.c.t &&
-               test_cmp expect actual &&
-
-               git hash-object bar.c.t >actual &&
-               git rev-parse B:a/b/bar.c.t >expect &&
-               test_cmp expect actual &&
-
-               test_must_fail git rev-parse HEAD:a/b/subdir/foo.c.t &&
-               test_must_fail git rev-parse HEAD:a/b/bar.c.t &&
-               test_path_is_missing a/
-       )
-'
-
 ###########################################################################
 # SECTION 13: Checking informational and conflict messages
 #