mv: Fix spurious warning when moving a file in presence of submodules

In commit 0656781fa "git mv" learned to update the submodule path in the .gitmodules file when moving a submodule in the work tree. But since that commit update_path_in_gitmodules() gets called no matter if we moved a submodule or a regular file, which is wrong and leads to a bogus warning when moving a regular file in a repo containing a .gitmodules file: warning: Could not find section in .gitmodules where path=<filename> Fix that by only calling update_path_in_gitmodules() when moving a submodule. To achieve that, we introduce the special SUBMODULE_WITH_GITDIR define to distinguish the cases where we also have to connect work tree and git directory from those where we only need to update the .gitmodules setting. A test for submodules using a .git directory together with a .gitmodules file has been added to t7001. Even though newer git versions will always use a gitfile when cloning submodules, repositories cloned with older git versions will still use this layout. Reported-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>

Jens Lehmann committed Oct 13, 2013 at 13:52 UTC 04c1ee576accad4d0a04f168b86992aba0a6727d
2 files changed +35 -4
builtin/mv.c
+9 -4
@@ -55,6 +55,7 @@ static const char *add_slash(const char *path)
55 }
56
57 static struct lock_file lock_file;
58 +#define SUBMODULE_WITH_GITDIR ((const char *)1)
59
60 int cmd_mv(int argc, const char **argv, const char *prefix)
61 {
@@ -132,6 +133,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
133 submodule_gitfile[i] = read_gitfile(submodule_dotgit.buf);
134 if (submodule_gitfile[i])
135 submodule_gitfile[i] = xstrdup(submodule_gitfile[i]);
136 + else
137 + submodule_gitfile[i] = SUBMODULE_WITH_GITDIR;
138 strbuf_release(&submodule_dotgit);
139 } else {
140 const char *src_w_slash = add_slash(src);
@@ -230,10 +233,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
233 if (!show_only && mode != INDEX) {
234 if (rename(src, dst) < 0 && !ignore_errors)
235 die_errno (_("renaming '%s' failed"), src);
233 - if (submodule_gitfile[i])
234 - connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
235 - if (!update_path_in_gitmodules(src, dst))
236 - gitmodules_modified = 1;
236 + if (submodule_gitfile[i]) {
237 + if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
238 + connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
239 + if (!update_path_in_gitmodules(src, dst))
240 + gitmodules_modified = 1;
241 + }
242 }
243
244 if (mode == WORKING_DIRECTORY)
t/t7001-mv.sh
+26
@@ -293,6 +293,32 @@ test_expect_success 'git mv moves a submodule with a .git directory and no .gitm
293 git diff-files --quiet
294 '
295
296 +test_expect_success 'git mv moves a submodule with a .git directory and .gitmodules' '
297 + rm -rf mod &&
298 + git reset --hard &&
299 + git submodule update &&
300 + entry="$(git ls-files --stage sub | cut -f 1)" &&
301 + (
302 + cd sub &&
303 + rm -f .git &&
304 + cp -a ../.git/modules/sub .git &&
305 + GIT_WORK_TREE=. git config --unset core.worktree
306 + ) &&
307 + mkdir mod &&
308 + git mv sub mod/sub &&
309 + ! test -e sub &&
310 + [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
311 + (
312 + cd mod/sub &&
313 + git status
314 + ) &&
315 + echo mod/sub >expected &&
316 + git config -f .gitmodules submodule.sub.path >actual &&
317 + test_cmp expected actual &&
318 + git update-index --refresh &&
319 + git diff-files --quiet
320 +'
321 +
322 test_expect_success 'git mv moves a submodule with gitfile' '
323 rm -rf mod/sub &&
324 git reset --hard &&