Merge branch 'jl/submodule-mv-checkout-caveat'
authorJunio C Hamano <gitster@pobox.com>
Mon, 13 Jan 2014 19:33:47 +0000 (11:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Jan 2014 19:33:47 +0000 (11:33 -0800)
With a submodule that was initialized in an old fashioned way
without gitlinks, switching branches in the superproject between
the one with and without the submodule may leave the submodule
working tree with its embedded repository behind, as there may be
unexpendable state there. Document and warn users about this.

* jl/submodule-mv-checkout-caveat:
rm: better document side effects when removing a submodule
mv: better document side effects when moving a submodule

Documentation/git-mv.txt
Documentation/git-rm.txt
t/t3600-rm.sh
t/t7001-mv.sh
index b1f79881efdd181cf996672bc47c7772f21df8fd..e4531325cd0e00000670692ee3e5a26387460d9e 100644 (file)
@@ -52,6 +52,18 @@ core.worktree setting to make the submodule work in the new location.
 It also will attempt to update the submodule.<name>.path setting in
 the linkgit:gitmodules[5] file and stage that file (unless -n is used).
 
+BUGS
+----
+Each time a superproject update moves a populated submodule (e.g. when
+switching between commits before and after the move) a stale submodule
+checkout will remain in the old location and an empty directory will
+appear in the new location. To populate the submodule again in the new
+location the user will have to run "git submodule update"
+afterwards. Removing the old directory is only safe when it uses a
+gitfile, as otherwise the history of the submodule will be deleted
+too. Both steps will be obsolete when recursive submodule update has
+been implemented.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index 9d731b453d1af4cbdbf559b72e8064a77696f4a3..f1efc116ebb88a3bc31898f6a18837f8b951ad09 100644 (file)
@@ -170,6 +170,15 @@ of files and subdirectories under the `Documentation/` directory.
        (i.e. you are listing the files explicitly), it
        does not remove `subdir/git-foo.sh`.
 
+BUGS
+----
+Each time a superproject update removes a populated submodule
+(e.g. when switching between commits before and after the removal) a
+stale submodule checkout will remain in the old location. Removing the
+old directory is only safe when it uses a gitfile, as otherwise the
+history of the submodule will be deleted too. This step will be
+obsolete when recursive submodule update has been implemented.
+
 SEE ALSO
 --------
 linkgit:git-add[1]
index 540c49bab618ffb75dd789b098ef982634648f7c..3d305814b9d755a827d27ed9036ebb2f8d48abe6 100755 (executable)
@@ -705,6 +705,22 @@ test_expect_success 'rm of a populated nested submodule with a nested .git direc
        rm -rf submod
 '
 
+test_expect_success 'checking out a commit after submodule removal needs manual updates' '
+       git commit -m "submodule removal" submod &&
+       git checkout HEAD^ &&
+       git submodule update &&
+       git checkout -q HEAD^ 2>actual &&
+       git checkout -q master 2>actual &&
+       echo "warning: unable to rmdir submod: Directory not empty" >expected &&
+       test_i18ncmp expected actual &&
+       git status -s submod >actual &&
+       echo "?? submod/" >expected &&
+       test_cmp expected actual &&
+       rm -rf submod &&
+       git status -s -uno --ignore-submodules=none > actual &&
+       ! test -s actual
+'
+
 test_expect_success 'rm of d/f when d has become a non-directory' '
        rm -rf d &&
        mkdir d &&
index 3bfdfed1f7774edb8a87864bdb6a021dc6a185ed..e3c8c2c1b8817acd85866470c6f76c4a4f8d17d7 100755 (executable)
@@ -442,4 +442,25 @@ test_expect_success 'mv --dry-run does not touch the submodule or .gitmodules' '
        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_done