Merge branch 'jk/mv-submodules-fix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 25 Mar 2014 18:02:01 +0000 (11:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 25 Mar 2014 18:02:02 +0000 (11:02 -0700)
"git mv" that moves a submodule forgot to adjust the array that uses
to keep track of which submodules were to be moved to update its
configuration.

* jk/mv-submodules-fix:
mv: prevent mismatched data when ignoring errors.
builtin/mv: fix out of bounds write

1  2 
builtin/mv.c
t/t7001-mv.sh
diff --combined builtin/mv.c
index 7e26eb5229a0c8a526314cecb9860c3dfb0fed00,45e57f307b799490a949d60b37f8cff1a1e5d07f..2a7243f52e413c821f9f75969edcc0a9822c8e21
@@@ -162,8 -162,7 +162,8 @@@ int cmd_mv(int argc, const char **argv
                                        if (strncmp(path, src_w_slash, len_w_slash))
                                                break;
                                }
 -                              free((char *)src_w_slash);
 +                              if (src_w_slash != src)
 +                                      free((char *)src_w_slash);
  
                                if (last - first < 1)
                                        bad = _("source directory is empty");
                                                modes = xrealloc(modes,
                                                                (argc + last - first)
                                                                * sizeof(enum update_mode));
+                                               submodule_gitfile = xrealloc(submodule_gitfile,
+                                                               (argc + last - first)
+                                                               * sizeof(char *));
                                        }
  
                                        dst = add_slash(dst);
                                                        prefix_path(dst, dst_len,
                                                                path + length + 1);
                                                modes[argc + j] = INDEX;
+                                               submodule_gitfile[argc + j] = NULL;
                                        }
                                        argc += last - first;
                                }
                                        memmove(destination + i,
                                                destination + i + 1,
                                                (argc - i) * sizeof(char *));
+                                       memmove(modes + i, modes + i + 1,
+                                               (argc - i) * sizeof(enum update_mode));
+                                       memmove(submodule_gitfile + i,
+                                               submodule_gitfile + i + 1,
+                                               (argc - i) * sizeof(char *));
                                        i--;
                                }
                        } else
diff --combined t/t7001-mv.sh
index e3c8c2c1b8817acd85866470c6f76c4a4f8d17d7,4023b6ec48729d1cd2c9e9809fd322852166d9f0..215d43d6a6c8ce7f2b30e32dce6dfe34adc98b15
@@@ -294,7 -294,8 +294,8 @@@ test_expect_success 'setup submodule' 
        git submodule add ./. sub &&
        echo content >file &&
        git add file &&
-       git commit -m "added sub and file"
+       git commit -m "added sub and file" &&
+       git branch submodule
  '
  
  test_expect_success 'git mv cannot move a submodule in a file' '
@@@ -442,25 -443,14 +443,35 @@@ test_expect_success 'mv --dry-run does 
        git diff-files --quiet -- sub .gitmodules
  '
  
 +test_expect_success 'checking out a commit before submodule moved needs manual updates' '
 +      git mv sub sub2 &&
 +      git commit -m "moved sub to sub2" &&
 +      git checkout -q HEAD^ 2>actual &&
 +      echo "warning: unable to rmdir sub2: Directory not empty" >expected &&
 +      test_i18ncmp expected actual &&
 +      git status -s sub2 >actual &&
 +      echo "?? sub2/" >expected &&
 +      test_cmp expected actual &&
 +      ! test -f sub/.git &&
 +      test -f sub2/.git &&
 +      git submodule update &&
 +      test -f sub/.git &&
 +      rm -rf sub2 &&
 +      git diff-index --exit-code HEAD &&
 +      git update-index --refresh &&
 +      git diff-files --quiet -- sub .gitmodules &&
 +      git status -s sub2 >actual &&
 +      ! test -s actual
 +'
 +
+ test_expect_success 'mv -k does not accidentally destroy submodules' '
+       git checkout submodule &&
+       mkdir dummy dest &&
+       git mv -k dummy sub dest &&
+       git status --porcelain >actual &&
+       grep "^R  sub -> dest/sub" actual &&
+       git reset --hard &&
+       git checkout .
+ '
  test_done