Merge branch 'jl/status-added-submodule-is-never-ignored' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:50:03 +0000 (11:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:50:03 +0000 (11:50 -0700)
"git status" (and "git commit") behaved as if changes in a modified
submodule are not there if submodule.*.ignore configuration is set,
which was misleading. The configuration is only to unclutter diff
output during the course of development, and should not to hide
changes in the "status" output to cause the users forget to commit
them.

* jl/status-added-submodule-is-never-ignored:
commit -m: commit staged submodules regardless of ignore config
status/commit: show staged submodules regardless of ignore config

Documentation/config.txt
Documentation/gitmodules.txt
builtin/commit.c
t/t7508-status.sh
wt-status.c
index 1932e9b9a2be5437dd467f91472318a5bf1bb992..c08286e968ad057c288b72f77e877f42a640ae5f 100644 (file)
@@ -2293,7 +2293,9 @@ status.submodulesummary::
        --summary-limit option of linkgit:git-submodule[1]). Please note
        that the summary output command will be suppressed for all
        submodules when `diff.ignoreSubmodules` is set to 'all' or only
-       for those submodules where `submodule.<name>.ignore=all`. To
+       for those submodules where `submodule.<name>.ignore=all`. The only
+       exception to that rule is that status and commit will show staged
+       submodule changes. To
        also view the summary for ignored submodules you can either use
        the --ignore-submodules=dirty command line option or the 'git
        submodule summary' command, which shows a similar output but does
@@ -2324,7 +2326,9 @@ submodule.<name>.fetchRecurseSubmodules::
 submodule.<name>.ignore::
        Defines under what circumstances "git status" and the diff family show
        a submodule as modified. When set to "all", it will never be considered
-       modified, "dirty" will ignore all changes to the submodules work tree and
+       modified (but it will nonetheless show up in the output of status and
+       commit when it has been staged), "dirty" will ignore all changes
+       to the submodules work tree and
        takes only differences between the HEAD of the submodule and the commit
        recorded in the superproject into account. "untracked" will additionally
        let submodules with modified tracked files in their work tree show up.
index 347a9f76ee809c3691dc6580b0fba3ebde0b0e3c..f6c0dfd0290a9b2174c645630998d2a62cdb9f5e 100644 (file)
@@ -67,7 +67,9 @@ submodule.<name>.fetchRecurseSubmodules::
 submodule.<name>.ignore::
        Defines under what circumstances "git status" and the diff family show
        a submodule as modified. When set to "all", it will never be considered
-       modified, "dirty" will ignore all changes to the submodules work tree and
+       modified (but will nonetheless show up in the output of status and
+       commit when it has been staged), "dirty" will ignore all changes
+       to the submodules work tree and
        takes only differences between the HEAD of the submodule and the commit
        recorded in the superproject into account. "untracked" will additionally
        let submodules with modified tracked files in their work tree show up.
index 65c069d2cbdd7f34b9ebf7add06e65de17df8efa..12afc42d197bfaffc950e7f44acb5d75517f1fc2 100644 (file)
@@ -832,8 +832,22 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 
                if (get_sha1(parent, sha1))
                        commitable = !!active_nr;
-               else
-                       commitable = index_differs_from(parent, 0);
+               else {
+                       /*
+                        * Unless the user did explicitly request a submodule
+                        * ignore mode by passing a command line option we do
+                        * not ignore any changed submodule SHA-1s when
+                        * comparing index and parent, no matter what is
+                        * configured. Otherwise we won't commit any
+                        * submodules which were manually staged, which would
+                        * be really confusing.
+                        */
+                       int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;
+                       if (ignore_submodule_arg &&
+                           !strcmp(ignore_submodule_arg, "all"))
+                               diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;
+                       commitable = index_differs_from(parent, diff_flags);
+               }
        }
        strbuf_release(&committer_ident);
 
index c987b5ed652b977cc2169bdd4c64f42eccdf63db..d48006960e8b4e5feb3d8af8d7a505983f8317eb 100755 (executable)
@@ -1380,7 +1380,32 @@ EOF
        test_i18ncmp expect output
 '
 
-test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
+test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '
+       cat > expect << EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+       modified:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+       modified:   dir1/modified
+
+Untracked files:
+  (use "git add <file>..." to include in what will be committed)
+
+       .gitmodules
+       dir1/untracked
+       dir2/modified
+       dir2/untracked
+       expect
+       output
+       untracked
+
+EOF
        git config --add -f .gitmodules submodule.subname.ignore all &&
        git config --add -f .gitmodules submodule.subname.path sm &&
        git status > output &&
@@ -1388,7 +1413,7 @@ test_expect_success '.gitmodules ignore=all suppresses submodule summary' '
        git config -f .gitmodules  --remove-section submodule.subname
 '
 
-test_expect_success '.git/config ignore=all suppresses submodule summary' '
+test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '
        git config --add -f .gitmodules submodule.subname.ignore none &&
        git config --add -f .gitmodules submodule.subname.path sm &&
        git config --add submodule.subname.ignore all &&
@@ -1461,4 +1486,49 @@ test_expect_success 'Restore default test environment' '
        git config --unset status.showUntrackedFiles
 '
 
+test_expect_success 'git commit will commit a staged but ignored submodule' '
+       git config --add -f .gitmodules submodule.subname.ignore all &&
+       git config --add -f .gitmodules submodule.subname.path sm &&
+       git config --add submodule.subname.ignore all &&
+       git status -s --ignore-submodules=dirty >output &&
+       test_i18ngrep "^M. sm" output &&
+       GIT_EDITOR="echo hello >>\"\$1\"" &&
+       export GIT_EDITOR &&
+       git commit -uno &&
+       git status -s --ignore-submodules=dirty >output &&
+       test_i18ngrep ! "^M. sm" output
+'
+
+test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '
+       git reset HEAD^ &&
+       git add sm &&
+       cat >expect << EOF &&
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+       modified:   sm
+
+Changes not staged for commit:
+  (use "git add <file>..." to update what will be committed)
+  (use "git checkout -- <file>..." to discard changes in working directory)
+
+       modified:   dir1/modified
+
+Untracked files not listed (use -u option to show untracked files)
+EOF
+       git commit -uno --dry-run >output &&
+       test_i18ncmp expect output &&
+       git status -s --ignore-submodules=dirty >output &&
+       test_i18ngrep "^M. sm" output
+'
+
+test_expect_success 'git commit -m will commit a staged but ignored submodule' '
+       git commit -uno -m message &&
+       git status -s --ignore-submodules=dirty >output &&
+        test_i18ngrep ! "^M. sm" output &&
+       git config --remove-section submodule.subname &&
+       git config -f .gitmodules  --remove-section submodule.subname
+'
+
 test_done
index ec7344e50834f18821692d7e38f634778d632080..86fec8986f3c22911a85a042704d4150ccb6a134 100644 (file)
@@ -519,9 +519,19 @@ static void wt_status_collect_changes_index(struct wt_status *s)
        opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
        setup_revisions(0, NULL, &rev, &opt);
 
+       DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
        if (s->ignore_submodule_arg) {
-               DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
+       } else {
+               /*
+                * Unless the user did explicitly request a submodule ignore
+                * mode by passing a command line option we do not ignore any
+                * changed submodule SHA-1s when comparing index and HEAD, no
+                * matter what is configured. Otherwise the user won't be
+                * shown any submodules she manually added (and which are
+                * staged to be committed), which would be really confusing.
+                */
+               handle_ignore_submodules_arg(&rev.diffopt, "dirty");
        }
 
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;