{"thread":{"id":"24044","subject":"[PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","startedAt":"2010-06-08T16:30:47Z","lastAt":"2010-06-24T17:11:43Z","messageCount":14,"participants":["Jens Lehmann","Junio C Hamano","Johannes Schindelin","Johan Herland","Brandon Casey"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"143250","messageId":"4C0E7037.8080403@web.de","threadId":"24044","inReplyTo":null,"subject":"[PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-08T16:30:47Z","receivedAt":"2010-06-08T16:30:47Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"After thinking some time about peoples expectations and troubles\nwith the recursive scanning of submodules, I came up with this:\n\nWhat about expanding the \"--ignore-submodules\" option of the git diff\nfamily with three parameters:\n\n--ignore-submodules=all : Same behavior as \"--ignore-submodules\",\n  submodules show never up as modified.\n\n--ignore-submodules=untracked : Don't consider submodules as modified\n  when they only contain untracked files, but do if the commits in the\n  superproject are different or tracked content is modified.\n\n--ignore-submodules=dirty : Don't consider submodules as modified\n  when their work tree is dirty, no matter why. This is the pre 1.7.0\n  behavior and doesn't recurse into submodules at all.\n\nThe first patch is just a resend of a test case rename, the second\ncontains the implementation.\n\n\nTo make that more useful the default could be controlled by the\n.git/config or .gitmodules file. So you could have two submodules:\n\n[submodule \"sub1\"]\n\tpath = sub1\n\turl = /home/me/sub1.git/\n\tignore = dirty\n[submodule \"sub2\"]\n\tpath = sub2\n\turl = /home/me/sub2.git/\n\tignore = untracked\n\nWhere sub1 will not be scanned for work tree modifications by \"git\ndiff\" and \"git status\" and for sub2 any untracked files inside the\nsubmodule will be ignored. And then \"git status\" should learn the\n\"--ignore-submodule\" option too. With a fourth parameter \"none\" it\nwould be possible to override the defaults from the configuration\nanyway you want.\n\nOpinions?\n\n\nJens Lehmann (2):\n  git diff: rename test that had a conflicting name\n  Add optional parameters to the diff option \"--ignore-submodules\"\n\n Documentation/diff-options.txt                     |   10 ++-\n diff-lib.c                                         |    1 +\n diff.c                                             |   11 +++-\n diff.h                                             |    1 +\n t/t4027-diff-submodule.sh                          |   20 ++++-\n ...submodule.sh => t4041-diff-submodule-option.sh} |   81 ++++++++++++++++++++\n 6 files changed, 118 insertions(+), 6 deletions(-)\n rename t/{t4041-diff-submodule.sh => t4041-diff-submodule-option.sh} (74%)\n"},{"id":"143253","messageId":"4C0E705D.4060305@web.de","threadId":"24044","inReplyTo":"4C0E7037.8080403@web.de","subject":"[PATCH 1/2] git diff: rename test that had a conflicting name","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-08T16:31:25Z","receivedAt":"2010-06-08T16:31:25Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"In 86140d5 the new test t4041-diff-submodule.sh was introduced although\nt4027-diff-submodule.sh already existed. Rename the newer test to\nt4041-diff-submodule-option.sh to fix that.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n ...submodule.sh => t4041-diff-submodule-option.sh} |    0\n 1 files changed, 0 insertions(+), 0 deletions(-)\n rename t/{t4041-diff-submodule.sh => t4041-diff-submodule-option.sh} (100%)\n\ndiff --git a/t/t4041-diff-submodule.sh b/t/t4041-diff-submodule-option.sh\nsimilarity index 100%\nrename from t/t4041-diff-submodule.sh\nrename to t/t4041-diff-submodule-option.sh\n-- \n1.7.1.447.g4d763\n"},{"id":"143251","messageId":"4C0E7077.9090509@web.de","threadId":"24044","inReplyTo":"4C0E7037.8080403@web.de","subject":"[PATCH 2/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-08T16:31:51Z","receivedAt":"2010-06-08T16:31:51Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"In some use cases it is not desirable that the diff family considers\nsubmodules that only contain untracked content as dirty. This may happen\ne.g. when the submodule is not under the developers control and not all\nbuild generated files have been added to .gitignore by the upstream\ndevelopers. Using the \"untracked\" parameter for the \"--ignore-submodules\"\noption disables checking for untracked content and lets git diff report\nthem as changed only when they have new commits or modified content.\n\nSometimes it is not wanted to have submodules show up as changed when they\njust contain changes to their work tree. An example for that are scripts\nwhich just want to check for submodule commits while ignoring any changes\nto the work tree. Also users having large submodules known not to change\nmight want to use this option, as the - sometimes substantial - time it\ntakes to scan the submodule work tree(s) is saved.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n Documentation/diff-options.txt   |   10 ++++-\n diff-lib.c                       |    1 +\n diff.c                           |   11 +++++-\n diff.h                           |    1 +\n t/t4027-diff-submodule.sh        |   20 ++++++++-\n t/t4041-diff-submodule-option.sh |   81 ++++++++++++++++++++++++++++++++++++++\n 6 files changed, 118 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex e745a3c..2371262 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -328,8 +328,14 @@ endif::git-format-patch[]\n --no-ext-diff::\n \tDisallow external diff drivers.\n\n---ignore-submodules::\n-\tIgnore changes to submodules in the diff generation.\n+--ignore-submodules[=<when>]::\n+\tIgnore changes to submodules in the diff generation. <when> can be\n+\teither \"untracked\", \"dirty\" or \"all\", which is the default. When\n+\t\"untracked\" is used submodules are not considered dirty when they only\n+\tcontain untracked content (but they are still scanned for modified\n+\tcontent). Using \"dirty\" ignores all changes to the work tree of submodules,\n+\tonly changes to the commits stored in the superproject are shown (this was\n+\tthe behavior until 1.7.0). Using \"all\" hides all changes to submodules.\n\n --src-prefix=<prefix>::\n \tShow the given source prefix instead of \"a/\".\ndiff --git a/diff-lib.c b/diff-lib.c\nindex c9f6e05..8b8978a 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -70,6 +70,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt,\n \tint changed = ce_match_stat(ce, st, ce_option);\n \tif (S_ISGITLINK(ce->ce_mode)\n \t    && !DIFF_OPT_TST(diffopt, IGNORE_SUBMODULES)\n+\t    && !DIFF_OPT_TST(diffopt, IGNORE_DIRTY_SUBMODULES)\n \t    && (!changed || DIFF_OPT_TST(diffopt, DIRTY_SUBMODULES))) {\n \t\t*dirty_submodule = is_submodule_modified(ce->name, DIFF_OPT_TST(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES));\n \t}\ndiff --git a/diff.c b/diff.c\nindex 2327cea..71fff7e 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -3174,7 +3174,16 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n \t\tDIFF_OPT_CLR(options, ALLOW_TEXTCONV);\n \telse if (!strcmp(arg, \"--ignore-submodules\"))\n \t\tDIFF_OPT_SET(options, IGNORE_SUBMODULES);\n-\telse if (!strcmp(arg, \"--submodule\"))\n+\telse if (!prefixcmp(arg, \"--ignore-submodules=\")) {\n+\t\tif (!strcmp(arg + 20, \"all\"))\n+\t\t\tDIFF_OPT_SET(options, IGNORE_SUBMODULES);\n+\t\telse if (!strcmp(arg + 20, \"untracked\"))\n+\t\t\tDIFF_OPT_SET(options, IGNORE_UNTRACKED_IN_SUBMODULES);\n+\t\telse if (!strcmp(arg + 20, \"dirty\"))\n+\t\t\tDIFF_OPT_SET(options, IGNORE_DIRTY_SUBMODULES);\n+\t\telse\n+\t\t\tdie(\"bad --ignore-submodules argument: %s\", arg + 20);\n+\t} else if (!strcmp(arg, \"--submodule\"))\n \t\tDIFF_OPT_SET(options, SUBMODULE_LOG);\n \telse if (!prefixcmp(arg, \"--submodule=\")) {\n \t\tif (!strcmp(arg + 12, \"log\"))\ndiff --git a/diff.h b/diff.h\nindex 48abe7a..5248cd8 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -74,6 +74,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)\n #define DIFF_OPT_SUBMODULE_LOG       (1 << 23)\n #define DIFF_OPT_DIRTY_SUBMODULES    (1 << 24)\n #define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)\n+#define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)\n\n #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)\n #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)\ndiff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh\nindex 83c1914..559b41e 100755\n--- a/t/t4027-diff-submodule.sh\n+++ b/t/t4027-diff-submodule.sh\n@@ -103,9 +103,17 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'\n \tgit diff HEAD >actual &&\n \tsed -e \"1,/^@@/d\" actual >actual.body &&\n \texpect_from_to >expect.body $subprev $subprev-dirty &&\n-\ttest_cmp expect.body actual.body\n+\ttest_cmp expect.body actual.body &&\n+\tgit diff --ignore-submodules HEAD >actual2 &&\n+\techo -n \"\" | test_cmp - actual2 &&\n+\tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n+\tsed -e \"1,/^@@/d\" actual3 >actual3.body &&\n+\texpect_from_to >expect.body $subprev $subprev-dirty &&\n+\ttest_cmp expect.body actual3.body &&\n+\tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n+\techo -n \"\" | test_cmp - actual4\n '\n-\n+test_done\n test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '\n \t(\n \t\tcd sub &&\n@@ -129,7 +137,13 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'\n \tgit diff HEAD >actual &&\n \tsed -e \"1,/^@@/d\" actual >actual.body &&\n \texpect_from_to >expect.body $subprev $subprev-dirty &&\n-\ttest_cmp expect.body actual.body\n+\ttest_cmp expect.body actual.body &&\n+\tgit diff --ignore-submodules=all HEAD >actual2 &&\n+\techo -n \"\" | test_cmp - actual2 &&\n+\tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n+\techo -n \"\" | test_cmp - actual3 &&\n+\tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n+\techo -n \"\" | test_cmp - actual4\n '\n\n test_expect_success 'git diff (empty submodule dir)' '\ndiff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh\nindex 019acb9..f44b906 100755\n--- a/t/t4041-diff-submodule-option.sh\n+++ b/t/t4041-diff-submodule-option.sh\n@@ -205,6 +205,21 @@ Submodule sm1 contains untracked content\n EOF\n \"\n\n+test_expect_success 'submodule contains untracked content (untracked ignored)' \"\n+\tgit diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n+test_expect_success 'submodule contains untracked content (dirty ignored)' \"\n+\tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n+test_expect_success 'submodule contains untracked content (all ignored)' \"\n+\tgit diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n test_expect_success 'submodule contains untracked and modifed content' \"\n \techo new > sm1/foo6 &&\n \tgit diff-index -p --submodule=log HEAD >actual &&\n@@ -214,6 +229,26 @@ Submodule sm1 contains modified content\n EOF\n \"\n\n+test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' \"\n+\techo new > sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&\n+\tdiff actual - <<-EOF\n+Submodule sm1 contains modified content\n+EOF\n+\"\n+\n+test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' \"\n+\techo new > sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n+test_expect_success 'submodule contains untracked and modifed content (all ignored)' \"\n+\techo new > sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n test_expect_success 'submodule contains modifed content' \"\n \trm -f sm1/new-file &&\n \tgit diff-index -p --submodule=log HEAD >actual &&\n@@ -242,6 +277,27 @@ Submodule sm1 $head6..$head8:\n EOF\n \"\n\n+test_expect_success 'modified submodule contains untracked content (untracked ignored)' \"\n+\tgit diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&\n+\tdiff actual - <<-EOF\n+Submodule sm1 $head6..$head8:\n+  > change\n+EOF\n+\"\n+\n+test_expect_success 'modified submodule contains untracked content (dirty ignored)' \"\n+\tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n+\tdiff actual - <<-EOF\n+Submodule sm1 $head6..$head8:\n+  > change\n+EOF\n+\"\n+\n+test_expect_success 'modified submodule contains untracked content (all ignored)' \"\n+\tgit diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n test_expect_success 'modified submodule contains untracked and modifed content' \"\n \techo modification >> sm1/foo6 &&\n \tgit diff-index -p --submodule=log HEAD >actual &&\n@@ -253,6 +309,31 @@ Submodule sm1 $head6..$head8:\n EOF\n \"\n\n+test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' \"\n+\techo modification >> sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&\n+\tdiff actual - <<-EOF\n+Submodule sm1 contains modified content\n+Submodule sm1 $head6..$head8:\n+  > change\n+EOF\n+\"\n+\n+test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' \"\n+\techo modification >> sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n+\tdiff actual - <<-EOF\n+Submodule sm1 $head6..$head8:\n+  > change\n+EOF\n+\"\n+\n+test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' \"\n+\techo modification >> sm1/foo6 &&\n+\tgit diff-index -p --ignore-submodules --submodule=log HEAD >actual &&\n+\techo -n '' | diff actual -\n+\"\n+\n test_expect_success 'modified submodule contains modifed content' \"\n \trm -f sm1/new-file &&\n \tgit diff-index -p --submodule=log HEAD >actual &&\n-- \n1.7.1.447.g4d763\n"},{"id":"143257","messageId":"7vhbldtow3.fsf@alter.siamese.dyndns.org","threadId":"24044","inReplyTo":"4C0E7037.8080403@web.de","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-08T17:28:28Z","receivedAt":"2010-06-08T17:28:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> After thinking some time about peoples expectations and troubles\n> with the recursive scanning of submodules, I came up with this:\n>\n> What about expanding the \"--ignore-submodules\" option of the git diff\n> family with three parameters:\n>\n> --ignore-submodules=all : Same behavior as \"--ignore-submodules\",\n>   submodules show never up as modified.\n>\n> --ignore-submodules=untracked : Don't consider submodules as modified\n>   when they only contain untracked files, but do if the commits in the\n>   superproject are different or tracked content is modified.\n>\n> --ignore-submodules=dirty : Don't consider submodules as modified\n>   when their work tree is dirty, no matter why. This is the pre 1.7.0\n>   behavior and doesn't recurse into submodules at all.\n>\n> The first patch is just a resend of a test case rename, the second\n> contains the implementation.\n>\n>\n> To make that more useful the default could be controlled by the\n> .git/config or .gitmodules file. So you could have two submodules:\n>\n> [submodule \"sub1\"]\n> \tpath = sub1\n> \turl = /home/me/sub1.git/\n> \tignore = dirty\n> [submodule \"sub2\"]\n> \tpath = sub2\n> \turl = /home/me/sub2.git/\n> \tignore = untracked\n>\n> Where sub1 will not be scanned for work tree modifications by \"git\n> diff\" and \"git status\" and for sub2 any untracked files inside the\n> submodule will be ignored. And then \"git status\" should learn the\n> \"--ignore-submodule\" option too. With a fourth parameter \"none\" it\n> would be possible to override the defaults from the configuration\n> anyway you want.\n>\n> Opinions?\n\nThe above outline (I haven't looked at the code) sounds sane.  We might\neven want to make untracked (or dirty) the default, if nothing is given\nfrom the command line nor configuration.\n\nI don't see a reason for patch 1/2, though.\n\nThanks.\n"},{"id":"143273","messageId":"4C0EAAE8.3060300@web.de","threadId":"24044","inReplyTo":"7vhbldtow3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-08T20:41:12Z","receivedAt":"2010-06-08T20:41:12Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 08.06.2010 19:28, schrieb Junio C Hamano:\n> The above outline (I haven't looked at the code) sounds sane.  We might\n> even want to make untracked (or dirty) the default, if nothing is given\n> from the command line nor configuration.\n\nHm, as far as I interpreted the postings here, \"none\" should be a\nreasonable default for most users because it protects them from errors\nthat are easy to make and hard to detect.\n\nIIRC there are two main exceptions which want a different setting:\n\n - Huge submodules which take a substantial portion of time to scan may\n   want \"dirty\" to avoid spending the extra time (at least until we have\n   an inotfiy daemon ;-).\n\n - Submodules where the provider doesn't care or is not able to provide\n   a proper .gitignore for other reasons want \"untracked\" to avoid the\n   noise.\n\n(Anything I missed?)\n\nAnd these seem to fall into the category: If you are unlucky enough to\nhave one of these included in your superproject, configure these to use\n\"dirty\" or \"untracked\" as appropriate. And AFAICT they are more the\nexception than the rule so I came up with this proposal of a per\nsubmodule configuration, so people won't have to turn off submodule\nchecking for all submodules because of a single special one.\n\n\n> I don't see a reason for patch 1/2, though.\n\nOk, I will drop that from the next round.\n"},{"id":"143279","messageId":"alpine.DEB.1.00.1006082247390.1732@bonsai2","threadId":"24044","inReplyTo":"4C0EAAE8.3060300@web.de","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-06-08T21:02:39Z","receivedAt":"2010-06-08T21:02:39Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 Jun 2010, Jens Lehmann wrote:\n\n> Am 08.06.2010 19:28, schrieb Junio C Hamano:\n> > The above outline (I haven't looked at the code) sounds sane.  We might\n> > even want to make untracked (or dirty) the default, if nothing is given\n> > from the command line nor configuration.\n> \n> Hm, as far as I interpreted the postings here, \"none\" should be a\n> reasonable default for most users because it protects them from errors\n> that are easy to make and hard to detect.\n> \n> IIRC there are two main exceptions which want a different setting:\n> \n>  - Huge submodules which take a substantial portion of time to scan may \n>    want \"dirty\" to avoid spending the extra time (at least until we have \n>    an inotfiy daemon ;-).\n\nNot only huge submodules. Thrashing the disk cache (e.g. by the sheer \nnumber of submodules) is another reason. In my main project, the time for \na simple \"git status\" went up from unnoticable (<0.1 seconds AFAICT) to 45 \nseconds.\n\nLet me repeat that. Fourty-five seconds. For a simple \"git status\".\n\nAccording to me, the fact that nobody noticed can only be explained by the \nlack of real submodule users. In particular, the people who invented the \nsubmodules, and pushed them into \"official\" Git, never used it, but \nprecluded more appropriate solutions. I am not complaining, I am just \nstating observations.\n\nIt comes back to my argument that developers should not have beefy \nmachines, lest they lose touch with the users and uses, and develop things \nthat closely skirt reality just so.\n\n>  - Submodules where the provider doesn't care or is not able to provide \n>    a proper .gitignore for other reasons want \"untracked\" to avoid the \n>    noise.\n\nWhile this is a valid scenario, I do not think that any user was hurt \nby that case.\n\n> And these seem to fall into the category: If you are unlucky enough to \n> have one of these included in your superproject, configure these to use \n> \"dirty\" or \"untracked\" as appropriate. And AFAICT they are more the \n> exception than the rule so I came up with this proposal of a per \n> submodule configuration, so people won't have to turn off submodule \n> checking for all submodules because of a single special one.\n\nI agree that the basic reason for the default to check for dirty and \nuntracked files is sound.\n\nIt is not your (Jens') fault that this does not integrate well into the \nGit context, and that users of the submodule feature were punished that \nheavily (just to reiterate, if anybody missed that number, the time on \n\"git status\" -- or for that matter, \"git diff\" -- went up by >4500%. In \nEnglish words, that is four-thousand five hundred percent, and that is \njust a lower bound).\n\nSo I would actually argue (being a real submodule user, not just an \nimaginary one) that the default for dirty checking in the submodules \nshould stay.\n\n> > I don't see a reason for patch 1/2, though.\n> \n> Ok, I will drop that from the next round.\n\nIf I had not stopped caring about consistency in Git, I would strongly \ncontest this dropping.\n\nCiao,\nDscho\n"},{"id":"143288","messageId":"201006090011.14995.johan@herland.net","threadId":"24044","inReplyTo":"4C0E7037.8080403@web.de","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-06-08T22:11:14Z","receivedAt":"2010-06-08T22:11:14Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Tuesday 08 June 2010, Jens Lehmann wrote:\n> After thinking some time about peoples expectations and troubles\n> with the recursive scanning of submodules, I came up with this:\n> \n> What about expanding the \"--ignore-submodules\" option of the git diff\n> family with three parameters:\n> \n> --ignore-submodules=all : Same behavior as \"--ignore-submodules\",\n>   submodules show never up as modified.\n> \n> --ignore-submodules=untracked : Don't consider submodules as modified\n>   when they only contain untracked files, but do if the commits in the\n>   superproject are different or tracked content is modified.\n> \n> --ignore-submodules=dirty : Don't consider submodules as modified\n>   when their work tree is dirty, no matter why. This is the pre 1.7.0\n>   behavior and doesn't recurse into submodules at all.\n\nPardon my ignorance: Does this make \"dirty\" a superset of \"untracked\"? Or \nare they orthogonal. And how does \"all\" compare to \"dirty\"? Are they \nsynonyms, or is \"all\" a superset of \"dirty\"?\n\n> To make that more useful the default could be controlled by the\n> .git/config or .gitmodules file. So you could have two submodules:\n> \n> [submodule \"sub1\"]\n> \tpath = sub1\n> \turl = /home/me/sub1.git/\n> \tignore = dirty\n> [submodule \"sub2\"]\n> \tpath = sub2\n> \turl = /home/me/sub2.git/\n> \tignore = untracked\n> \n> [...]\n> \n> Opinions?\n\nI agree with adding support for this in .gitmodules, to allow customizing on \na per-submodule level.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"143290","messageId":"4C0EC201.9060309@web.de","threadId":"24044","inReplyTo":"201006090011.14995.johan@herland.net","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-08T22:19:45Z","receivedAt":"2010-06-08T22:19:45Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 09.06.2010 00:11, schrieb Johan Herland:\n> On Tuesday 08 June 2010, Jens Lehmann wrote:\n>> After thinking some time about peoples expectations and troubles\n>> with the recursive scanning of submodules, I came up with this:\n>>\n>> What about expanding the \"--ignore-submodules\" option of the git diff\n>> family with three parameters:\n>>\n>> --ignore-submodules=all : Same behavior as \"--ignore-submodules\",\n>>   submodules show never up as modified.\n>>\n>> --ignore-submodules=untracked : Don't consider submodules as modified\n>>   when they only contain untracked files, but do if the commits in the\n>>   superproject are different or tracked content is modified.\n>>\n>> --ignore-submodules=dirty : Don't consider submodules as modified\n>>   when their work tree is dirty, no matter why. This is the pre 1.7.0\n>>   behavior and doesn't recurse into submodules at all.\n> \n> Pardon my ignorance: Does this make \"dirty\" a superset of \"untracked\"? Or \n> are they orthogonal. And how does \"all\" compare to \"dirty\"? Are they \n> synonyms, or is \"all\" a superset of \"dirty\"?\n\nSorry I didn't make that clear enough: \"all\" is a superset of \"dirty\" and\n\"dirty\" is a superset of \"untracked\".\n\nThere are currently (since 1.7.0) three reasons a submodule is considered\ndirty:\n\n1) It contains untracked content\n2) It contains modified tracked content\n3) It contains newer commits than those committed in the superproject\n\n\"all\" would ignore 1), 2) & 3)\n\"dirty\" would ignore 1) & 2)\n\"untracked\" would ignore 1)\n\n\n> I agree with adding support for this in .gitmodules, to allow customizing on \n> a per-submodule level.\n\nYup, and different branches could handle that differently that way too.\n"},{"id":"143295","messageId":"7vy6epqf5y.fsf@alter.siamese.dyndns.org","threadId":"24044","inReplyTo":"alpine.DEB.1.00.1006082247390.1732@bonsai2","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-06-08T23:26:49Z","receivedAt":"2010-06-08T23:26:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> I agree that the basic reason for the default to check for dirty and \n> untracked files is sound.\n>\n> It is not your (Jens') fault that this does not integrate well into the \n> Git context, and that users of the submodule feature were punished that \n> heavily (just to reiterate, if anybody missed that number, the time on \n> \"git status\" -- or for that matter, \"git diff\" -- went up by >4500%. In \n> English words, that is four-thousand five hundred percent, and that is \n> just a lower bound).\n>\n> So I would actually argue (being a real submodule user, not just an \n> imaginary one) that the default for dirty checking in the submodules \n> should stay.\n\nLet me make sure I understand.  You repeated three times that you suffered\nbig time spending too many cycles due to extra checks (compared with older\nbehaviour of not checking submodule working tree at all), but you would\nrecommend the default to be the expensive one?\n\nI am not trying to point out that these two statements are inconsistent. I\nam guessing that you are suggesting to \"default to safe-but-expensive, let\npeople who know what they are doing to tweak for performance\", but you are\nas always a bit too terse for me to be sure, hence this question.\n"},{"id":"143296","messageId":"alpine.DEB.1.00.1006090135170.1732@bonsai2","threadId":"24044","inReplyTo":"7vy6epqf5y.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-06-08T23:36:44Z","receivedAt":"2010-06-08T23:36:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 8 Jun 2010, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > I agree that the basic reason for the default to check for dirty and \n> > untracked files is sound.\n> >\n> > It is not your (Jens') fault that this does not integrate well into the \n> > Git context, and that users of the submodule feature were punished that \n> > heavily (just to reiterate, if anybody missed that number, the time on \n> > \"git status\" -- or for that matter, \"git diff\" -- went up by >4500%. In \n> > English words, that is four-thousand five hundred percent, and that is \n> > just a lower bound).\n> >\n> > So I would actually argue (being a real submodule user, not just an \n> > imaginary one) that the default for dirty checking in the submodules \n> > should stay.\n> \n> Let me make sure I understand.  You repeated three times that you suffered\n> big time spending too many cycles due to extra checks (compared with older\n> behaviour of not checking submodule working tree at all), but you would\n> recommend the default to be the expensive one?\n\nI also pointed out that the suffering came from power usage of submodules.\n\nIf you only have a handful of submodules, and if they are relatively \nsmall, the current default makes much more sense than \n--ignore-submodules=dirty\n\nHth,\nJohannes\n"},{"id":"143299","messageId":"201006090149.22027.johan@herland.net","threadId":"24044","inReplyTo":"4C0EC201.9060309@web.de","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2010-06-08T23:49:21Z","receivedAt":"2010-06-08T23:49:21Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Wednesday 09 June 2010, Jens Lehmann wrote:\n> Am 09.06.2010 00:11, schrieb Johan Herland:\n> > On Tuesday 08 June 2010, Jens Lehmann wrote:\n> >> After thinking some time about peoples expectations and troubles\n> >> with the recursive scanning of submodules, I came up with this:\n> >> \n> >> What about expanding the \"--ignore-submodules\" option of the git diff\n> >> family with three parameters:\n> >> \n> >> --ignore-submodules=all : Same behavior as \"--ignore-submodules\",\n> >> \n> >>   submodules show never up as modified.\n> >> \n> >> --ignore-submodules=untracked : Don't consider submodules as modified\n> >> \n> >>   when they only contain untracked files, but do if the commits in the\n> >>   superproject are different or tracked content is modified.\n> >> \n> >> --ignore-submodules=dirty : Don't consider submodules as modified\n> >> \n> >>   when their work tree is dirty, no matter why. This is the pre 1.7.0\n> >>   behavior and doesn't recurse into submodules at all.\n> > \n> > Pardon my ignorance: Does this make \"dirty\" a superset of \"untracked\"?\n> > Or are they orthogonal. And how does \"all\" compare to \"dirty\"? Are\n> > they synonyms, or is \"all\" a superset of \"dirty\"?\n> \n> Sorry I didn't make that clear enough: \"all\" is a superset of \"dirty\" and\n> \"dirty\" is a superset of \"untracked\".\n> \n> There are currently (since 1.7.0) three reasons a submodule is considered\n> dirty:\n> \n> 1) It contains untracked content\n> 2) It contains modified tracked content\n> 3) It contains newer commits than those committed in the superproject\n\nI guess 3) really means that the submodule's HEAD points to a _different_ \n(not necessarily _newer_) commit than what's referenced in the superproject.\n\n> \"all\" would ignore 1), 2) & 3)\n> \"dirty\" would ignore 1) & 2)\n> \"untracked\" would ignore 1)\n\n...and just to complete my understanding of this, 3) requires only checking \nthe submodule's current HEAD, while 1) and 2) require traversing its work \ntree (i.e. the equivalent of a 'git status'), hence the potential \nexpensiveness.\n\nAlso, I guess 2) includes both staged and unstaged modifications to tracked \ncontent?\n\nThanks for your help. All the ideas in your cover letter seem good to me.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"143306","messageId":"4C0F3355.7050202@web.de","threadId":"24044","inReplyTo":"201006090149.22027.johan@herland.net","subject":"Re: [PATCH 0/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-09T06:23:17Z","receivedAt":"2010-06-09T06:23:17Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 09.06.2010 01:49, schrieb Johan Herland:\n> On Wednesday 09 June 2010, Jens Lehmann wrote:\n>> There are currently (since 1.7.0) three reasons a submodule is considered\n>> dirty:\n>>\n>> 1) It contains untracked content\n>> 2) It contains modified tracked content\n>> 3) It contains newer commits than those committed in the superproject\n> \n> I guess 3) really means that the submodule's HEAD points to a _different_ \n> (not necessarily _newer_) commit than what's referenced in the superproject.\n\nSure, please replace my inaccurate description with yours ;-)\n\n\n>> \"all\" would ignore 1), 2) & 3)\n>> \"dirty\" would ignore 1) & 2)\n>> \"untracked\" would ignore 1)\n> \n> ...and just to complete my understanding of this, 3) requires only checking \n> the submodule's current HEAD, while 1) and 2) require traversing its work \n> tree (i.e. the equivalent of a 'git status'), hence the potential \n> expensiveness.\n\nThats correct.\n\n\n> Also, I guess 2) includes both staged and unstaged modifications to tracked \n> content?\n\nYes (as it doesn't make a difference to the superproject if modifications\ninside the submodule are staged or not there is no distinction made between\nthose two).\n\n\n> Thanks for your help. All the ideas in your cover letter seem good to me.\n\nThank you for your comments, I'll start hacking to show some more patches.\n"},{"id":"144155","messageId":"oyrgMnuxMzyEmKMa6Bb_rvLb_zp8WscXW73T03xzJ5_bpheAt9Hpcw@cipher.nrlssc.navy.mil","threadId":"24044","inReplyTo":"4C0E7077.9090509@web.de","subject":"Re: [PATCH 2/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Brandon Casey","fromEmail":"brandon.casey.ctr@nrlssc.navy.mil","sentAt":"2010-06-24T14:23:04Z","receivedAt":"2010-06-24T14:23:04Z","isPatch":true,"sender":{"key":"brandon.casey.ctr@nrlssc.navy.mil","avatar":null},"body":"On 06/08/2010 11:31 AM, Jens Lehmann wrote:\n\nTwo things...\n\n> diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh\n> index 83c1914..559b41e 100755\n> --- a/t/t4027-diff-submodule.sh\n> +++ b/t/t4027-diff-submodule.sh\n> @@ -103,9 +103,17 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'\n>  \tgit diff HEAD >actual &&\n>  \tsed -e \"1,/^@@/d\" actual >actual.body &&\n>  \texpect_from_to >expect.body $subprev $subprev-dirty &&\n> -\ttest_cmp expect.body actual.body\n> +\ttest_cmp expect.body actual.body &&\n> +\tgit diff --ignore-submodules HEAD >actual2 &&\n> +\techo -n \"\" | test_cmp - actual2 &&\n\n'echo -n' is not portable (here, and below).  Please use printf\ninstead.  Ditto for t4041\n\n> +\tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n> +\tsed -e \"1,/^@@/d\" actual3 >actual3.body &&\n> +\texpect_from_to >expect.body $subprev $subprev-dirty &&\n> +\ttest_cmp expect.body actual3.body &&\n> +\tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n> +\techo -n \"\" | test_cmp - actual4\n>  '\n> -\n> +test_done\n   ^^^^^^^^^\n\nWhy is this test_done here?  There are additional tests after this point,\nand an additional call to test_done.\n\n\n>  test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '\n>  \t(\n>  \t\tcd sub &&\n> @@ -129,7 +137,13 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'\n>  \tgit diff HEAD >actual &&\n>  \tsed -e \"1,/^@@/d\" actual >actual.body &&\n>  \texpect_from_to >expect.body $subprev $subprev-dirty &&\n> -\ttest_cmp expect.body actual.body\n> +\ttest_cmp expect.body actual.body &&\n> +\tgit diff --ignore-submodules=all HEAD >actual2 &&\n> +\techo -n \"\" | test_cmp - actual2 &&\n> +\tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n> +\techo -n \"\" | test_cmp - actual3 &&\n> +\tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n> +\techo -n \"\" | test_cmp - actual4\n>  '\n> \n>  test_expect_success 'git diff (empty submodule dir)' '\n> diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh\n> index 019acb9..f44b906 100755\n> --- a/t/t4041-diff-submodule-option.sh\n> +++ b/t/t4041-diff-submodule-option.sh\n"},{"id":"144164","messageId":"4C2391CF.5090606@web.de","threadId":"24044","inReplyTo":"oyrgMnuxMzyEmKMa6Bb_rvLb_zp8WscXW73T03xzJ5_bpheAt9Hpcw@cipher.nrlssc.navy.mil","subject":"Re: [PATCH 2/2] Add optional parameters to the diff option \"--ignore-submodules\"","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2010-06-24T17:11:43Z","receivedAt":"2010-06-24T17:11:43Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 24.06.2010 16:23, schrieb Brandon Casey:\n> On 06/08/2010 11:31 AM, Jens Lehmann wrote:\n> \n> Two things...\n> \n>> diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh\n>> index 83c1914..559b41e 100755\n>> --- a/t/t4027-diff-submodule.sh\n>> +++ b/t/t4027-diff-submodule.sh\n>> @@ -103,9 +103,17 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'\n>>  \tgit diff HEAD >actual &&\n>>  \tsed -e \"1,/^@@/d\" actual >actual.body &&\n>>  \texpect_from_to >expect.body $subprev $subprev-dirty &&\n>> -\ttest_cmp expect.body actual.body\n>> +\ttest_cmp expect.body actual.body &&\n>> +\tgit diff --ignore-submodules HEAD >actual2 &&\n>> +\techo -n \"\" | test_cmp - actual2 &&\n> \n> 'echo -n' is not portable (here, and below).  Please use printf\n> instead.  Ditto for t4041\n\nThanks, I haven't been aware of that.\n\n\n>> +\tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n>> +\tsed -e \"1,/^@@/d\" actual3 >actual3.body &&\n>> +\texpect_from_to >expect.body $subprev $subprev-dirty &&\n>> +\ttest_cmp expect.body actual3.body &&\n>> +\tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n>> +\techo -n \"\" | test_cmp - actual4\n>>  '\n>> -\n>> +test_done\n>    ^^^^^^^^^\n> \n> Why is this test_done here?  There are additional tests after this point,\n> and an additional call to test_done.\n\nGrmph, this is a leftover from debugging :-(\nThank you for spotting this one too!\n\n\nAs the patch introducing this is already in next, here is another one:\n\n--------------------8<--------------------------\nFrom: Jens Lehmann <Jens.Lehmann@web.de>\nDate: Thu, 24 Jun 2010 19:01:27 +0200\nSubject: [PATCH] t4027 & t4041: Fix use of \"echo -n\" and a premature \"test_done\"\n\nReplace the non portable \"echo -n\" with \"printf\" and remove a premature\n\"test_done\".\n\nReported-by: Brandon Casey <brandon.casey.ctr@nrlssc.navy.mil>\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n t/t4027-diff-submodule.sh        |   12 ++++++------\n t/t4041-diff-submodule-option.sh |   14 +++++++-------\n 2 files changed, 13 insertions(+), 13 deletions(-)\n\ndiff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh\nindex 559b41e..3f2e591 100755\n--- a/t/t4027-diff-submodule.sh\n+++ b/t/t4027-diff-submodule.sh\n@@ -105,15 +105,15 @@ test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)'\n \texpect_from_to >expect.body $subprev $subprev-dirty &&\n \ttest_cmp expect.body actual.body &&\n \tgit diff --ignore-submodules HEAD >actual2 &&\n-\techo -n \"\" | test_cmp - actual2 &&\n+\tprintf \"\" | test_cmp - actual2 &&\n \tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n \tsed -e \"1,/^@@/d\" actual3 >actual3.body &&\n \texpect_from_to >expect.body $subprev $subprev-dirty &&\n \ttest_cmp expect.body actual3.body &&\n \tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n-\techo -n \"\" | test_cmp - actual4\n+\tprintf \"\" | test_cmp - actual4\n '\n-test_done\n+\n test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' '\n \t(\n \t\tcd sub &&\n@@ -139,11 +139,11 @@ test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)'\n \texpect_from_to >expect.body $subprev $subprev-dirty &&\n \ttest_cmp expect.body actual.body &&\n \tgit diff --ignore-submodules=all HEAD >actual2 &&\n-\techo -n \"\" | test_cmp - actual2 &&\n+\tprintf \"\" | test_cmp - actual2 &&\n \tgit diff --ignore-submodules=untracked HEAD >actual3 &&\n-\techo -n \"\" | test_cmp - actual3 &&\n+\tprintf \"\" | test_cmp - actual3 &&\n \tgit diff --ignore-submodules=dirty HEAD >actual4 &&\n-\techo -n \"\" | test_cmp - actual4\n+\tprintf \"\" | test_cmp - actual4\n '\n\n test_expect_success 'git diff (empty submodule dir)' '\ndiff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh\nindex f44b906..7600ed1 100755\n--- a/t/t4041-diff-submodule-option.sh\n+++ b/t/t4041-diff-submodule-option.sh\n@@ -207,17 +207,17 @@ EOF\n\n test_expect_success 'submodule contains untracked content (untracked ignored)' \"\n \tgit diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'submodule contains untracked content (dirty ignored)' \"\n \tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'submodule contains untracked content (all ignored)' \"\n \tgit diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'submodule contains untracked and modifed content' \"\n@@ -240,13 +240,13 @@ EOF\n test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' \"\n \techo new > sm1/foo6 &&\n \tgit diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'submodule contains untracked and modifed content (all ignored)' \"\n \techo new > sm1/foo6 &&\n \tgit diff-index -p --ignore-submodules --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'submodule contains modifed content' \"\n@@ -295,7 +295,7 @@ EOF\n\n test_expect_success 'modified submodule contains untracked content (all ignored)' \"\n \tgit diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'modified submodule contains untracked and modifed content' \"\n@@ -331,7 +331,7 @@ EOF\n test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' \"\n \techo modification >> sm1/foo6 &&\n \tgit diff-index -p --ignore-submodules --submodule=log HEAD >actual &&\n-\techo -n '' | diff actual -\n+\tprintf '' | diff actual -\n \"\n\n test_expect_success 'modified submodule contains modifed content' \"\n-- \n1.7.1.716.g6c3d8\n"}]}