{"thread":{"id":"36308","subject":"git commit vs. ignore-submodules","startedAt":"2014-03-27T23:36:00Z","lastAt":"2014-04-24T19:42:57Z","messageCount":51,"participants":["Ronald Weiss","Jens Lehmann","Junio C Hamano","Eric Sunshine"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"237960","messageId":"CABxC_L92v=cV=+e_DNa0L6f21LB0BRP5duai2h_heGJN_PRoUQ@mail.gmail.com","threadId":"36308","inReplyTo":null,"subject":"git commit vs. ignore-submodules","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-27T23:36:00Z","receivedAt":"2014-03-27T23:36:00Z","isPatch":false,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Hello.\n\nAs this is my first post to this list, let me first thank all the\npeople involved in Git development - it's really a great tool.\n\nNow to the point. Since Git 1.8 (I think), git commit command honours\nthe submodules' ignore settings, configured either in .gitmodules, or\nin .git/config. That's very nice and certainly correct for \"git commit\n-a\", but it's less clear if one explicitely stages an updated\nsubmodule using git add. Git commit will ignore it anyway, if\nignore=all is configured in .gitmodules. Maybe that's correct too, I'm\nnot sure about that, but it's inconvenient in our use case, especially\ncombined with the lack of --ignore-submodule parameter to git commit,\nas git status and git diff have.\n\nWe use submodules in such a way that normally we don't ever want to\nsee changes in them in output of git diff and git status. So we set\nignore=all in .gitmodules for each submodule. But occasionally, we\nneed to add a new submodule, and sometimes also commit changed\nsubmodule. This got harder with Git 1.8, we have to \"git config\nsubmodule.<name>.ignore none\" before the commit, and \"git config\n--unset ...\" after.\n\nI'd like to at least add an --ignore-submodules parameter to git\ncommit. I though about posting a patch, but as I looked into the\ncommit source file, I didn't see any straightforward way to implement\nit. I don't have enough free time for a deeper analysis of the\nsources, I'm sorry.\n\nSo please, let me first know, whether you could possibly accept such\npatch, and if so, then I'd really appreciate some hints on how to do\nit.\n\nAnd also, I'd like to know git folks' opinion on whether it's OK that\ngit commit with ignore=all in .gitmodules ignores submodules even when\nthey are explicitely staged with git add.\n\nThanks in advance for any reply,\nRonald Weiss\n"},{"id":"238011","messageId":"5335A78C.60401@web.de","threadId":"36308","inReplyTo":"CABxC_L92v=cV=+e_DNa0L6f21LB0BRP5duai2h_heGJN_PRoUQ@mail.gmail.com","subject":"Re: git commit vs. ignore-submodules","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-28T16:47:08Z","receivedAt":"2014-03-28T16:47:08Z","isPatch":false,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 28.03.2014 00:36, schrieb Ronald Weiss:\n> Hello.\n> \n> As this is my first post to this list, let me first thank all the\n> people involved in Git development - it's really a great tool.\n\nWelcome and thanks for the feedback!\n\n> Now to the point. Since Git 1.8 (I think), git commit command honours\n> the submodules' ignore settings, configured either in .gitmodules, or\n> in .git/config. That's very nice and certainly correct for \"git commit\n> -a\", but it's less clear if one explicitely stages an updated\n> submodule using git add. Git commit will ignore it anyway, if\n> ignore=all is configured in .gitmodules. Maybe that's correct too, I'm\n> not sure about that, but it's inconvenient in our use case, especially\n> combined with the lack of --ignore-submodule parameter to git commit,\n> as git status and git diff have.\n> \n> We use submodules in such a way that normally we don't ever want to\n> see changes in them in output of git diff and git status. So we set\n> ignore=all in .gitmodules for each submodule. But occasionally, we\n> need to add a new submodule, and sometimes also commit changed\n> submodule. This got harder with Git 1.8, we have to \"git config\n> submodule.<name>.ignore none\" before the commit, and \"git config\n> --unset ...\" after.\n> \n> I'd like to at least add an --ignore-submodules parameter to git\n> commit. I though about posting a patch, but as I looked into the\n> commit source file, I didn't see any straightforward way to implement\n> it. I don't have enough free time for a deeper analysis of the\n> sources, I'm sorry.\n> \n> So please, let me first know, whether you could possibly accept such\n> patch, and if so, then I'd really appreciate some hints on how to do\n> it.\n\nSuch a patch would be very much appreciated. You might want to look\ninto other commands that already have the --ignore-submodules option\nto get an idea how to do that. cmd_status() in builtin/commit.c\nshould be a good starting point.\n\n> And also, I'd like to know git folks' opinion on whether it's OK that\n> git commit with ignore=all in .gitmodules ignores submodules even when\n> they are explicitely staged with git add.\n\nNo, they should be visible in status and commit when the user chose\nto add them. I see if I can hack something up (as I've been bitten\nmyself by that recently ;-).\n"},{"id":"238024","messageId":"xmqqbnwqb3wo.fsf@gitster.dls.corp.google.com","threadId":"36308","inReplyTo":"5335A78C.60401@web.de","subject":"Re: git commit vs. ignore-submodules","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-03-28T17:59:19Z","receivedAt":"2014-03-28T17:59:19Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n>> .. but it's less clear if one explicitely stages an updated\n>> submodule using git add. Git commit will ignore it anyway, if\n>> ignore=all is configured in .gitmodules. Maybe that's correct too\n\nThat definitely smells like a bug to me.  Excluding modified\nsubmodules when \"git add -u\" is run with ignore=all would be fine\nand most likely the right thing to do, but once the user actually\nadds the change to the index, it should not be ignored.\n\n> ...\n>> And also, I'd like to know git folks' opinion on whether it's OK that\n>> git commit with ignore=all in .gitmodules ignores submodules even when\n>> they are explicitely staged with git add.\n>\n> No, they should be visible in status and commit when the user chose\n> to add them. I see if I can hack something up (as I've been bitten\n> myself by that recently ;-).\n\nThanks.\n"},{"id":"238061","messageId":"CABxC_L-4=qcZiix05dL8GrDJXv=19fw4yB0qFzRRfw=G=_Gxbg@mail.gmail.com","threadId":"36308","inReplyTo":"5335A78C.60401@web.de","subject":"Re: git commit vs. ignore-submodules","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-29T22:44:09Z","receivedAt":"2014-03-29T22:44:09Z","isPatch":false,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On Fri, Mar 28, 2014 at 5:47 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n> Such a patch would be very much appreciated. You might want to look\n> into other commands that already have the --ignore-submodules option\n> to get an idea how to do that. cmd_status() in builtin/commit.c\n> should be a good starting point.\n\nOK, I managed to create a patch, will post it as separate email right\nafter this one. I also had to touch builtin/add.c, to make the new\n--ignore-submodes option work with \"git commit -a\" too.\n\n>> And also, I'd like to know git folks' opinion on whether it's OK that\n>> git commit with ignore=all in .gitmodules ignores submodules even when\n>> they are explicitely staged with git add.\n>\n> No, they should be visible in status and commit when the user chose\n> to add them. I see if I can hack something up (as I've been bitten\n> myself by that recently ;-).\n\nWhile I was playing with that now, I discovered that the problem is\nactually not in commit, but only in status. Commit really commits the\nsubmodule, but it's not visible in the commit message (generated by\nstatus), that confused me before. And if there are no other changes in\nthe index, then commit fails immediately with \"no changes\". A small\nchange in wt-status.c fixes that for me, but I'm not sure about any\nundesired side effects. I'll post a patch for that too, in a few\nmoments.\n"},{"id":"238062","messageId":"53374E49.9000702@gmail.com","threadId":"36308","inReplyTo":"CABxC_L-4=qcZiix05dL8GrDJXv=19fw4yB0qFzRRfw=G=_Gxbg@mail.gmail.com","subject":"[PATCH 1/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-29T22:50:49Z","receivedAt":"2014-03-29T22:50:49Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Git commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line, like other commands do.\n\nUseful <when> values for commit are 'all' (default) or 'none'. The others\n('dirty' and 'untracked') have same effect as 'none', as commit is only\ninterested in whether the submodule's HEAD differs from what is commited\nin the superproject.\n\nChanges in add.c and cache.h (and related compilo fix in checkout.c) are\nneeded to make it work for \"commit -a\" too.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\n Documentation/git-commit.txt |  6 ++++++\n builtin/add.c                | 16 ++++++++++++----\n builtin/checkout.c           |  2 +-\n builtin/commit.c             |  8 +++++++-\n cache.h                      |  2 +-\n 5 files changed, 27 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 1a7616c..c8839c8 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -271,6 +272,11 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'ignore' option\n+\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 672adc0..1086294 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n \n static void update_files_in_cache(const char *prefix,\n \t\t\t\t  const struct pathspec *pathspec,\n-\t\t\t\t  struct update_callback_data *data)\n+\t\t\t\t  struct update_callback_data *data,\n+\t\t\t\t  const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \n@@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \n \tmemset(&data, 0, sizeof(data));\n \tdata.flags = flags;\n-\tupdate_files_in_cache(prefix, pathspec, &data);\n+\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n \treturn !!data.add_errors;\n }\n \n@@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tmemset(&pathspec, 0, sizeof(pathspec));\n \t}\n \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n-\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n+\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n \n \texit_status |= !!update_data.add_errors;\n \tif (add_new_files)\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ada51fa..22a4b48 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 26b2986..121c185 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/cache.h b/cache.h\nindex ebe9a40..5ef8dd6 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\n-- \n1.9.0\n \n"},{"id":"238063","messageId":"53374F82.3020800@gmail.com","threadId":"36308","inReplyTo":"CABxC_L-4=qcZiix05dL8GrDJXv=19fw4yB0qFzRRfw=G=_Gxbg@mail.gmail.com","subject":"[PATCH 2/2] status: don't ignore submodules added to index","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-29T22:56:02Z","receivedAt":"2014-03-29T22:56:02Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Submodules explicitly added to index by user should be never hidden in\nstatus output.\n\nThis also fixes a bug in commit, where submodules with configured ignore\nsetting (in .gitmodules or .git/config), added to index by user, are not\ndisplayed in the commit message as being commited, but they still are\ncommited. Unless the changed submodules are the only changes in the index,\nin such case commit fails immediately with \"no changes\", which is even\nworse.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\n wt-status.c | 6 ++----\n 1 file changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex a452407..108a048 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -486,10 +486,8 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \topt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n \n-\tif (s->ignore_submodule_arg) {\n-\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n-\t\thandle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);\n-\t}\n+\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\tDIFF_OPT_CLR(&rev.diffopt, IGNORE_SUBMODULES);\n \n \trev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;\n \trev.diffopt.format_callback = wt_status_collect_updated_cb;\n-- \n1.9.0\n \n"},{"id":"238065","messageId":"533753B9.6040001@web.de","threadId":"36308","inReplyTo":"53374E49.9000702@gmail.com","subject":"Re: [PATCH 1/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-29T23:14:01Z","receivedAt":"2014-03-29T23:14:01Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 29.03.2014 23:50, schrieb Ronald Weiss:\n> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n> but didn't allow to override it from command line, like other commands do.\n> \n> Useful <when> values for commit are 'all' (default) or 'none'. The others\n> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n> interested in whether the submodule's HEAD differs from what is commited\n> in the superproject.\n> \n> Changes in add.c and cache.h (and related compilo fix in checkout.c) are\n> needed to make it work for \"commit -a\" too.\n\nThanks, looking good from first glance, will look deeper into that\ntomorrow.\n\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  Documentation/git-commit.txt |  6 ++++++\n>  builtin/add.c                | 16 ++++++++++++----\n>  builtin/checkout.c           |  2 +-\n>  builtin/commit.c             |  8 +++++++-\n>  cache.h                      |  2 +-\n>  5 files changed, 27 insertions(+), 7 deletions(-)\n> \n> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\n> index 1a7616c..c8839c8 100644\n> --- a/Documentation/git-commit.txt\n> +++ b/Documentation/git-commit.txt\n> @@ -13,6 +13,7 @@ SYNOPSIS\n>  \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n>  \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n>  \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n> +\t   [--ignore-submodules[=<when>]]\n>  \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n>  \n>  DESCRIPTION\n> @@ -271,6 +272,11 @@ The possible options are:\n>  The default can be changed using the status.showUntrackedFiles\n>  configuration variable documented in linkgit:git-config[1].\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'ignore' option\n> +\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\" or \"all\", which is the default.\n> +\n>  -v::\n>  --verbose::\n>  \tShow unified diff between the HEAD commit and what\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 672adc0..1086294 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n>  \n>  static void update_files_in_cache(const char *prefix,\n>  \t\t\t\t  const struct pathspec *pathspec,\n> -\t\t\t\t  struct update_callback_data *data)\n> +\t\t\t\t  struct update_callback_data *data,\n> +\t\t\t\t  const char *ignore_submodules_arg)\n>  {\n>  \tstruct rev_info rev;\n>  \n> @@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n>  \trev.diffopt.format_callback = update_callback;\n>  \trev.diffopt.format_callback_data = data;\n>  \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n> +\n> +\tif (ignore_submodules_arg) {\n> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n> +\t}\n> +\n>  \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n>  }\n>  \n>  int add_files_to_cache(const char *prefix,\n> -\t\t       const struct pathspec *pathspec, int flags)\n> +\t\t       const struct pathspec *pathspec, int flags,\n> +\t\t       const char *ignore_submodules_arg)\n>  {\n>  \tstruct update_callback_data data;\n>  \n>  \tmemset(&data, 0, sizeof(data));\n>  \tdata.flags = flags;\n> -\tupdate_files_in_cache(prefix, pathspec, &data);\n> +\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n>  \treturn !!data.add_errors;\n>  }\n>  \n> @@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\tmemset(&pathspec, 0, sizeof(pathspec));\n>  \t}\n>  \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n> -\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n> +\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n>  \n>  \texit_status |= !!update_data.add_errors;\n>  \tif (add_new_files)\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index ada51fa..22a4b48 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n>  \t\t\t * entries in the index.\n>  \t\t\t */\n>  \n> -\t\t\tadd_files_to_cache(NULL, NULL, 0);\n> +\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n>  \t\t\t/*\n>  \t\t\t * NEEDSWORK: carrying over local changes\n>  \t\t\t * when branches have different end-of-line\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 26b2986..121c185 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> @@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n>  \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n>  \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n> +\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \t\t/* end commit contents options */\n>  \n>  \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n> @@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n>  \t\t\t\t\t  builtin_commit_usage,\n>  \t\t\t\t\t  prefix, current_head, &s);\n> +\n> +\ts.ignore_submodule_arg = ignore_submodule_arg;\n> +\n>  \tif (dry_run)\n>  \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n>  \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\n> diff --git a/cache.h b/cache.h\n> index ebe9a40..5ef8dd6 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n>   * return 0 if success, 1 - if addition of a file failed and\n>   * ADD_FILES_IGNORE_ERRORS was specified in flags\n>   */\n> -int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n> +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n>  \n>  /* diff.c */\n>  extern int diff_auto_refresh_index;\n> \n"},{"id":"238066","messageId":"53375447.2050502@web.de","threadId":"36308","inReplyTo":"53374F82.3020800@gmail.com","subject":"Re: [PATCH 2/2] status: don't ignore submodules added to index","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-29T23:16:23Z","receivedAt":"2014-03-29T23:16:23Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 29.03.2014 23:56, schrieb Ronald Weiss:\n> Submodules explicitly added to index by user should be never hidden in\n> status output.\n> \n> This also fixes a bug in commit, where submodules with configured ignore\n> setting (in .gitmodules or .git/config), added to index by user, are not\n> displayed in the commit message as being commited, but they still are\n> commited. Unless the changed submodules are the only changes in the index,\n> in such case commit fails immediately with \"no changes\", which is even\n> worse.\n\nThanks, but I think this patch falls a bit short (I assume you should see\ntest failures with this patch). I'm currently working on fixing that, will\npost that as soon as I finished it.\n\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  wt-status.c | 6 ++----\n>  1 file changed, 2 insertions(+), 4 deletions(-)\n> \n> diff --git a/wt-status.c b/wt-status.c\n> index a452407..108a048 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -486,10 +486,8 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n>  \topt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;\n>  \tsetup_revisions(0, NULL, &rev, &opt);\n>  \n> -\tif (s->ignore_submodule_arg) {\n> -\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> -\t\thandle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);\n> -\t}\n> +\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\tDIFF_OPT_CLR(&rev.diffopt, IGNORE_SUBMODULES);\n>  \n>  \trev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;\n>  \trev.diffopt.format_callback = wt_status_collect_updated_cb;\n> \n"},{"id":"238067","messageId":"533759EB.20100@gmail.com","threadId":"36308","inReplyTo":"53375447.2050502@web.de","subject":"Re: [PATCH 2/2] status: don't ignore submodules added to index","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-29T23:40:27Z","receivedAt":"2014-03-29T23:40:27Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 30. 3. 2014 0:16, Jens Lehmann wrote:\n> Thanks, but I think this patch falls a bit short (I assume you should see\n> test failures with this patch). I'm currently working on fixing that, will\n> post that as soon as I finished it.\n\nYou're right, 3 tests from t7508 failed with that, I'm sorry for not\nverifying that :-(.\n\nThat change was really too aggresive, the one below seems better, all\ntests pass with it, and it still works. But I'm not sending it as patch\nanymore, knowing that You are already working on better solution.\n\ndiff --git a/wt-status.c b/wt-status.c\nindex a452407..520835e 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -489,4 +489,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n        if (s->ignore_submodule_arg) {\n                DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n                handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);\n+       } else {\n+               DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+               DIFF_OPT_CLR(&rev.diffopt, IGNORE_SUBMODULES);\n        }\n"},{"id":"238069","messageId":"53375EE6.1020407@gmail.com","threadId":"36308","inReplyTo":"533759EB.20100@gmail.com","subject":"Re: [PATCH 2/2] status: don't ignore submodules added to index","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-30T00:01:42Z","receivedAt":"2014-03-30T00:01:42Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 30. 3. 2014 0:40, Ronald Weiss wrote:\n> That change was really too aggresive, the one below seems better, all\n> tests pass with it, and it still works.\n\nOops, some tests still fail, sorry for my blindness. Nevermind, I'm \nlooking forward to Your fix.\n"},{"id":"238075","messageId":"5337EE9C.4080101@web.de","threadId":"36308","inReplyTo":"5335A78C.60401@web.de","subject":"[WIP/PATCH] status/commit: always show staged submodules regardless of ignore config","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-30T10:14:52Z","receivedAt":"2014-03-30T10:14:52Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Currently setting submodule.<name>.ignore and/or diff.ignoreSubmodules to\n\"all\" suppresses all output of submodule changes for the diff family,\nstatus and commit. For status and commit this is really confusing, as it\neven when the user chooses to record a new commit for an ignored submodule\nby adding it manually this change won't show up under the to-be-committed\nchanges. To add insult to injury, a later \"git commit\" will error out with\n\"nothing to commit\" when only ignored submodules are staged.\n\nFix that by making wt_status always print staged submodule changes, no\nmatter what ignore settings are configured. The only exception is when the\nuser explicitly uses the \"--ignore-submodules=all\" command line option, in\nthat case the submodule output is still suppressed. This also makes \"git\ncommit\" work again when only modifications of ignored submodules are\nstaged, as that command uses the \"commitable\" member of the wt_status\nstruct to determine if staged changes are present.\n\nChange t7508 to reflect this new behavior. Also mention it in the\ndocumentation of the ignore config options.\n\nSigned-off-by: Jens Lehmann <Jens.Lehmann@web.de>\n---\n\n\nAm 28.03.2014 17:47, schrieb Jens Lehmann:\n> Am 28.03.2014 00:36, schrieb Ronald Weiss:\n>> And also, I'd like to know git folks' opinion on whether it's OK that\n>> git commit with ignore=all in .gitmodules ignores submodules even when\n>> they are explicitely staged with git add.\n> \n> No, they should be visible in status and commit when the user chose\n> to add them. I see if I can hack something up (as I've been bitten\n> myself by that recently ;-).\n\nOk, here we go! As we discussed the same issue last November I\nadded the people involved back then to the CC.\n\nI still need to fix an issue with this patch: committing a single\nignored submodule sometimes exits with an error code (even though\nthe commit succeeds), I'm still looking into that and will provide\na test for commit too.\n\nAfter this we need at least two other patches:\n\n- git gui should show staged ignored submodules\n\n- gitk should show staged ignored submodules\n\n(It'd be great if someone else would tackle these two, just let me\nknow if you want to to avoid duplicated work)\n\nDid I forget a git command that shows what is to be staged?\n\n\n Documentation/config.txt     |  8 ++++++--\n Documentation/gitmodules.txt |  4 +++-\n t/t7508-status.sh            | 29 +++++++++++++++++++++++++++--\n wt-status.c                  | 12 +++++++++++-\n 4 files changed, 47 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 73c8973..0a2e9ad 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -2279,7 +2279,9 @@ status.submodulesummary::\n \t--summary-limit option of linkgit:git-submodule[1]). Please note\n \tthat the summary output command will be suppressed for all\n \tsubmodules when `diff.ignoreSubmodules` is set to 'all' or only\n-\tfor those submodules where `submodule.<name>.ignore=all`. To\n+\tfor those submodules where `submodule.<name>.ignore=all`. The only\n+\texception to that rule is that status and commit will always show\n+\tsubmodule changes that have been staged. To\n \talso view the summary for ignored submodules you can either use\n \tthe --ignore-submodules=dirty command line option or the 'git\n \tsubmodule summary' command, which shows a similar output but does\n@@ -2310,7 +2312,9 @@ submodule.<name>.fetchRecurseSubmodules::\n submodule.<name>.ignore::\n \tDefines under what circumstances \"git status\" and the diff family show\n \ta submodule as modified. When set to \"all\", it will never be considered\n-\tmodified, \"dirty\" will ignore all changes to the submodules work tree and\n+\tmodified (but will nonetheless show up in the output of status and\n++\tcommit when they have been staged), \"dirty\" will ignore all changes\n+\tto the submodules work tree and\n \ttakes only differences between the HEAD of the submodule and the commit\n \trecorded in the superproject into account. \"untracked\" will additionally\n \tlet submodules with modified tracked files in their work tree show up.\ndiff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt\nindex f539e3f..f684963 100644\n--- a/Documentation/gitmodules.txt\n+++ b/Documentation/gitmodules.txt\n@@ -71,7 +71,9 @@ submodule.<name>.fetchRecurseSubmodules::\n submodule.<name>.ignore::\n \tDefines under what circumstances \"git status\" and the diff family show\n \ta submodule as modified. When set to \"all\", it will never be considered\n-\tmodified, \"dirty\" will ignore all changes to the submodules work tree and\n+\tmodified (but will nonetheless show up in the output of status and\n+\tcommit when they have been staged), \"dirty\" will ignore all changes\n+\tto the submodules work tree and\n \ttakes only differences between the HEAD of the submodule and the commit\n \trecorded in the superproject into account. \"untracked\" will additionally\n \tlet submodules with modified tracked files in their work tree show up.\ndiff --git a/t/t7508-status.sh b/t/t7508-status.sh\nindex c987b5e..f2b89e8 100755\n--- a/t/t7508-status.sh\n+++ b/t/t7508-status.sh\n@@ -1380,7 +1380,32 @@ EOF\n \ttest_i18ncmp expect output\n '\n\n-test_expect_success '.gitmodules ignore=all suppresses submodule summary' '\n+test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '\n+\tcat > expect << EOF &&\n+On branch master\n+Changes to be committed:\n+  (use \"git reset HEAD <file>...\" to unstage)\n+\n+\tmodified:   sm\n+\n+Changes not staged for commit:\n+  (use \"git add <file>...\" to update what will be committed)\n+  (use \"git checkout -- <file>...\" to discard changes in working directory)\n+\n+\tmodified:   dir1/modified\n+\n+Untracked files:\n+  (use \"git add <file>...\" to include in what will be committed)\n+\n+\t.gitmodules\n+\tdir1/untracked\n+\tdir2/modified\n+\tdir2/untracked\n+\texpect\n+\toutput\n+\tuntracked\n+\n+EOF\n \tgit config --add -f .gitmodules submodule.subname.ignore all &&\n \tgit config --add -f .gitmodules submodule.subname.path sm &&\n \tgit status > output &&\n@@ -1388,7 +1413,7 @@ test_expect_success '.gitmodules ignore=all suppresses submodule summary' '\n \tgit config -f .gitmodules  --remove-section submodule.subname\n '\n\n-test_expect_success '.git/config ignore=all suppresses submodule summary' '\n+test_expect_success '.git/config ignore=all suppresses unstaged submodule summary' '\n \tgit config --add -f .gitmodules submodule.subname.ignore none &&\n \tgit config --add -f .gitmodules submodule.subname.path sm &&\n \tgit config --add submodule.subname.ignore all &&\ndiff --git a/wt-status.c b/wt-status.c\nindex e1827fa..821d10c 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -519,9 +519,19 @@ static void wt_status_collect_changes_index(struct wt_status *s)\n \topt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;\n \tsetup_revisions(0, NULL, &rev, &opt);\n\n+\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n \tif (s->ignore_submodule_arg) {\n-\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n \t\thandle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);\n+\t} else {\n+\t\t/*\n+\t\t * Unless the user did explicitly request a submodule ignore\n+\t\t * mode by passing a command line option we do not ignore any\n+\t\t * changed submodule SHA-1s when comparing index and HEAD, no\n+\t\t * matter what is configured. Otherwise the user won't be\n+\t\t * shown any submodules she manually added (and which are\n+\t\t * staged to be committed), which would be really confusing.\n+\t\t */\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, \"dirty\");\n \t}\n\n \trev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;\n-- \n1.9.1.378.g5fbabd4\n"},{"id":"238105","messageId":"533874F9.3090802@web.de","threadId":"36308","inReplyTo":"53374E49.9000702@gmail.com","subject":"Re: [PATCH 1/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-30T19:48:09Z","receivedAt":"2014-03-30T19:48:09Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 29.03.2014 23:50, schrieb Ronald Weiss:\n> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n> but didn't allow to override it from command line, like other commands do.\n> \n> Useful <when> values for commit are 'all' (default) or 'none'. The others\n> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n> interested in whether the submodule's HEAD differs from what is commited\n> in the superproject.\n> \n> Changes in add.c and cache.h (and related compilo fix in checkout.c) are\n> needed to make it work for \"commit -a\" too.\n\nLooking good so far, but we definitely need tests for this new option.\n\nBut I wonder if it would make more sense to start by teaching the\n--ignore-submodules option to git add. Then this patch could reuse\nthat for commit -a.\n\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  Documentation/git-commit.txt |  6 ++++++\n>  builtin/add.c                | 16 ++++++++++++----\n>  builtin/checkout.c           |  2 +-\n>  builtin/commit.c             |  8 +++++++-\n>  cache.h                      |  2 +-\n>  5 files changed, 27 insertions(+), 7 deletions(-)\n> \n> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\n> index 1a7616c..c8839c8 100644\n> --- a/Documentation/git-commit.txt\n> +++ b/Documentation/git-commit.txt\n> @@ -13,6 +13,7 @@ SYNOPSIS\n>  \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n>  \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n>  \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n> +\t   [--ignore-submodules[=<when>]]\n>  \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n>  \n>  DESCRIPTION\n> @@ -271,6 +272,11 @@ The possible options are:\n>  The default can be changed using the status.showUntrackedFiles\n>  configuration variable documented in linkgit:git-config[1].\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'ignore' option\n> +\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\" or \"all\", which is the default.\n> +\n>  -v::\n>  --verbose::\n>  \tShow unified diff between the HEAD commit and what\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 672adc0..1086294 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n>  \n>  static void update_files_in_cache(const char *prefix,\n>  \t\t\t\t  const struct pathspec *pathspec,\n> -\t\t\t\t  struct update_callback_data *data)\n> +\t\t\t\t  struct update_callback_data *data,\n> +\t\t\t\t  const char *ignore_submodules_arg)\n>  {\n>  \tstruct rev_info rev;\n>  \n> @@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n>  \trev.diffopt.format_callback = update_callback;\n>  \trev.diffopt.format_callback_data = data;\n>  \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n> +\n> +\tif (ignore_submodules_arg) {\n> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n> +\t}\n> +\n>  \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n>  }\n>  \n>  int add_files_to_cache(const char *prefix,\n> -\t\t       const struct pathspec *pathspec, int flags)\n> +\t\t       const struct pathspec *pathspec, int flags,\n> +\t\t       const char *ignore_submodules_arg)\n>  {\n>  \tstruct update_callback_data data;\n>  \n>  \tmemset(&data, 0, sizeof(data));\n>  \tdata.flags = flags;\n> -\tupdate_files_in_cache(prefix, pathspec, &data);\n> +\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n>  \treturn !!data.add_errors;\n>  }\n>  \n> @@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\tmemset(&pathspec, 0, sizeof(pathspec));\n>  \t}\n>  \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n> -\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n> +\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n>  \n>  \texit_status |= !!update_data.add_errors;\n>  \tif (add_new_files)\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index ada51fa..22a4b48 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n>  \t\t\t * entries in the index.\n>  \t\t\t */\n>  \n> -\t\t\tadd_files_to_cache(NULL, NULL, 0);\n> +\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n>  \t\t\t/*\n>  \t\t\t * NEEDSWORK: carrying over local changes\n>  \t\t\t * when branches have different end-of-line\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 26b2986..121c185 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> @@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n>  \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n>  \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n> +\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \t\t/* end commit contents options */\n>  \n>  \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n> @@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n>  \t\t\t\t\t  builtin_commit_usage,\n>  \t\t\t\t\t  prefix, current_head, &s);\n> +\n> +\ts.ignore_submodule_arg = ignore_submodule_arg;\n> +\n>  \tif (dry_run)\n>  \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n>  \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\n> diff --git a/cache.h b/cache.h\n> index ebe9a40..5ef8dd6 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n>   * return 0 if success, 1 - if addition of a file failed and\n>   * ADD_FILES_IGNORE_ERRORS was specified in flags\n>   */\n> -int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n> +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n>  \n>  /* diff.c */\n>  extern int diff_auto_refresh_index;\n> \n"},{"id":"238106","messageId":"5338AC36.6000109@gmail.com","threadId":"36308","inReplyTo":"533874F9.3090802@web.de","subject":"[PATCH v2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-30T23:43:50Z","receivedAt":"2014-03-30T23:43:50Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Git commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line, like other commands do.\n\nUseful <when> values for commit are 'all' (default) or 'none'. The others\n('dirty' and 'untracked') have same effect as 'none', as commit is only\ninterested in whether the submodule's HEAD differs from what is commited\nin the superproject.\n\nChanges in add.c and cache.h (and related compilo fix in checkout.c) are\nneeded to make it work for \"commit -a\" too.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nOn 30. 3. 2014 21:48, Jens Lehmann wrote:\n> Looking good so far, but we definitely need tests for this new option.\n\nI added two simple tests (one for --ignore-submodules=all, another one\nfor =none). But I am sure the tests could be written better, by someone\nmore proficient in Git than I am.\n\nThe tests immediately revealed, that the patch was not complete. It\ndidn't work with commit message given on command line (-m). To make\nthat work, I had to also patch the index_differs_from function in\ndiff-lib.c.\n\n> But I wonder if it would make more sense to start by teaching the\n> --ignore-submodules option to git add. Then this patch could reuse\n> that for commit -a.\n\nThat sounds reasonable, however I don't think that any code from my\npatch would be affected, or would it? IOW, would commit really \"reuse\"\nanything? If not (or not much), there is probably no point in\npostponing this patch, support for git add may be added later.\n\n\n Documentation/git-commit.txt        |  6 ++++++\n builtin/add.c                       | 16 +++++++++++----\n builtin/checkout.c                  |  2 +-\n builtin/commit.c                    | 10 ++++++++--\n cache.h                             |  2 +-\n diff-lib.c                          |  7 ++++++-\n diff.h                              |  3 ++-\n sequencer.c                         |  4 ++--\n t/t7513-commit-ignore-submodules.sh | 39 +++++++++++++++++++++++++++++++++++++\n 9 files changed, 77 insertions(+), 12 deletions(-)\n create mode 100644 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 1a7616c..c8839c8 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -271,6 +272,11 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'ignore' option\n+\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 672adc0..1086294 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n \n static void update_files_in_cache(const char *prefix,\n \t\t\t\t  const struct pathspec *pathspec,\n-\t\t\t\t  struct update_callback_data *data)\n+\t\t\t\t  struct update_callback_data *data,\n+\t\t\t\t  const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \n@@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \n \tmemset(&data, 0, sizeof(data));\n \tdata.flags = flags;\n-\tupdate_files_in_cache(prefix, pathspec, &data);\n+\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n \treturn !!data.add_errors;\n }\n \n@@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tmemset(&pathspec, 0, sizeof(pathspec));\n \t}\n \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n-\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n+\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n \n \texit_status |= !!update_data.add_errors;\n \tif (add_new_files)\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ada51fa..22a4b48 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 26b2986..b3fb28e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -827,7 +827,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\tif (get_sha1(parent, sha1))\n \t\t\tcommitable = !!active_nr;\n \t\telse\n-\t\t\tcommitable = index_differs_from(parent, 0);\n+\t\t\tcommitable = index_differs_from(parent, 0, ignore_submodule_arg);\n \t}\n \tstrbuf_release(&committer_ident);\n \n@@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/cache.h b/cache.h\nindex ebe9a40..5ef8dd6 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 2eddc66..fec5ad4 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -508,7 +508,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n \treturn 0;\n }\n \n-int index_differs_from(const char *def, int diff_flags)\n+int index_differs_from(const char *def, int diff_flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \tstruct setup_revision_opt opt;\n@@ -520,6 +521,10 @@ int index_differs_from(const char *def, int diff_flags)\n \tDIFF_OPT_SET(&rev.diffopt, QUICK);\n \tDIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);\n \trev.diffopt.flags |= diff_flags;\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n \trun_diff_index(&rev, 1);\n \tif (rev.pending.alloc)\n \t\tfree(rev.pending.objects);\ndiff --git a/diff.h b/diff.h\nindex ce123fa..0ac869b 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -334,7 +334,8 @@ extern int diff_result_code(struct diff_options *, int);\n \n extern void diff_no_index(struct rev_info *, int, const char **, const char *);\n \n-extern int index_differs_from(const char *def, int diff_flags);\n+extern int index_differs_from(const char *def, int diff_flags,\n+\t\t\t      const char *ignore_submodules_arg);\n \n extern size_t fill_textconv(struct userdiff_driver *driver,\n \t\t\t    struct diff_filespec *df,\ndiff --git a/sequencer.c b/sequencer.c\nindex 90cac7b..de9edec 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -496,7 +496,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t\tunborn = get_sha1(\"HEAD\", head);\n \t\tif (unborn)\n \t\t\thashcpy(head, EMPTY_TREE_SHA1_BIN);\n-\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0))\n+\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0, NULL))\n \t\t\treturn error_dirty_index(opts);\n \t}\n \tdiscard_cache();\n@@ -1042,7 +1042,7 @@ static int sequencer_continue(struct replay_opts *opts)\n \t\tif (ret)\n \t\t\treturn ret;\n \t}\n-\tif (index_differs_from(\"HEAD\", 0))\n+\tif (index_differs_from(\"HEAD\", 0, NULL))\n \t\treturn error_dirty_index(opts);\n \ttodo_list = todo_list->next;\n \treturn pick_commits(todo_list, opts);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..a3a68ce\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,39 @@\n+#!/bin/sh\n+\n+test_description='git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(cd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a -m \"Update sm\" &&\n+\tgit diff-index --exit-code --cached --ignore-submodules=none HEAD &&\n+\tgit diff-files --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.0\n \n"},{"id":"238107","messageId":"5338B1B0.3050703@gmail.com","threadId":"36308","inReplyTo":"5338AC36.6000109@gmail.com","subject":"[PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-31T00:07:12Z","receivedAt":"2014-03-31T00:07:12Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Git commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line, like other commands do.\n\nUseful <when> values for commit are 'all' (default) or 'none'. The others\n('dirty' and 'untracked') have same effect as 'none', as commit is only\ninterested in whether the submodule's HEAD differs from what is commited\nin the superproject.\n\nChanges in add.c and cache.h (and related compilo fix in checkout.c) are\nneeded to make it work for \"commit -a\" too.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nThe previous patch version (v2) contained bug in the test, by mistake I\nhave sent older version than I was testing with, sorry for that.\n\nOn 30. 3. 2014 21:48, Jens Lehmann wrote:\n> Looking good so far, but we definitely need tests for this new option.\n\nI added two simple tests (one for --ignore-submodules=all, another one\nfor =none). But I am sure the tests could be written better, by someone\nmore proficient in Git than I am.\n\nThe tests immediately revealed, that the patch was not complete. It\ndidn't work with commit message given on command line (-m). To make\nthat work, I had to also patch the index_differs_from function in\ndiff-lib.c.\n\n> But I wonder if it would make more sense to start by teaching the\n> --ignore-submodules option to git add. Then this patch could reuse\n> that for commit -a.\n\nThat sounds reasonable, however I don't think that any code from my\npatch would be affected, or would it? IOW, would commit really \"reuse\"\nanything? If not (or not much), there is probably no point in\npostponing this patch, support for git add may be added later.\n\n\n Documentation/git-commit.txt        |  6 ++++++\n builtin/add.c                       | 16 +++++++++++----\n builtin/checkout.c                  |  2 +-\n builtin/commit.c                    | 10 ++++++++--\n cache.h                             |  2 +-\n diff-lib.c                          |  7 ++++++-\n diff.h                              |  3 ++-\n sequencer.c                         |  4 ++--\n t/t7513-commit-ignore-submodules.sh | 39 +++++++++++++++++++++++++++++++++++++\n 9 files changed, 77 insertions(+), 12 deletions(-)\n create mode 100644 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 1a7616c..c8839c8 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -271,6 +272,11 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'ignore' option\n+\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 672adc0..1086294 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n \n static void update_files_in_cache(const char *prefix,\n \t\t\t\t  const struct pathspec *pathspec,\n-\t\t\t\t  struct update_callback_data *data)\n+\t\t\t\t  struct update_callback_data *data,\n+\t\t\t\t  const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \n@@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \n \tmemset(&data, 0, sizeof(data));\n \tdata.flags = flags;\n-\tupdate_files_in_cache(prefix, pathspec, &data);\n+\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n \treturn !!data.add_errors;\n }\n \n@@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tmemset(&pathspec, 0, sizeof(pathspec));\n \t}\n \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n-\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n+\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n \n \texit_status |= !!update_data.add_errors;\n \tif (add_new_files)\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ada51fa..22a4b48 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 26b2986..b3fb28e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -827,7 +827,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n \t\tif (get_sha1(parent, sha1))\n \t\t\tcommitable = !!active_nr;\n \t\telse\n-\t\t\tcommitable = index_differs_from(parent, 0);\n+\t\t\tcommitable = index_differs_from(parent, 0, ignore_submodule_arg);\n \t}\n \tstrbuf_release(&committer_ident);\n \n@@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/cache.h b/cache.h\nindex ebe9a40..5ef8dd6 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 2eddc66..fec5ad4 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -508,7 +508,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n \treturn 0;\n }\n \n-int index_differs_from(const char *def, int diff_flags)\n+int index_differs_from(const char *def, int diff_flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \tstruct setup_revision_opt opt;\n@@ -520,6 +521,10 @@ int index_differs_from(const char *def, int diff_flags)\n \tDIFF_OPT_SET(&rev.diffopt, QUICK);\n \tDIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);\n \trev.diffopt.flags |= diff_flags;\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n \trun_diff_index(&rev, 1);\n \tif (rev.pending.alloc)\n \t\tfree(rev.pending.objects);\ndiff --git a/diff.h b/diff.h\nindex ce123fa..0ac869b 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -334,7 +334,8 @@ extern int diff_result_code(struct diff_options *, int);\n \n extern void diff_no_index(struct rev_info *, int, const char **, const char *);\n \n-extern int index_differs_from(const char *def, int diff_flags);\n+extern int index_differs_from(const char *def, int diff_flags,\n+\t\t\t      const char *ignore_submodules_arg);\n \n extern size_t fill_textconv(struct userdiff_driver *driver,\n \t\t\t    struct diff_filespec *df,\ndiff --git a/sequencer.c b/sequencer.c\nindex 90cac7b..de9edec 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -496,7 +496,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t\tunborn = get_sha1(\"HEAD\", head);\n \t\tif (unborn)\n \t\t\thashcpy(head, EMPTY_TREE_SHA1_BIN);\n-\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0))\n+\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0, NULL))\n \t\t\treturn error_dirty_index(opts);\n \t}\n \tdiscard_cache();\n@@ -1042,7 +1042,7 @@ static int sequencer_continue(struct replay_opts *opts)\n \t\tif (ret)\n \t\t\treturn ret;\n \t}\n-\tif (index_differs_from(\"HEAD\", 0))\n+\tif (index_differs_from(\"HEAD\", 0, NULL))\n \t\treturn error_dirty_index(opts);\n \ttodo_list = todo_list->next;\n \treturn pick_commits(todo_list, opts);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..a7148ce\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,39 @@\n+#!/bin/sh\n+\n+test_description='git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(cd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n+\tgit diff-index --exit-code --cached --ignore-submodules=none HEAD &&\n+\tgit diff-files --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.0\n \n"},{"id":"238112","messageId":"xmqqd2h28f3z.fsf@gitster.dls.corp.google.com","threadId":"36308","inReplyTo":"533874F9.3090802@web.de","subject":"Re: [PATCH 1/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-03-31T17:14:40Z","receivedAt":"2014-03-31T17:14:40Z","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>> Changes in add.c and cache.h (and related compilo fix in checkout.c) are\n>> needed to make it work for \"commit -a\" too.\n>\n> Looking good so far, but we definitely need tests for this new option.\n>\n> But I wonder if it would make more sense to start by teaching the\n> --ignore-submodules option to git add. Then this patch could reuse\n> that for commit -a.\n\nI am not sure about the code reuse, but from the usability and\nconsistency point of view, they must go hand in hand, I would\nthink.\n"},{"id":"238127","messageId":"5339BAE4.8020306@web.de","threadId":"36308","inReplyTo":"5338B1B0.3050703@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-31T18:58:44Z","receivedAt":"2014-03-31T18:58:44Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 31.03.2014 02:07, schrieb Ronald Weiss:\n> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n> but didn't allow to override it from command line, like other commands do.\n> \n> Useful <when> values for commit are 'all' (default) or 'none'. The others\n> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n> interested in whether the submodule's HEAD differs from what is commited\n> in the superproject.\n> \n> Changes in add.c and cache.h (and related compilo fix in checkout.c) are\n> needed to make it work for \"commit -a\" too.\n> \n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n> The previous patch version (v2) contained bug in the test, by mistake I\n> have sent older version than I was testing with, sorry for that.\n> \n> On 30. 3. 2014 21:48, Jens Lehmann wrote:\n>> Looking good so far, but we definitely need tests for this new option.\n> \n> I added two simple tests (one for --ignore-submodules=all, another one\n> for =none). But I am sure the tests could be written better, by someone\n> more proficient in Git than I am.\n> \n> The tests immediately revealed, that the patch was not complete. It\n> didn't work with commit message given on command line (-m). To make\n> that work, I had to also patch the index_differs_from function in\n> diff-lib.c.\n\nWhich is exactly the same function I have to tweak to make my\n\"status/commit: always show staged submodules regardless of\nignore config\" patch work for \"git commit -m\" too ;-)\n\nI was doing that slightly differently but it seems that your way\nof adding the \"ignore_submodules_arg\" parameter could serve us\nboth. Will update my upcoming patch accordingly.\n\n>> But I wonder if it would make more sense to start by teaching the\n>> --ignore-submodules option to git add. Then this patch could reuse\n>> that for commit -a.\n> \n> That sounds reasonable, however I don't think that any code from my\n> patch would be affected, or would it? IOW, would commit really \"reuse\"\n> anything? If not (or not much), there is probably no point in\n> postponing this patch, support for git add may be added later.\n\nYou might be right as I didn't really check the actual codepaths. I\nwas deducing this from the observation that most changes were made\nto builtin/add.c. And seeing a function like add_files_to_cache()\nbeing modified made me expect that plain add would use the same\nfunction to stage the files.\n\nAs Junio mentioned it would be great if you could teach the add\ncommand also honor the --ignore-submodule command line option in\na companion patch. In the course of doing so you'll easily see if\nI was right or not, then please just order them in the most logical\nway.\n\nThanks for digging into this!\n\n>  Documentation/git-commit.txt        |  6 ++++++\n>  builtin/add.c                       | 16 +++++++++++----\n>  builtin/checkout.c                  |  2 +-\n>  builtin/commit.c                    | 10 ++++++++--\n>  cache.h                             |  2 +-\n>  diff-lib.c                          |  7 ++++++-\n>  diff.h                              |  3 ++-\n>  sequencer.c                         |  4 ++--\n>  t/t7513-commit-ignore-submodules.sh | 39 +++++++++++++++++++++++++++++++++++++\n>  9 files changed, 77 insertions(+), 12 deletions(-)\n>  create mode 100644 t/t7513-commit-ignore-submodules.sh\n> \n> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\n> index 1a7616c..c8839c8 100644\n> --- a/Documentation/git-commit.txt\n> +++ b/Documentation/git-commit.txt\n> @@ -13,6 +13,7 @@ SYNOPSIS\n>  \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n>  \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n>  \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n> +\t   [--ignore-submodules[=<when>]]\n>  \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n>  \n>  DESCRIPTION\n> @@ -271,6 +272,11 @@ The possible options are:\n>  The default can be changed using the status.showUntrackedFiles\n>  configuration variable documented in linkgit:git-config[1].\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'ignore' option\n> +\tin linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\" or \"all\", which is the default.\n> +\n>  -v::\n>  --verbose::\n>  \tShow unified diff between the HEAD commit and what\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 672adc0..1086294 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n>  \n>  static void update_files_in_cache(const char *prefix,\n>  \t\t\t\t  const struct pathspec *pathspec,\n> -\t\t\t\t  struct update_callback_data *data)\n> +\t\t\t\t  struct update_callback_data *data,\n> +\t\t\t\t  const char *ignore_submodules_arg)\n>  {\n>  \tstruct rev_info rev;\n>  \n> @@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n>  \trev.diffopt.format_callback = update_callback;\n>  \trev.diffopt.format_callback_data = data;\n>  \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n> +\n> +\tif (ignore_submodules_arg) {\n> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n> +\t}\n> +\n>  \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n>  }\n>  \n>  int add_files_to_cache(const char *prefix,\n> -\t\t       const struct pathspec *pathspec, int flags)\n> +\t\t       const struct pathspec *pathspec, int flags,\n> +\t\t       const char *ignore_submodules_arg)\n>  {\n>  \tstruct update_callback_data data;\n>  \n>  \tmemset(&data, 0, sizeof(data));\n>  \tdata.flags = flags;\n> -\tupdate_files_in_cache(prefix, pathspec, &data);\n> +\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n>  \treturn !!data.add_errors;\n>  }\n>  \n> @@ -576,7 +584,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\tmemset(&pathspec, 0, sizeof(pathspec));\n>  \t}\n>  \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n> -\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n> +\tupdate_files_in_cache(prefix, &pathspec, &update_data, NULL);\n>  \n>  \texit_status |= !!update_data.add_errors;\n>  \tif (add_new_files)\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index ada51fa..22a4b48 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n>  \t\t\t * entries in the index.\n>  \t\t\t */\n>  \n> -\t\t\tadd_files_to_cache(NULL, NULL, 0);\n> +\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n>  \t\t\t/*\n>  \t\t\t * NEEDSWORK: carrying over local changes\n>  \t\t\t * when branches have different end-of-line\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 26b2986..b3fb28e 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> @@ -827,7 +827,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,\n>  \t\tif (get_sha1(parent, sha1))\n>  \t\t\tcommitable = !!active_nr;\n>  \t\telse\n> -\t\t\tcommitable = index_differs_from(parent, 0);\n> +\t\t\tcommitable = index_differs_from(parent, 0, ignore_submodule_arg);\n>  \t}\n>  \tstrbuf_release(&committer_ident);\n>  \n> @@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n>  \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n>  \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n> +\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \t\t/* end commit contents options */\n>  \n>  \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n> @@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n>  \t\t\t\t\t  builtin_commit_usage,\n>  \t\t\t\t\t  prefix, current_head, &s);\n> +\n> +\ts.ignore_submodule_arg = ignore_submodule_arg;\n> +\n>  \tif (dry_run)\n>  \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n>  \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\n> diff --git a/cache.h b/cache.h\n> index ebe9a40..5ef8dd6 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n>   * return 0 if success, 1 - if addition of a file failed and\n>   * ADD_FILES_IGNORE_ERRORS was specified in flags\n>   */\n> -int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n> +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n>  \n>  /* diff.c */\n>  extern int diff_auto_refresh_index;\n> diff --git a/diff-lib.c b/diff-lib.c\n> index 2eddc66..fec5ad4 100644\n> --- a/diff-lib.c\n> +++ b/diff-lib.c\n> @@ -508,7 +508,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n>  \treturn 0;\n>  }\n>  \n> -int index_differs_from(const char *def, int diff_flags)\n> +int index_differs_from(const char *def, int diff_flags,\n> +\t\t       const char *ignore_submodules_arg)\n>  {\n>  \tstruct rev_info rev;\n>  \tstruct setup_revision_opt opt;\n> @@ -520,6 +521,10 @@ int index_differs_from(const char *def, int diff_flags)\n>  \tDIFF_OPT_SET(&rev.diffopt, QUICK);\n>  \tDIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);\n>  \trev.diffopt.flags |= diff_flags;\n> +\tif (ignore_submodules_arg) {\n> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n> +\t}\n>  \trun_diff_index(&rev, 1);\n>  \tif (rev.pending.alloc)\n>  \t\tfree(rev.pending.objects);\n> diff --git a/diff.h b/diff.h\n> index ce123fa..0ac869b 100644\n> --- a/diff.h\n> +++ b/diff.h\n> @@ -334,7 +334,8 @@ extern int diff_result_code(struct diff_options *, int);\n>  \n>  extern void diff_no_index(struct rev_info *, int, const char **, const char *);\n>  \n> -extern int index_differs_from(const char *def, int diff_flags);\n> +extern int index_differs_from(const char *def, int diff_flags,\n> +\t\t\t      const char *ignore_submodules_arg);\n>  \n>  extern size_t fill_textconv(struct userdiff_driver *driver,\n>  \t\t\t    struct diff_filespec *df,\n> diff --git a/sequencer.c b/sequencer.c\n> index 90cac7b..de9edec 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -496,7 +496,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n>  \t\tunborn = get_sha1(\"HEAD\", head);\n>  \t\tif (unborn)\n>  \t\t\thashcpy(head, EMPTY_TREE_SHA1_BIN);\n> -\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0))\n> +\t\tif (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : \"HEAD\", 0, NULL))\n>  \t\t\treturn error_dirty_index(opts);\n>  \t}\n>  \tdiscard_cache();\n> @@ -1042,7 +1042,7 @@ static int sequencer_continue(struct replay_opts *opts)\n>  \t\tif (ret)\n>  \t\t\treturn ret;\n>  \t}\n> -\tif (index_differs_from(\"HEAD\", 0))\n> +\tif (index_differs_from(\"HEAD\", 0, NULL))\n>  \t\treturn error_dirty_index(opts);\n>  \ttodo_list = todo_list->next;\n>  \treturn pick_commits(todo_list, opts);\n> diff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\n> new file mode 100644\n> index 0000000..a7148ce\n> --- /dev/null\n> +++ b/t/t7513-commit-ignore-submodules.sh\n> @@ -0,0 +1,39 @@\n> +#!/bin/sh\n> +\n> +test_description='git commit --ignore-submodules'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'create submodule' '\n> +\ttest_create_repo sm && (\n> +\t\tcd sm &&\n> +\t\t>foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Add foo\"\n> +\t) &&\n> +\tgit submodule add ./sm &&\n> +\tgit commit -m \"Add sm\"\n> +'\n> +\n> +update_sm () {\n> +\t(cd sm &&\n> +\t\techo bar >> foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Updated foo\"\n> +\t)\n> +}\n> +\n> +test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n> +\tupdate_sm &&\n> +\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n> +'\n> +\n> +test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n> +\tupdate_sm &&\n> +\tgit config submodule.sm.ignore all &&\n> +\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n> +\tgit diff-index --exit-code --cached --ignore-submodules=none HEAD &&\n> +\tgit diff-files --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_done\n> \n"},{"id":"238140","messageId":"5339D213.4070303@web.de","threadId":"36308","inReplyTo":"5339BAE4.8020306@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-03-31T20:37:39Z","receivedAt":"2014-03-31T20:37:39Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 31.03.2014 20:58, schrieb Jens Lehmann:\n> Am 31.03.2014 02:07, schrieb Ronald Weiss:\n>> The tests immediately revealed, that the patch was not complete. It\n>> didn't work with commit message given on command line (-m). To make\n>> that work, I had to also patch the index_differs_from function in\n>> diff-lib.c.\n> \n> Which is exactly the same function I have to tweak to make my\n> \"status/commit: always show staged submodules regardless of\n> ignore config\" patch work for \"git commit -m\" too ;-)\n> \n> I was doing that slightly differently but it seems that your way\n> of adding the \"ignore_submodules_arg\" parameter could serve us\n> both. Will update my upcoming patch accordingly.\n\nI've been hacking on that some more (I'll post it as soon as I\nhave all new tests up and running) and think we might be able to\nhandle that even easier. Please see below:\n\n>> diff --git a/diff-lib.c b/diff-lib.c\n>> index 2eddc66..fec5ad4 100644\n>> --- a/diff-lib.c\n>> +++ b/diff-lib.c\n>> @@ -508,7 +508,8 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)\n>>  \treturn 0;\n>>  }\n>>  \n>> -int index_differs_from(const char *def, int diff_flags)\n>> +int index_differs_from(const char *def, int diff_flags,\n>> +\t\t       const char *ignore_submodules_arg)\n>>  {\n>>  \tstruct rev_info rev;\n>>  \tstruct setup_revision_opt opt;\n>> @@ -520,6 +521,10 @@ int index_differs_from(const char *def, int diff_flags)\n>>  \tDIFF_OPT_SET(&rev.diffopt, QUICK);\n>>  \tDIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS);\n>>  \trev.diffopt.flags |= diff_flags;\n>> +\tif (ignore_submodules_arg) {\n>> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n\nYou'll have to do this unconditionally, as this option tells the\ndiff machinery to ignore any submodule configurations, which is\nwhat we want in either case. But ...\n\n>> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n>> +\t}\n>>  \trun_diff_index(&rev, 1);\n>>  \tif (rev.pending.alloc)\n>>  \t\tfree(rev.pending.objects);\n\n... maybe the best way is to leave index_differs_from() unchanged\nand call that function with the correct diff_flags instead:\n\n+\t\tint diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;\n+\t\tif (ignore_submodule_arg &&\n+\t\t    !strcmp(ignore_submodule_arg, \"all\"))\n+\t\t\tdiff_flags |= DIFF_OPT_IGNORE_SUBMODULES;\n+\t\tcommitable = index_differs_from(parent, diff_flags);\n\nNot thoroughly tested yet, but that'd also prevent any fallout for\nthe two callsites of index_differs_from() in sequencer.c.\n"},{"id":"238156","messageId":"CABxC_L8_tQrANXji_Z0LfigxsAuzSDj3K9ndTGOTHh2ctHvc6A@mail.gmail.com","threadId":"36308","inReplyTo":"5339BAE4.8020306@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-31T21:47:14Z","receivedAt":"2014-03-31T21:47:14Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n> As Junio mentioned it would be great if you could teach the add\n> command also honor the --ignore-submodule command line option in\n> a companion patch. In the course of doing so you'll easily see if\n> I was right or not, then please just order them in the most logical\n> way.\n\nWell, if You (or Junio) really don't want my patch without another one\nfor git add, I may try to do it. However, git add does not even honor\nthe submodules' ignore setting from .gitmodules (just tested with git\n1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\nteaching git add the --ignore-submodules switch in current state\ndoesn't seem right to me. You might propose to add also support for\nthe ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\nThat seems like a good idea, but the effort needed is getting bigger,\nand nobody actually complains about lack of submodule ignoring\nfacility in git add, while I know that the current behavior of commit\nreally causes trouble.\n"},{"id":"238162","messageId":"CABxC_L88+eaQJUog0Bhj3EVE0A0NN=hh0heWogjuv2jve7Gx=A@mail.gmail.com","threadId":"36308","inReplyTo":"5339D213.4070303@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-31T21:50:17Z","receivedAt":"2014-03-31T21:50:17Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On Mon, Mar 31, 2014 at 10:37 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n> ... maybe the best way is to leave index_differs_from() unchanged\n> and call that function with the correct diff_flags instead:\n>\n> +               int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG;\n> +               if (ignore_submodule_arg &&\n> +                   !strcmp(ignore_submodule_arg, \"all\"))\n> +                       diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;\n> +               commitable = index_differs_from(parent, diff_flags);\n>\n> Not thoroughly tested yet, but that'd also prevent any fallout for\n> the two callsites of index_differs_from() in sequencer.c.\n\nThanks for this hint, that is really much nicer. I'll test that, and\npost updated patch if it works.\n"},{"id":"238181","messageId":"5339F122.60801@gmail.com","threadId":"36308","inReplyTo":"CABxC_L8_tQrANXji_Z0LfigxsAuzSDj3K9ndTGOTHh2ctHvc6A@mail.gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-31T22:50:10Z","receivedAt":"2014-03-31T22:50:10Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 31. 3. 2014 23:47, Ronald Weiss wrote:\n> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>> As Junio mentioned it would be great if you could teach the add\n>> command also honor the --ignore-submodule command line option in\n>> a companion patch. In the course of doing so you'll easily see if\n>> I was right or not, then please just order them in the most logical\n>> way.\n> \n> Well, if You (or Junio) really don't want my patch without another one\n> for git add, I may try to do it. However, git add does not even honor\n> the submodules' ignore setting from .gitmodules (just tested with git\n> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n> teaching git add the --ignore-submodules switch in current state\n> doesn't seem right to me. You might propose to add also support for\n> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n> That seems like a good idea, but the effort needed is getting bigger,\n\nWell, now I actually looked at it, and it was pretty easy after all.\nThe changes below seem to enable support for both ignore setting in\n.gitmodules, and also --ignore-submodules switch, for git add, on top\nof my patch for commit.\n\nSo I'm going to do some more testing, write tests for git add with\nignoring submodules the various ways, and then post two patches\nrearranged, one for git add, and second for git commit on top of that,\nas you guys suggested. Including the change suggested by Jens, to not\nmess with index_differs_from() in diff-lib.c, that works fine too.\n\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 1086294..9f70327 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -350,6 +350,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n static int addremove = ADDREMOVE_DEFAULT;\n static int addremove_explicit = -1; /* unspecified */\n\n+static char *ignore_submodule_arg;\n+\n static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n {\n        /* if we are told to ignore, we are not adding removals */\n@@ -375,6 +377,9 @@ static struct option builtin_add_options[] = {\n        OPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n        OPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n        OPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n+       { OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+         N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+         PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n        OPT_END(),\n };\n\n@@ -422,6 +427,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n        int implicit_dot = 0;\n        struct update_callback_data update_data;\n\n+       gitmodules_config();\n        git_config(add_config, NULL);\n\n        argc = parse_options(argc, argv, prefix, builtin_add_options,\n@@ -584,7 +590,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n                memset(&pathspec, 0, sizeof(pathspec));\n        }\n        update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n-       update_files_in_cache(prefix, &pathspec, &update_data, NULL);\n+       update_files_in_cache(prefix, &pathspec, &update_data, ignore_submodule_arg);\n\n        exit_status |= !!update_data.add_errors;\n        if (add_new_files)\n"},{"id":"238184","messageId":"5339FBB4.1010101@gmail.com","threadId":"36308","inReplyTo":"5339F122.60801@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-03-31T23:35:16Z","receivedAt":"2014-03-31T23:35:16Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 1. 4. 2014 0:50, Ronald Weiss wrote:\n> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>> As Junio mentioned it would be great if you could teach the add\n>>> command also honor the --ignore-submodule command line option in\n>>> a companion patch. In the course of doing so you'll easily see if\n>>> I was right or not, then please just order them in the most logical\n>>> way.\n>>\n>> Well, if You (or Junio) really don't want my patch without another one\n>> for git add, I may try to do it. However, git add does not even honor\n>> the submodules' ignore setting from .gitmodules (just tested with git\n>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>> teaching git add the --ignore-submodules switch in current state\n>> doesn't seem right to me. You might propose to add also support for\n>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>> That seems like a good idea, but the effort needed is getting bigger,\n>\n> Well, now I actually looked at it, and it was pretty easy after all.\n> The changes below seem to enable support for both ignore setting in\n> .gitmodules, and also --ignore-submodules switch, for git add, on top\n> of my patch for commit.\n\nThere is a catch. With the changes below, submodules are ignored by add \neven if explitely named on command line (eg. \"git add x\" does nothing if \nx is submodule with new commits, but with ignore=all in .gitmodules).\nThat doesn't seem right.\n\nAny ideas, what to do about that? When exactly should such submodule be \nactually ignored?\n\n>\n> So I'm going to do some more testing, write tests for git add with\n> ignoring submodules the various ways, and then post two patches\n> rearranged, one for git add, and second for git commit on top of that,\n> as you guys suggested. Including the change suggested by Jens, to not\n> mess with index_differs_from() in diff-lib.c, that works fine too.\n>\n>\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 1086294..9f70327 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -350,6 +350,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n>   static int addremove = ADDREMOVE_DEFAULT;\n>   static int addremove_explicit = -1; /* unspecified */\n>\n> +static char *ignore_submodule_arg;\n> +\n>   static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n>   {\n>          /* if we are told to ignore, we are not adding removals */\n> @@ -375,6 +377,9 @@ static struct option builtin_add_options[] = {\n>          OPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n>          OPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n>          OPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n> +       { OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +         N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +         PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>          OPT_END(),\n>   };\n>\n> @@ -422,6 +427,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>          int implicit_dot = 0;\n>          struct update_callback_data update_data;\n>\n> +       gitmodules_config();\n>          git_config(add_config, NULL);\n>\n>          argc = parse_options(argc, argv, prefix, builtin_add_options,\n> @@ -584,7 +590,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>                  memset(&pathspec, 0, sizeof(pathspec));\n>          }\n>          update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n> -       update_files_in_cache(prefix, &pathspec, &update_data, NULL);\n> +       update_files_in_cache(prefix, &pathspec, &update_data, ignore_submodule_arg);\n>\n>          exit_status |= !!update_data.add_errors;\n>          if (add_new_files)\n>\n"},{"id":"238269","messageId":"533B2036.3050506@web.de","threadId":"36308","inReplyTo":"5339FBB4.1010101@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-01T20:23:18Z","receivedAt":"2014-04-01T20:23:18Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 01.04.2014 01:35, schrieb Ronald Weiss:\n> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>> As Junio mentioned it would be great if you could teach the add\n>>>> command also honor the --ignore-submodule command line option in\n>>>> a companion patch. In the course of doing so you'll easily see if\n>>>> I was right or not, then please just order them in the most logical\n>>>> way.\n>>>\n>>> Well, if You (or Junio) really don't want my patch without another one\n>>> for git add, I may try to do it. However, git add does not even honor\n>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>> teaching git add the --ignore-submodules switch in current state\n>>> doesn't seem right to me. You might propose to add also support for\n>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>> That seems like a good idea, but the effort needed is getting bigger,\n>>\n>> Well, now I actually looked at it, and it was pretty easy after all.\n>> The changes below seem to enable support for both ignore setting in\n>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>> of my patch for commit.\n> \n> There is a catch. With the changes below, submodules are ignored by add even if explitely named on command line (eg. \"git add x\" does nothing if x is submodule with new commits, but with ignore=all in .gitmodules).\n> That doesn't seem right.\n> \n> Any ideas, what to do about that? When exactly should such submodule be actually ignored?\n\nMe thinks git add should require the '-f' option to add an ignored\nsubmodule (just like it does for files) unless the user uses the\n'--ignore-submodules=none' option. And if neither of these are given\nit should \"fail with a list of ignored files\" as the documentation\nstates.\n"},{"id":"238276","messageId":"533B36AA.3090600@gmail.com","threadId":"36308","inReplyTo":"533B2036.3050506@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-01T21:59:06Z","receivedAt":"2014-04-01T21:59:06Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 1. 4. 2014 22:23, Jens Lehmann wrote:\n> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>> command also honor the --ignore-submodule command line option in\n>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>> I was right or not, then please just order them in the most logical\n>>>>> way.\n>>>>\n>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>> for git add, I may try to do it. However, git add does not even honor\n>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>> teaching git add the --ignore-submodules switch in current state\n>>>> doesn't seem right to me. You might propose to add also support for\n>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>\n>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>> The changes below seem to enable support for both ignore setting in\n>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>> of my patch for commit.\n>>\n>> There is a catch. With the changes below, submodules are ignored by add even if explitely named on command line (eg. \"git add x\" does nothing if x is submodule with new commits, but with ignore=all in .gitmodules).\n>> That doesn't seem right.\n>>\n>> Any ideas, what to do about that? When exactly should such submodule be actually ignored?\n> \n> Me thinks git add should require the '-f' option to add an ignored\n> submodule (just like it does for files) unless the user uses the\n> '--ignore-submodules=none' option. And if neither of these are given\n> it should \"fail with a list of ignored files\" as the documentation\n> states.\n\nIt's still not clear, at least not to me. Should '-f' suppress the\nignore setting of all involved submodules? That would make it a\nsynonyme (or a superset) of --ignore-submodules=none. Or only if the\nsubmodule is explicitly named on command line? That seems fuzzy to me,\nand also more tricky to implement.\n"},{"id":"238338","messageId":"533C5CBD.4050601@web.de","threadId":"36308","inReplyTo":"533B36AA.3090600@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-02T18:53:49Z","receivedAt":"2014-04-02T18:53:49Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 01.04.2014 23:59, schrieb Ronald Weiss:\n> On 1. 4. 2014 22:23, Jens Lehmann wrote:\n>> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>>> command also honor the --ignore-submodule command line option in\n>>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>>> I was right or not, then please just order them in the most logical\n>>>>>> way.\n>>>>>\n>>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>>> for git add, I may try to do it. However, git add does not even honor\n>>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>>> teaching git add the --ignore-submodules switch in current state\n>>>>> doesn't seem right to me. You might propose to add also support for\n>>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>>\n>>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>>> The changes below seem to enable support for both ignore setting in\n>>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>>> of my patch for commit.\n>>>\n>>> There is a catch. With the changes below, submodules are ignored by add even if explitely named on command line (eg. \"git add x\" does nothing if x is submodule with new commits, but with ignore=all in .gitmodules).\n>>> That doesn't seem right.\n>>>\n>>> Any ideas, what to do about that? When exactly should such submodule be actually ignored?\n>>\n>> Me thinks git add should require the '-f' option to add an ignored\n>> submodule (just like it does for files) unless the user uses the\n>> '--ignore-submodules=none' option. And if neither of these are given\n>> it should \"fail with a list of ignored files\" as the documentation\n>> states.\n> \n> It's still not clear, at least not to me. Should '-f' suppress the\n> ignore setting of all involved submodules? That would make it a\n> synonyme (or a superset) of --ignore-submodules=none. Or only if the\n> submodule is explicitly named on command line? That seems fuzzy to me,\n> and also more tricky to implement.\n\nMaybe my impression that doing \"add\" together with \"commit\" would be\neasy wasn't correct after all. I won't object if you try to tackle\ncommit first (but I have the slight suspicion that similar questions\nwill arise concerning the \"add\"ish functionality in commit too. So\nmaybe after resolving those things might look clearer ;-)\n"},{"id":"238291","messageId":"533C6B57.3080901@gmail.com","threadId":"36308","inReplyTo":"533C5CBD.4050601@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-02T19:56:07Z","receivedAt":"2014-04-02T19:56:07Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 2. 4. 2014 20:53, Jens Lehmann wrote:\n> Am 01.04.2014 23:59, schrieb Ronald Weiss:\n>> On 1. 4. 2014 22:23, Jens Lehmann wrote:\n>>> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>>>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>>>> command also honor the --ignore-submodule command line option in\n>>>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>>>> I was right or not, then please just order them in the most logical\n>>>>>>> way.\n>>>>>>\n>>>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>>>> for git add, I may try to do it. However, git add does not even honor\n>>>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>>>> teaching git add the --ignore-submodules switch in current state\n>>>>>> doesn't seem right to me. You might propose to add also support for\n>>>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>>>\n>>>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>>>> The changes below seem to enable support for both ignore setting in\n>>>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>>>> of my patch for commit.\n>>>>\n>>>> There is a catch. With the changes below, submodules are ignored by add\n>>>> even if explitely named on command line (eg. \"git add x\" does nothing\n>>>> if x is submodule with new commits, but with ignore=all in .gitmodules).\n>>>> That doesn't seem right.\n>>>>\n>>>> Any ideas, what to do about that? When exactly should such submodule be\n>>>> actually ignored?\n>>>\n>>> Me thinks git add should require the '-f' option to add an ignored\n>>> submodule (just like it does for files) unless the user uses the\n>>> '--ignore-submodules=none' option. And if neither of these are given\n>>> it should \"fail with a list of ignored files\" as the documentation\n>>> states.\n>>\n>> It's still not clear, at least not to me. Should '-f' suppress the\n>> ignore setting of all involved submodules? That would make it a\n>> synonyme (or a superset) of --ignore-submodules=none. Or only if the\n>> submodule is explicitly named on command line? That seems fuzzy to me,\n>> and also more tricky to implement.\n> \n> Maybe my impression that doing \"add\" together with \"commit\" would be\n> easy wasn't correct after all. I won't object if you try to tackle\n> commit first (but I have the slight suspicion that similar questions\n> will arise concerning the \"add\"ish functionality in commit too. So\n> maybe after resolving those things might look clearer ;-)\n\nThere is one big distinction. My patch for commit doesn't add any new\nproblems. It just adds the --ignore-submodules argument, which is easy\nto implement and no unclear behavior decisions are needed.\n\nYou are right that when specifying ignored submodules on commit's\ncommand line, there is the same problem as with git add. However, it's\nalready there anyway. I don't feel in position to solve it, I'd just\nlike to have \"git commit --ignore-submodules=none\".\n\nWith git add however, changing it to honor settings from .gitmodules\nwould change behavior people might be used to, so I would be afraid to\ndo that. Btw add also has the problem already, but only if somebody\nconfigures the submodule's ignore setting in .git/config, rather than\n.gitmodules. I don't know how much real use case that is.\n\nAs I see it, there are now these rather easy possibilities (sorted\nfrom the easiest):\n\n1) Just teach commit the --ignore-submodules argument, as I proposed.\n\n2) Teach both add and commit to --ignore-submodules, but dont add that\nproblematic gitmodules_config() in add.c.\n\n3) Teach both add and commit to --ignore-submodules, and also let add\nhonor settings from .gitmodules, to make it more consistent with other\ncommands. And, make add --force imply --ignore-submodules=none.\n\nI like both 1) and 2). I don't like 3), the problem of add with\nsubmodules' ignore setting is a bug IMHO (ignore=all in .git/config\ncauses strange behavior, while ignore=all in .gitmodules is ignored),\nbut not directly related to the --ignore-submodules param, and should\nbe solved separately.\n"},{"id":"238398","messageId":"534180BC.308@web.de","threadId":"36308","inReplyTo":"533C6B57.3080901@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-06T16:28:44Z","receivedAt":"2014-04-06T16:28:44Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 02.04.2014 21:56, schrieb Ronald Weiss:\n> On 2. 4. 2014 20:53, Jens Lehmann wrote:\n>> Am 01.04.2014 23:59, schrieb Ronald Weiss:\n>>> On 1. 4. 2014 22:23, Jens Lehmann wrote:\n>>>> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>>>>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>>>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>>>>> command also honor the --ignore-submodule command line option in\n>>>>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>>>>> I was right or not, then please just order them in the most logical\n>>>>>>>> way.\n>>>>>>>\n>>>>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>>>>> for git add, I may try to do it. However, git add does not even honor\n>>>>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>>>>> teaching git add the --ignore-submodules switch in current state\n>>>>>>> doesn't seem right to me. You might propose to add also support for\n>>>>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>>>>\n>>>>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>>>>> The changes below seem to enable support for both ignore setting in\n>>>>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>>>>> of my patch for commit.\n>>>>>\n>>>>> There is a catch. With the changes below, submodules are ignored by add\n>>>>> even if explitely named on command line (eg. \"git add x\" does nothing\n>>>>> if x is submodule with new commits, but with ignore=all in .gitmodules).\n>>>>> That doesn't seem right.\n>>>>>\n>>>>> Any ideas, what to do about that? When exactly should such submodule be\n>>>>> actually ignored?\n>>>>\n>>>> Me thinks git add should require the '-f' option to add an ignored\n>>>> submodule (just like it does for files) unless the user uses the\n>>>> '--ignore-submodules=none' option. And if neither of these are given\n>>>> it should \"fail with a list of ignored files\" as the documentation\n>>>> states.\n>>>\n>>> It's still not clear, at least not to me. Should '-f' suppress the\n>>> ignore setting of all involved submodules? That would make it a\n>>> synonyme (or a superset) of --ignore-submodules=none. Or only if the\n>>> submodule is explicitly named on command line? That seems fuzzy to me,\n>>> and also more tricky to implement.\n>>\n>> Maybe my impression that doing \"add\" together with \"commit\" would be\n>> easy wasn't correct after all. I won't object if you try to tackle\n>> commit first (but I have the slight suspicion that similar questions\n>> will arise concerning the \"add\"ish functionality in commit too. So\n>> maybe after resolving those things might look clearer ;-)\n> \n> There is one big distinction. My patch for commit doesn't add any new\n> problems. It just adds the --ignore-submodules argument, which is easy\n> to implement and no unclear behavior decisions are needed.\n> \n> You are right that when specifying ignored submodules on commit's\n> command line, there is the same problem as with git add. However, it's\n> already there anyway. I don't feel in position to solve it, I'd just\n> like to have \"git commit --ignore-submodules=none\".\n> \n> With git add however, changing it to honor settings from .gitmodules\n> would change behavior people might be used to, so I would be afraid to\n> do that. Btw add also has the problem already, but only if somebody\n> configures the submodule's ignore setting in .git/config, rather than\n> .gitmodules. I don't know how much real use case that is.\n> \n> As I see it, there are now these rather easy possibilities (sorted\n> from the easiest):\n> \n> 1) Just teach commit the --ignore-submodules argument, as I proposed.\n\n1a) Teach commit to honor ignore from .git/config.\n\n> 2) Teach both add and commit to --ignore-submodules, but dont add that\n> problematic gitmodules_config() in add.c.\n\nWhy is that problematic after add learned --ignore-submodules=none?\n\n> 3) Teach both add and commit to --ignore-submodules, and also let add\n> honor settings from .gitmodules, to make it more consistent with other\n> commands. And, make add --force imply --ignore-submodules=none.\n> \n> I like both 1) and 2). I don't like 3), the problem of add with\n> submodules' ignore setting is a bug IMHO (ignore=all in .git/config\n> causes strange behavior, while ignore=all in .gitmodules is ignored),\n> but not directly related to the --ignore-submodules param, and should\n> be solved separately.\n\nI think the ignore config options and --ignore-submodules parameter\nare directly related, as you need the latter to override the former.\nIn the long run commit should honor ignore=all in .git/config for\nunstaged submodules like add should honor the settings from the\n.gitmodules file. But we should always add the --ignore-submodules\nparameter first so that the user can override the configuration\nwhen needed. So I see these steps:\n\n1) Teach commit the --ignore-submodules option; then make it honor\n   ignore=all in .git/config in another commit.\n\n2) Teach add --ignore-submodules (which is implied by -f, but only\n   for the submodules given on the command line); then make it\n   honor the submodule.<name>.ignore option in another commit.\n\nAfter that we'd have consistent ignore and override behavior. But\nit looks like getting -f right is not easy, so I'd prefer having\n1) without 2) if the alternative is to get neither.\n"},{"id":"238514","messageId":"53431CB8.2050600@gmail.com","threadId":"36308","inReplyTo":"534180BC.308@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-07T21:46:32Z","receivedAt":"2014-04-07T21:46:32Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 6. 4. 2014 18:28, Jens Lehmann wrote:\n> Am 02.04.2014 21:56, schrieb Ronald Weiss:\n>> On 2. 4. 2014 20:53, Jens Lehmann wrote:\n>>> Am 01.04.2014 23:59, schrieb Ronald Weiss:\n>>>> On 1. 4. 2014 22:23, Jens Lehmann wrote:\n>>>>> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>>>>>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>>>>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>>>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>>>>>> command also honor the --ignore-submodule command line option in\n>>>>>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>>>>>> I was right or not, then please just order them in the most logical\n>>>>>>>>> way.\n>>>>>>>>\n>>>>>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>>>>>> for git add, I may try to do it. However, git add does not even honor\n>>>>>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>>>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>>>>>> teaching git add the --ignore-submodules switch in current state\n>>>>>>>> doesn't seem right to me. You might propose to add also support for\n>>>>>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>>>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>>>>>\n>>>>>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>>>>>> The changes below seem to enable support for both ignore setting in\n>>>>>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>>>>>> of my patch for commit.\n>>>>>>\n>>>>>> There is a catch. With the changes below, submodules are ignored by add\n>>>>>> even if explitely named on command line (eg. \"git add x\" does nothing\n>>>>>> if x is submodule with new commits, but with ignore=all in .gitmodules).\n>>>>>> That doesn't seem right.\n>>>>>>\n>>>>>> Any ideas, what to do about that? When exactly should such submodule be\n>>>>>> actually ignored?\n>>>>>\n>>>>> Me thinks git add should require the '-f' option to add an ignored\n>>>>> submodule (just like it does for files) unless the user uses the\n>>>>> '--ignore-submodules=none' option. And if neither of these are given\n>>>>> it should \"fail with a list of ignored files\" as the documentation\n>>>>> states.\n>>>>\n>>>> It's still not clear, at least not to me. Should '-f' suppress the\n>>>> ignore setting of all involved submodules? That would make it a\n>>>> synonyme (or a superset) of --ignore-submodules=none. Or only if the\n>>>> submodule is explicitly named on command line? That seems fuzzy to me,\n>>>> and also more tricky to implement.\n>>>\n>>> Maybe my impression that doing \"add\" together with \"commit\" would be\n>>> easy wasn't correct after all. I won't object if you try to tackle\n>>> commit first (but I have the slight suspicion that similar questions\n>>> will arise concerning the \"add\"ish functionality in commit too. So\n>>> maybe after resolving those things might look clearer ;-)\n>>\n>> There is one big distinction. My patch for commit doesn't add any new\n>> problems. It just adds the --ignore-submodules argument, which is easy\n>> to implement and no unclear behavior decisions are needed.\n>>\n>> You are right that when specifying ignored submodules on commit's\n>> command line, there is the same problem as with git add. However, it's\n>> already there anyway. I don't feel in position to solve it, I'd just\n>> like to have \"git commit --ignore-submodules=none\".\n>>\n>> With git add however, changing it to honor settings from .gitmodules\n>> would change behavior people might be used to, so I would be afraid to\n>> do that. Btw add also has the problem already, but only if somebody\n>> configures the submodule's ignore setting in .git/config, rather than\n>> .gitmodules. I don't know how much real use case that is.\n>>\n>> As I see it, there are now these rather easy possibilities (sorted\n>> from the easiest):\n>>\n>> 1) Just teach commit the --ignore-submodules argument, as I proposed.\n> \n> 1a) Teach commit to honor ignore from .git/config.\n\nBut commit already honors that. It honors submodule.<name>.ignore from\nboth .git/config and .gitmodules. It's just add which doesn't honor it\nfrom .gitmodules, because cmd_add() function lacks a gitmodules_config()\ncall. Or do I miss something?\n\n>> 2) Teach both add and commit to --ignore-submodules, but dont add that\n>> problematic gitmodules_config() in add.c.\n> \n> Why is that problematic after add learned --ignore-submodules=none?\n\nFirst, because it changes current behaviour. Which is obviously\ninconsistent currently, however I didn't find it easy to tell what's\nthe right thing to do.\n\nAnd second, because the \"-f implies --ignore-submodules=none\" proposal,\nwhich seems to be the easy cure for those accustomed to the current\nbehavior, seems non-trivial. Below You wrote that\n--ignore-submodules=none should be implied by -f only for files\nspecified on the command line. OK. And what if a directory\ncontaining the submodule is specified?\n\n>> 3) Teach both add and commit to --ignore-submodules, and also let add\n>> honor settings from .gitmodules, to make it more consistent with other\n>> commands. And, make add --force imply --ignore-submodules=none.\n>>\n>> I like both 1) and 2). I don't like 3), the problem of add with\n>> submodules' ignore setting is a bug IMHO (ignore=all in .git/config\n>> causes strange behavior, while ignore=all in .gitmodules is ignored),\n>> but not directly related to the --ignore-submodules param, and should\n>> be solved separately.\n> \n> I think the ignore config options and --ignore-submodules parameter\n> are directly related, as you need the latter to override the former.\n> In the long run commit should honor ignore=all in .git/config for\n> unstaged submodules like add should honor the settings from the\n> .gitmodules file. But we should always add the --ignore-submodules\n> parameter first so that the user can override the configuration\n> when needed. So I see these steps:\n> \n> 1) Teach commit the --ignore-submodules option; then make it honor\n>     ignore=all in .git/config in another commit.\n> \n> 2) Teach add --ignore-submodules (which is implied by -f, but only\n>     for the submodules given on the command line); then make it\n>     honor the submodule.<name>.ignore option in another commit.\n> \n> After that we'd have consistent ignore and override behavior. But\n> it looks like getting -f right is not easy, so I'd prefer having\n> 1) without 2) if the alternative is to get neither.\n\nOK, I will try prepare that. However I'd more like to start with two\ncommits just adding the --ignore-submodules param to add and commit.\nThat should be easily acceptable, as there is no risk to break\nanything, and it adds useful funcionality. Patching add first will\navoid having to touch add.c in patch for commit, which makes it more\nclear and logical IMHO.\n\nThen, on top of that, I'll prepare patches for add to honor ignore\nfrom .gitmodules, and -f implying --ignore-submodules. That might need\nmore discussion, let's see.\n"},{"id":"238520","messageId":"53432E38.4080403@gmail.com","threadId":"36308","inReplyTo":"53431CB8.2050600@gmail.com","subject":"[PATCH v3 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-07T23:01:12Z","receivedAt":"2014-04-07T23:01:12Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow overriding the ignore setting from config, using the command line\nparameter like diff and status have. Git add currently doesn't honor\nignore from .gitmodules, but it does honor it from .git/config. And\nsupport for .gitmodules will come in another patch.\n\nUseful <when> values are 'none' and 'all' (the default), the other values\n('dirty' and 'untracked') being equivalent to 'none' for add's purposes.\n\nAlso add ignore_submodules_arg parameter to function add_files_to_cache,\nwhich will allow implementing --ignore-submodules also for other commands\nusing this function (for commit command, in particular, coming in\nsubsequent commit). This requires compilo fixes in checkout.c and commit.c\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nI have changed order of commits, from what Jens proposed, to avoid the patch\nfor commit (coming right after this one) having to mess too much with add's\nsource code.\n\nIf anyone disagrees, let me know, and I will redo it as needed.\n\nI'll look in to the related \"add [-f] vs .gitmodules:ignore=all\" problem\nsoon.\n\n Documentation/git-add.txt        |  7 ++++++-\n builtin/add.c                    | 21 +++++++++++++++----\n builtin/checkout.c               |  2 +-\n builtin/commit.c                 |  2 +-\n cache.h                          |  2 +-\n t/t3704-add-ignore-submodules.sh | 45 ++++++++++++++++++++++++++++++++++++++++\n 6 files changed, 71 insertions(+), 8 deletions(-)\n create mode 100644 t/t3704-add-ignore-submodules.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 48754cb..be2e7b5 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -11,7 +11,7 @@ SYNOPSIS\n 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n \t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n-\t  [--] [<pathspec>...]\n+\t  [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -160,6 +160,11 @@ today's \"git add <pathspec>...\", ignoring removed files.\n \tbe ignored, no matter if they are already present in the work\n \ttree or not.\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 672adc0..72ef792 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -168,7 +168,8 @@ static void update_callback(struct diff_queue_struct *q,\n \n static void update_files_in_cache(const char *prefix,\n \t\t\t\t  const struct pathspec *pathspec,\n-\t\t\t\t  struct update_callback_data *data)\n+\t\t\t\t  struct update_callback_data *data,\n+\t\t\t\t  const char *ignore_submodules_arg)\n {\n \tstruct rev_info rev;\n \n@@ -180,17 +181,24 @@ static void update_files_in_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \n \tmemset(&data, 0, sizeof(data));\n \tdata.flags = flags;\n-\tupdate_files_in_cache(prefix, pathspec, &data);\n+\tupdate_files_in_cache(prefix, pathspec, &data, ignore_submodules_arg);\n \treturn !!data.add_errors;\n }\n \n@@ -342,6 +350,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n static int addremove = ADDREMOVE_DEFAULT;\n static int addremove_explicit = -1; /* unspecified */\n \n+static char *ignore_submodule_arg;\n+\n static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n {\n \t/* if we are told to ignore, we are not adding removals */\n@@ -367,6 +377,9 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n \tOPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n \tOPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n+\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \tOPT_END(),\n };\n \n@@ -576,7 +589,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\tmemset(&pathspec, 0, sizeof(pathspec));\n \t}\n \tupdate_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;\n-\tupdate_files_in_cache(prefix, &pathspec, &update_data);\n+\tupdate_files_in_cache(prefix, &pathspec, &update_data, ignore_submodule_arg);\n \n \texit_status |= !!update_data.add_errors;\n \tif (add_new_files)\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex ada51fa..22a4b48 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 26b2986..0db215b 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\ndiff --git a/cache.h b/cache.h\nindex ebe9a40..5ef8dd6 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1282,7 +1282,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..db58f0c\n--- /dev/null\n+++ b/t/t3704-add-ignore-submodules.sh\n@@ -0,0 +1,45 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git add with ignoring submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create dirty submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\" && (\n+\t\tcd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Update foo\"\n+\t)\n+'\n+\n+test_expect_success 'add --ignore-submodules ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=all ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules=all &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n+\tgit reset &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit add -u --ignore-submodules=none &&\n+\ttest_must_fail git diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.1.3.gef38fe4\n \n"},{"id":"238521","messageId":"53432EA5.5060102@gmail.com","threadId":"36308","inReplyTo":"53431CB8.2050600@gmail.com","subject":"[PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-07T23:03:01Z","receivedAt":"2014-04-07T23:03:01Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Git commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line, like other commands do.\n\nUseful <when> values for commit are 'all' (default) or 'none'. The others\n('dirty' and 'untracked') have same effect as 'none', as commit is only\ninterested in whether the submodule's HEAD differs from what is commited\nin the superproject.\n\nThis patch depends on Jens Lehmann's patch \"commit -m: commit staged\nsubmodules regardless of ignore config\". Without it,\n\"commit -m --ignore-submodules\" would not work and tests introduced\nhere would fail.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\n Documentation/git-commit.txt        |  6 ++++++\n builtin/commit.c                    |  8 ++++++-\n t/t7513-commit-ignore-submodules.sh | 42 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 55 insertions(+), 1 deletion(-)\n create mode 100644 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 1a7616c..8d3b2db 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -271,6 +272,11 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 0db215b..121c185 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..83ce04c\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,42 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(cd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n+\tgit diff --exit-code --ignore-submodules=none &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.1.3.gef38fe4\n \n"},{"id":"238548","messageId":"53443F5C.7050400@web.de","threadId":"36308","inReplyTo":"53431CB8.2050600@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-08T18:26:36Z","receivedAt":"2014-04-08T18:26:36Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 07.04.2014 23:46, schrieb Ronald Weiss:\n> On 6. 4. 2014 18:28, Jens Lehmann wrote:\n>> Am 02.04.2014 21:56, schrieb Ronald Weiss:\n>>> On 2. 4. 2014 20:53, Jens Lehmann wrote:\n>>>> Am 01.04.2014 23:59, schrieb Ronald Weiss:\n>>>>> On 1. 4. 2014 22:23, Jens Lehmann wrote:\n>>>>>> Am 01.04.2014 01:35, schrieb Ronald Weiss:\n>>>>>>> On 1. 4. 2014 0:50, Ronald Weiss wrote:\n>>>>>>>> On 31. 3. 2014 23:47, Ronald Weiss wrote:\n>>>>>>>>> On Mon, Mar 31, 2014 at 8:58 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:\n>>>>>>>>>> As Junio mentioned it would be great if you could teach the add\n>>>>>>>>>> command also honor the --ignore-submodule command line option in\n>>>>>>>>>> a companion patch. In the course of doing so you'll easily see if\n>>>>>>>>>> I was right or not, then please just order them in the most logical\n>>>>>>>>>> way.\n>>>>>>>>>\n>>>>>>>>> Well, if You (or Junio) really don't want my patch without another one\n>>>>>>>>> for git add, I may try to do it. However, git add does not even honor\n>>>>>>>>> the submodules' ignore setting from .gitmodules (just tested with git\n>>>>>>>>> 1.9.1: \"git add -u\" doesn't honor it, while \"git commit -a\" does). So\n>>>>>>>>> teaching git add the --ignore-submodules switch in current state\n>>>>>>>>> doesn't seem right to me. You might propose to add also support for\n>>>>>>>>> the ignore setting, to make \"add -u\" and \"commit -a\" more consistent.\n>>>>>>>>> That seems like a good idea, but the effort needed is getting bigger,\n>>>>>>>>\n>>>>>>>> Well, now I actually looked at it, and it was pretty easy after all.\n>>>>>>>> The changes below seem to enable support for both ignore setting in\n>>>>>>>> .gitmodules, and also --ignore-submodules switch, for git add, on top\n>>>>>>>> of my patch for commit.\n>>>>>>>\n>>>>>>> There is a catch. With the changes below, submodules are ignored by add\n>>>>>>> even if explitely named on command line (eg. \"git add x\" does nothing\n>>>>>>> if x is submodule with new commits, but with ignore=all in .gitmodules).\n>>>>>>> That doesn't seem right.\n>>>>>>>\n>>>>>>> Any ideas, what to do about that? When exactly should such submodule be\n>>>>>>> actually ignored?\n>>>>>>\n>>>>>> Me thinks git add should require the '-f' option to add an ignored\n>>>>>> submodule (just like it does for files) unless the user uses the\n>>>>>> '--ignore-submodules=none' option. And if neither of these are given\n>>>>>> it should \"fail with a list of ignored files\" as the documentation\n>>>>>> states.\n>>>>>\n>>>>> It's still not clear, at least not to me. Should '-f' suppress the\n>>>>> ignore setting of all involved submodules? That would make it a\n>>>>> synonyme (or a superset) of --ignore-submodules=none. Or only if the\n>>>>> submodule is explicitly named on command line? That seems fuzzy to me,\n>>>>> and also more tricky to implement.\n>>>>\n>>>> Maybe my impression that doing \"add\" together with \"commit\" would be\n>>>> easy wasn't correct after all. I won't object if you try to tackle\n>>>> commit first (but I have the slight suspicion that similar questions\n>>>> will arise concerning the \"add\"ish functionality in commit too. So\n>>>> maybe after resolving those things might look clearer ;-)\n>>>\n>>> There is one big distinction. My patch for commit doesn't add any new\n>>> problems. It just adds the --ignore-submodules argument, which is easy\n>>> to implement and no unclear behavior decisions are needed.\n>>>\n>>> You are right that when specifying ignored submodules on commit's\n>>> command line, there is the same problem as with git add. However, it's\n>>> already there anyway. I don't feel in position to solve it, I'd just\n>>> like to have \"git commit --ignore-submodules=none\".\n>>>\n>>> With git add however, changing it to honor settings from .gitmodules\n>>> would change behavior people might be used to, so I would be afraid to\n>>> do that. Btw add also has the problem already, but only if somebody\n>>> configures the submodule's ignore setting in .git/config, rather than\n>>> .gitmodules. I don't know how much real use case that is.\n>>>\n>>> As I see it, there are now these rather easy possibilities (sorted\n>>> from the easiest):\n>>>\n>>> 1) Just teach commit the --ignore-submodules argument, as I proposed.\n>>\n>> 1a) Teach commit to honor ignore from .git/config.\n> \n> But commit already honors that. It honors submodule.<name>.ignore from\n> both .git/config and .gitmodules. It's just add which doesn't honor it\n> from .gitmodules, because cmd_add() function lacks a gitmodules_config()\n> call. Or do I miss something?\n\nNo, I missed that, so please forget my comment.\n\n>>> 2) Teach both add and commit to --ignore-submodules, but dont add that\n>>> problematic gitmodules_config() in add.c.\n>>\n>> Why is that problematic after add learned --ignore-submodules=none?\n> \n> First, because it changes current behaviour. Which is obviously\n> inconsistent currently, however I didn't find it easy to tell what's\n> the right thing to do.\n\nI believe we should be consistent here, but the overriding of that\noption is the tricky part. So we need to solve that first before we\ncan add gitmodules_config() to add.c.\n\n> And second, because the \"-f implies --ignore-submodules=none\" proposal,\n> which seems to be the easy cure for those accustomed to the current\n> behavior, seems non-trivial. Below You wrote that\n> --ignore-submodules=none should be implied by -f only for files\n> specified on the command line. OK. And what if a directory\n> containing the submodule is specified?\n\nThat should behave just like an ignored file is contained in that\ndirectory me thinks. But I agree this is non trivial.\n\n>>> 3) Teach both add and commit to --ignore-submodules, and also let add\n>>> honor settings from .gitmodules, to make it more consistent with other\n>>> commands. And, make add --force imply --ignore-submodules=none.\n>>>\n>>> I like both 1) and 2). I don't like 3), the problem of add with\n>>> submodules' ignore setting is a bug IMHO (ignore=all in .git/config\n>>> causes strange behavior, while ignore=all in .gitmodules is ignored),\n>>> but not directly related to the --ignore-submodules param, and should\n>>> be solved separately.\n>>\n>> I think the ignore config options and --ignore-submodules parameter\n>> are directly related, as you need the latter to override the former.\n>> In the long run commit should honor ignore=all in .git/config for\n>> unstaged submodules like add should honor the settings from the\n>> .gitmodules file. But we should always add the --ignore-submodules\n>> parameter first so that the user can override the configuration\n>> when needed. So I see these steps:\n>>\n>> 1) Teach commit the --ignore-submodules option; then make it honor\n>>     ignore=all in .git/config in another commit.\n>>\n>> 2) Teach add --ignore-submodules (which is implied by -f, but only\n>>     for the submodules given on the command line); then make it\n>>     honor the submodule.<name>.ignore option in another commit.\n>>\n>> After that we'd have consistent ignore and override behavior. But\n>> it looks like getting -f right is not easy, so I'd prefer having\n>> 1) without 2) if the alternative is to get neither.\n> \n> OK, I will try prepare that. However I'd more like to start with two\n> commits just adding the --ignore-submodules param to add and commit.\n> That should be easily acceptable, as there is no risk to break\n> anything, and it adds useful funcionality. Patching add first will\n> avoid having to touch add.c in patch for commit, which makes it more\n> clear and logical IMHO.\n\nGood to hear that!\n\n> Then, on top of that, I'll prepare patches for add to honor ignore\n> from .gitmodules, and -f implying --ignore-submodules. That might need\n> more discussion, let's see.\n\nMakes sense.\n"},{"id":"238551","messageId":"53444368.9050607@web.de","threadId":"36308","inReplyTo":"53432EA5.5060102@gmail.com","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-08T18:43:52Z","receivedAt":"2014-04-08T18:43:52Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 08.04.2014 01:03, schrieb Ronald Weiss:\n> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n> but didn't allow to override it from command line, like other commands do.\n> \n> Useful <when> values for commit are 'all' (default) or 'none'. The others\n> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n> interested in whether the submodule's HEAD differs from what is commited\n> in the superproject.\n\nUnless it outputs a status message, then 'dirty' and 'untracked' do\ninfluence what is shown there. Apart from that (and maybe tests for\nthese two cases ;-) this is looking good to me.\n\n> This patch depends on Jens Lehmann's patch \"commit -m: commit staged\n> submodules regardless of ignore config\". Without it,\n> \"commit -m --ignore-submodules\" would not work and tests introduced\n> here would fail.\n> \n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  Documentation/git-commit.txt        |  6 ++++++\n>  builtin/commit.c                    |  8 ++++++-\n>  t/t7513-commit-ignore-submodules.sh | 42 +++++++++++++++++++++++++++++++++++++\n>  3 files changed, 55 insertions(+), 1 deletion(-)\n>  create mode 100644 t/t7513-commit-ignore-submodules.sh\n> \n> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\n> index 1a7616c..8d3b2db 100644\n> --- a/Documentation/git-commit.txt\n> +++ b/Documentation/git-commit.txt\n> @@ -13,6 +13,7 @@ SYNOPSIS\n>  \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n>  \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n>  \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n> +\t   [--ignore-submodules[=<when>]]\n>  \t   [-i | -o] [-S[<keyid>]] [--] [<file>...]\n>  \n>  DESCRIPTION\n> @@ -271,6 +272,11 @@ The possible options are:\n>  The default can be changed using the status.showUntrackedFiles\n>  configuration variable documented in linkgit:git-config[1].\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'submodule.*.ignore'\n> +\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\" or \"all\", which is the default.\n> +\n>  -v::\n>  --verbose::\n>  \tShow unified diff between the HEAD commit and what\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 0db215b..121c185 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -360,7 +360,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> @@ -1492,6 +1492,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n>  \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n>  \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n> +\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \t\t/* end commit contents options */\n>  \n>  \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n> @@ -1531,6 +1534,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n>  \t\t\t\t\t  builtin_commit_usage,\n>  \t\t\t\t\t  prefix, current_head, &s);\n> +\n> +\ts.ignore_submodule_arg = ignore_submodule_arg;\n> +\n>  \tif (dry_run)\n>  \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n>  \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\n> diff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\n> new file mode 100644\n> index 0000000..83ce04c\n> --- /dev/null\n> +++ b/t/t7513-commit-ignore-submodules.sh\n> @@ -0,0 +1,42 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2014 Ronald Weiss\n> +#\n> +\n> +test_description='Test of git commit --ignore-submodules'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'create submodule' '\n> +\ttest_create_repo sm && (\n> +\t\tcd sm &&\n> +\t\t>foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Add foo\"\n> +\t) &&\n> +\tgit submodule add ./sm &&\n> +\tgit commit -m \"Add sm\"\n> +'\n> +\n> +update_sm () {\n> +\t(cd sm &&\n> +\t\techo bar >> foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Updated foo\"\n> +\t)\n> +}\n> +\n> +test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n> +\tupdate_sm &&\n> +\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n> +'\n> +\n> +test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n> +\tupdate_sm &&\n> +\tgit config submodule.sm.ignore all &&\n> +\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n> +\tgit diff --exit-code --ignore-submodules=none &&\n> +\tgit diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_done\n> \n"},{"id":"238563","messageId":"534459C0.4090705@gmail.com","threadId":"36308","inReplyTo":"53444368.9050607@web.de","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-08T20:19:12Z","receivedAt":"2014-04-08T20:19:12Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 8. 4. 2014 20:43, Jens Lehmann wrote:\n> Am 08.04.2014 01:03, schrieb Ronald Weiss:\n>> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n>> but didn't allow to override it from command line, like other commands do.\n>>\n>> Useful <when> values for commit are 'all' (default) or 'none'. The others\n>> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n>> interested in whether the submodule's HEAD differs from what is commited\n>> in the superproject.\n> \n> Unless it outputs a status message, then 'dirty' and 'untracked' do\n> influence what is shown there. Apart from that (and maybe tests for\n> these two cases ;-) this is looking good to me.\n\nHm, You mean the status message, which is pre-inserted as comment into\nthe commit message, when opening an editor to write the commit message?\n\nOK, that really makes a difference, although really small and actually\naffecting nothing. I'll take it into account. But are You sure the tests\nfor this would be actually useful? If only effect of them would be\nincreasing time needed to run the full test suite, then it's better to\nnot have them :-). But I can do that, if You still think it's useful.\n"},{"id":"238799","messageId":"5349BC2C.9030509@gmail.com","threadId":"36308","inReplyTo":"53444368.9050607@web.de","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-12T22:20:28Z","receivedAt":"2014-04-12T22:20:28Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 8. 4. 2014 20:43, Jens Lehmann wrote:\n>> Useful <when> values for commit are 'all' (default) or 'none'. The others\n>> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n>> interested in whether the submodule's HEAD differs from what is commited\n>> in the superproject.\n>\n> Unless it outputs a status message, then 'dirty' and 'untracked' do\n> influence what is shown there. Apart from that (and maybe tests for\n> these two cases ;-) this is looking good to me.\n\nOK, I updated the patch for commit to take that into account. Also, I\nrebased both patches onto current master. Sending them in a moment.\n\nIf you don't have any more complaints, can I add \"Acked-by: <you>\" and\nresend the patches to Junio?\n"},{"id":"238801","messageId":"5349C226.9090709@gmail.com","threadId":"36308","inReplyTo":"5349BC2C.9030509@gmail.com","subject":"[PATCH v4 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-12T22:45:58Z","receivedAt":"2014-04-12T22:45:58Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nGit add currently doesn't honor ignore from .gitmodules or .git/config,\nwhich is related functionality, however I'd like to change that in\nanother patch, coming soon.\n\nThis commit is also a prerequisite for the next one in series, which\nadds the --ignore-submodules switch to git commit. That's why signature\nof function add_files_to_cache was changed. That also requires compilo\nfixes in checkout.c and commit.c\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\n Documentation/git-add.txt        |  7 ++++++-\n builtin/add.c                    | 16 ++++++++++++--\n builtin/checkout.c               |  2 +-\n builtin/commit.c                 |  2 +-\n cache.h                          |  2 +-\n t/t3704-add-ignore-submodules.sh | 45 ++++++++++++++++++++++++++++++++++++++++\n 6 files changed, 68 insertions(+), 6 deletions(-)\n create mode 100644 t/t3704-add-ignore-submodules.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 9631526..b2c936f 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -11,7 +11,7 @@ SYNOPSIS\n 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n \t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n-\t  [--] [<pathspec>...]\n+\t  [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -164,6 +164,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n \tbe ignored, no matter if they are already present in the work\n \ttree or not.\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 459208a..85f2110 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -83,7 +83,8 @@ static void update_callback(struct diff_queue_struct *q,\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \tstruct rev_info rev;\n@@ -99,6 +100,12 @@ int add_files_to_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = &data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n \treturn !!data.add_errors;\n }\n@@ -237,6 +244,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n static int addremove = ADDREMOVE_DEFAULT;\n static int addremove_explicit = -1; /* unspecified */\n \n+static char *ignore_submodule_arg;\n+\n static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n {\n \t/* if we are told to ignore, we are not adding removals */\n@@ -262,6 +271,9 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n \tOPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n \tOPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n+\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \tOPT_END(),\n };\n \n@@ -434,7 +446,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tplug_bulk_checkin();\n \n-\texit_status |= add_files_to_cache(prefix, &pathspec, flags);\n+\texit_status |= add_files_to_cache(prefix, &pathspec, flags, ignore_submodule_arg);\n \n \tif (add_new_files)\n \t\texit_status |= add_files(&dir, flags);\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 07cf555..607af47 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 9cfef6c..a148e28 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\ndiff --git a/cache.h b/cache.h\nindex 107ac61..a6cedc0 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1370,7 +1370,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..db58f0c\n--- /dev/null\n+++ b/t/t3704-add-ignore-submodules.sh\n@@ -0,0 +1,45 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git add with ignoring submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create dirty submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\" && (\n+\t\tcd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Update foo\"\n+\t)\n+'\n+\n+test_expect_success 'add --ignore-submodules ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=all ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules=all &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n+\tgit reset &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit add -u --ignore-submodules=none &&\n+\ttest_must_fail git diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.1.3.g7790cde.dirty\n \n"},{"id":"238802","messageId":"5349C314.50500@gmail.com","threadId":"36308","inReplyTo":"5349BC2C.9030509@gmail.com","subject":"[PATCH v4 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-12T22:49:56Z","receivedAt":"2014-04-12T22:49:56Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nGit commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line.\n\nThis patch depends on Jens Lehmann's patch \"commit -m: commit staged\nsubmodules regardless of ignore config\". Without it,\n\"commit -m --ignore-submodules\" would not work and tests introduced\nhere would fail.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\n Documentation/git-commit.txt        |  7 ++++\n builtin/commit.c                    |  8 +++-\n t/t7513-commit-ignore-submodules.sh | 78 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 92 insertions(+), 1 deletion(-)\n create mode 100644 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 0bbc8f5..de0e8fe 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<key-id>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -277,6 +278,12 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\", \"dirty, \"untracked\" or \"all\", which\n+\tis the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex a148e28..8c4d05e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -1526,6 +1526,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1564,6 +1567,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100644\nindex 0000000..52ab37d\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,78 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(cd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n+\tgit diff --exit-code --ignore-submodules=none &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of submodule with untracked content' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo untracked > sm/untracked &&\n+\n+\ttest_might_fail git commit --ignore-submodules=none > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=untracked > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=dirty > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=all > output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of dirty submodule' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo dirty > sm/foo &&\n+\n+\ttest_might_fail git commit --ignore-submodules=none > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=untracked > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=dirty > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_might_fail git commit --ignore-submodules=all > output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_done\n-- \n1.9.1.3.g7790cde.dirty\n \n"},{"id":"238805","messageId":"5349CF3E.7010606@gmail.com","threadId":"36308","inReplyTo":"53443F5C.7050400@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-12T23:41:50Z","receivedAt":"2014-04-12T23:41:50Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 8. 4. 2014 20:26, Jens Lehmann wrote:\n> Am 07.04.2014 23:46, schrieb Ronald Weiss:\n>> Then, on top of that, I'll prepare patches for add to honor ignore\n>> from .gitmodules, and -f implying --ignore-submodules. That might need\n>> more discussion, let's see.\n> \n> Makes sense.\n\nI thought more about that, and also played with the code a bit.\n\nFirst, I was confused when I wrote that git add doesn't honor\nsubmodules' ignore setting only from .gitmodules, but it does from\n.git/config. It doesn't, from neither. Sorry for the confusion. However,\nthat doesn't change anything on the fact that it would be nice if add\nwould honor the ignore setting, from both places.\n\nSecond, there are some differences between adding standard ignored\nfiles, and ignored submodules:\n\n1) Already tracked files are never ignored, regardless of .gitignore.\n However, tracked submodules should be ignored by \"add -u\", if told so\n by their ignore setting.\n\n2) So .gitignore seems to only do something when adding new files to\n the repo. However, when adding new submodules, they are probably never\n ignored (setting the ignore setting for non existent submodule seems\n like non-sense, although possible).\n\n3) Ignored files can be ignored less explicitely (in global gitignore,\n or using a wildcard, or by ignoring parent folder). So it makes sense\n to warn the user if he tries to explicitely add an ignored file, as he\n might not be aware that the file is ignored. Submodules, however, can\n only be ignored explicitely. And when user explicitely specifies the\n submodule in an add command, he most probably really wants to add it,\n so I don't see the point in warning him and requiring the -f option.\n\nSo, I think that the use cases are completely different, for submodules\nand ignored files. So trying to make add behave the same for both, might\nnot be that good idea.\n\nI would propose - let's make add honor the ignore setting by just\nparsing if from config like the other commands do, and pass it to\nunderlying diff invocations. And at the same the, let's override it for\nsubmodules explicitely specified on the command line, to never ignore\nsuch submodules, without requiring the -f option. That seems to be\npretty easy, see below.\n\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 85f2110..f19e6c8 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -284,6 +284,10 @@ static int add_config(const char *var, const char *value, void *cb)\n \t\tignore_add_errors = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n+\n+\tif (starts_with(var, \"submodule.\"))\n+\t\treturn parse_submodule_config_option(var, value);\n+\n \treturn git_default_config(var, value, cb);\n }\n \n@@ -320,6 +324,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \tchar *seen = NULL;\n \n \tgit_config(add_config, NULL);\n+\tgitmodules_config();\n \n \targc = parse_options(argc, argv, prefix, builtin_add_options,\n \t\t\t  builtin_add_usage, PARSE_OPT_KEEP_ARGV0);\n@@ -425,6 +430,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\t       PATHSPEC_EXCLUDE);\n \n \t\tfor (i = 0; i < pathspec.nr; i++) {\n+\t\t\tint cachepos;\n \t\t\tconst char *path = pathspec.items[i].match;\n \t\t\tif (pathspec.items[i].magic & PATHSPEC_EXCLUDE)\n \t\t\t\tcontinue;\n@@ -440,6 +446,18 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n \t\t\t\t\t    pathspec.items[i].original);\n \t\t\t}\n+\n+\t\t\t/* disable ignore setting for any submodules specified explicitly in the pathspec */\n+\t\t\tif (path[0] &&\n+\t\t\t\t(cachepos = cache_name_pos(path, pathspec.items[i].len)) >= 0 &&\n+\t\t\t\tS_ISGITLINK(active_cache[cachepos]->ce_mode)) {\n+\t\t\t\tchar *optname;\n+\t\t\t\tint optnamelen = pathspec.items[i].len + 17;\n+\t\t\t\toptname = xcalloc(optnamelen + 1, 1);\n+\t\t\t\tsnprintf(optname, optnamelen + 1, \"submodule.%s.ignore\", path);\n+\t\t\t\tparse_submodule_config_option(optname, \"none\");\n+\t\t\t\tfree(optname);\n+\t\t\t}\n \t\t}\n \t\tfree(seen);\n \t}\n--  \n"},{"id":"238854","messageId":"xmqqd2gjpxvy.fsf@gitster.dls.corp.google.com","threadId":"36308","inReplyTo":"5349BC2C.9030509@gmail.com","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-14T18:30:09Z","receivedAt":"2014-04-14T18:30:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ronald Weiss <weiss.ronald@gmail.com> writes:\n\n> On 8. 4. 2014 20:43, Jens Lehmann wrote:\n>>> Useful <when> values for commit are 'all' (default) or 'none'. The others\n>>> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n>>> interested in whether the submodule's HEAD differs from what is commited\n>>> in the superproject.\n>>\n>> Unless it outputs a status message, then 'dirty' and 'untracked' do\n>> influence what is shown there. Apart from that (and maybe tests for\n>> these two cases ;-) this is looking good to me.\n>\n> OK, I updated the patch for commit to take that into account. Also, I\n> rebased both patches onto current master. Sending them in a moment.\n>\n> If you don't have any more complaints, can I add \"Acked-by: <you>\" and\n> resend the patches to Junio?\n\nIt is not \"When I see no more complaints, I'll resend with your\nAck\".  An Ack is a positive thing, not lack of discovery of further\nissues.\n\nRather, it is more like \"I'll wait for your Acks and then I'll\nresend with your Ack\", or \"If they look good, reply with Ack and let\nthe maintainer pick them up\".\n\nThanks.\n"},{"id":"238860","messageId":"534C429A.6080508@gmail.com","threadId":"36308","inReplyTo":"xmqqd2gjpxvy.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-14T20:18:34Z","receivedAt":"2014-04-14T20:18:34Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 14. 4. 2014 20:30, Junio C Hamano wrote:\n> Ronald Weiss <weiss.ronald@gmail.com> writes:\n> \n>> On 8. 4. 2014 20:43, Jens Lehmann wrote:\n>>>> Useful <when> values for commit are 'all' (default) or 'none'. The others\n>>>> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n>>>> interested in whether the submodule's HEAD differs from what is commited\n>>>> in the superproject.\n>>>\n>>> Unless it outputs a status message, then 'dirty' and 'untracked' do\n>>> influence what is shown there. Apart from that (and maybe tests for\n>>> these two cases ;-) this is looking good to me.\n>>\n>> OK, I updated the patch for commit to take that into account. Also, I\n>> rebased both patches onto current master. Sending them in a moment.\n>>\n>> If you don't have any more complaints, can I add \"Acked-by: <you>\" and\n>> resend the patches to Junio?\n> \n> It is not \"When I see no more complaints, I'll resend with your\n> Ack\".  An Ack is a positive thing, not lack of discovery of further\n> issues.\n\nI'm really sorry if the tone of my message sounded harsh to you, it\nwasn't meant like that at all.\n\n> Rather, it is more like \"I'll wait for your Acks and then I'll\n> resend with your Ack\", or \"If they look good, reply with Ack and let\n> the maintainer pick them up\".\n\nOK.\n"},{"id":"238867","messageId":"xmqqsipfmxes.fsf@gitster.dls.corp.google.com","threadId":"36308","inReplyTo":"534C429A.6080508@gmail.com","subject":"Re: [PATCH v3 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-04-14T21:08:43Z","receivedAt":"2014-04-14T21:08:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ronald Weiss <weiss.ronald@gmail.com> writes:\n\n> On 14. 4. 2014 20:30, Junio C Hamano wrote:\n>> Ronald Weiss <weiss.ronald@gmail.com> writes:\n>> \n>>> On 8. 4. 2014 20:43, Jens Lehmann wrote:\n>>>>> Useful <when> values for commit are 'all' (default) or 'none'. The others\n>>>>> ('dirty' and 'untracked') have same effect as 'none', as commit is only\n>>>>> interested in whether the submodule's HEAD differs from what is commited\n>>>>> in the superproject.\n>>>>\n>>>> Unless it outputs a status message, then 'dirty' and 'untracked' do\n>>>> influence what is shown there. Apart from that (and maybe tests for\n>>>> these two cases ;-) this is looking good to me.\n>>>\n>>> OK, I updated the patch for commit to take that into account. Also, I\n>>> rebased both patches onto current master. Sending them in a moment.\n>>>\n>>> If you don't have any more complaints, can I add \"Acked-by: <you>\" and\n>>> resend the patches to Junio?\n>> \n>> It is not \"When I see no more complaints, I'll resend with your\n>> Ack\".  An Ack is a positive thing, not lack of discovery of further\n>> issues.\n>\n> I'm really sorry if the tone of my message sounded harsh to you, it\n> wasn't meant like that at all.\n\nNo, that wasn't harsh at all.  I just did not want to get a patch\nwith Acked-by with somebody's name on it, when there is not yet an\nAck, as that will confuse me greatly.  My mental bandwidth is not\nwide enough to keep track of all the in-flight topics I haven't yet\npicked up.\n\nI should be the one to say sorry if my message sounded harsh.\n\nThanks.\n\n>> Rather, it is more like \"I'll wait for your Acks and then I'll\n>> resend with your Ack\", or \"If they look good, reply with Ack and let\n>> the maintainer pick them up\".\n>\n> OK.\n"},{"id":"239063","messageId":"5351123A.9060201@web.de","threadId":"36308","inReplyTo":"5349C226.9090709@gmail.com","subject":"Re: [PATCH v4 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-18T11:53:30Z","receivedAt":"2014-04-18T11:53:30Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 13.04.2014 00:45, schrieb Ronald Weiss:\n> Allow ignoring submodules (or not) by command line switch, like diff\n> and status do.\n> \n> Git add currently doesn't honor ignore from .gitmodules or .git/config,\n> which is related functionality, however I'd like to change that in\n> another patch, coming soon.\n\nI think we should drop this paragraph from this commit message. Though\nI believe it's helpful to add this information after the \"---\" below\nto inform readers of the list of your future plans.\n\n> This commit is also a prerequisite for the next one in series, which\n> adds the --ignore-submodules switch to git commit.\n\nBut this information definitely belongs here.\n\n> That's why signature\n> of function add_files_to_cache was changed.\n\nBut that's necessary for this patch too, no?\n\n> That also requires compilo fixes in checkout.c and commit.c\n\nSorry, but I don't know what a \"compilo fix\" is ;-) .. I suspect you\nmean that add_files_to_cache() needs a new NULL argument in some\nplaces. What about dropping the last two sentences and adding\nsomething like \"Add a new argument to add_files_to_cache() to pass\nthe command line option and update all other call sites to pass\nNULL instead.\" to the first paragraph?\n\nApart from that and the flags of the test (see below) this patch\nis looking good to me.\n\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  Documentation/git-add.txt        |  7 ++++++-\n>  builtin/add.c                    | 16 ++++++++++++--\n>  builtin/checkout.c               |  2 +-\n>  builtin/commit.c                 |  2 +-\n>  cache.h                          |  2 +-\n>  t/t3704-add-ignore-submodules.sh | 45 ++++++++++++++++++++++++++++++++++++++++\n>  6 files changed, 68 insertions(+), 6 deletions(-)\n>  create mode 100644 t/t3704-add-ignore-submodules.sh\n> \n> diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\n> index 9631526..b2c936f 100644\n> --- a/Documentation/git-add.txt\n> +++ b/Documentation/git-add.txt\n> @@ -11,7 +11,7 @@ SYNOPSIS\n>  'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n>  \t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n>  \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n> -\t  [--] [<pathspec>...]\n> +\t  [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n>  \n>  DESCRIPTION\n>  -----------\n> @@ -164,6 +164,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n>  \tbe ignored, no matter if they are already present in the work\n>  \ttree or not.\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'submodule.*.ignore'\n> +\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\" or \"all\", which is the default.\n> +\n>  \\--::\n>  \tThis option can be used to separate command-line options from\n>  \tthe list of files, (useful when filenames might be mistaken\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 459208a..85f2110 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -83,7 +83,8 @@ static void update_callback(struct diff_queue_struct *q,\n>  }\n>  \n>  int add_files_to_cache(const char *prefix,\n> -\t\t       const struct pathspec *pathspec, int flags)\n> +\t\t       const struct pathspec *pathspec, int flags,\n> +\t\t       const char *ignore_submodules_arg)\n>  {\n>  \tstruct update_callback_data data;\n>  \tstruct rev_info rev;\n> @@ -99,6 +100,12 @@ int add_files_to_cache(const char *prefix,\n>  \trev.diffopt.format_callback = update_callback;\n>  \trev.diffopt.format_callback_data = &data;\n>  \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n> +\n> +\tif (ignore_submodules_arg) {\n> +\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n> +\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n> +\t}\n> +\n>  \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n>  \treturn !!data.add_errors;\n>  }\n> @@ -237,6 +244,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n>  static int addremove = ADDREMOVE_DEFAULT;\n>  static int addremove_explicit = -1; /* unspecified */\n>  \n> +static char *ignore_submodule_arg;\n> +\n>  static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n>  {\n>  \t/* if we are told to ignore, we are not adding removals */\n> @@ -262,6 +271,9 @@ static struct option builtin_add_options[] = {\n>  \tOPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n>  \tOPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n>  \tOPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n> +\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \tOPT_END(),\n>  };\n>  \n> @@ -434,7 +446,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \n>  \tplug_bulk_checkin();\n>  \n> -\texit_status |= add_files_to_cache(prefix, &pathspec, flags);\n> +\texit_status |= add_files_to_cache(prefix, &pathspec, flags, ignore_submodule_arg);\n>  \n>  \tif (add_new_files)\n>  \t\texit_status |= add_files(&dir, flags);\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index 07cf555..607af47 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n>  \t\t\t * entries in the index.\n>  \t\t\t */\n>  \n> -\t\t\tadd_files_to_cache(NULL, NULL, 0);\n> +\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n>  \t\t\t/*\n>  \t\t\t * NEEDSWORK: carrying over local changes\n>  \t\t\t * when branches have different end-of-line\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 9cfef6c..a148e28 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> diff --git a/cache.h b/cache.h\n> index 107ac61..a6cedc0 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1370,7 +1370,7 @@ void packet_trace_identity(const char *prog);\n>   * return 0 if success, 1 - if addition of a file failed and\n>   * ADD_FILES_IGNORE_ERRORS was specified in flags\n>   */\n> -int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n> +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n>  \n>  /* diff.c */\n>  extern int diff_auto_refresh_index;\n> diff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\n> new file mode 100644\n\nThe flags should be 100755 here, currently \"make test\" fails because\nof this.\n\n> index 0000000..db58f0c\n> --- /dev/null\n> +++ b/t/t3704-add-ignore-submodules.sh\n> @@ -0,0 +1,45 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2014 Ronald Weiss\n> +#\n> +\n> +test_description='Test of git add with ignoring submodules'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'create dirty submodule' '\n> +\ttest_create_repo sm && (\n> +\t\tcd sm &&\n> +\t\t>foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Add foo\"\n> +\t) &&\n> +\tgit submodule add ./sm &&\n> +\tgit commit -m \"Add sm\" && (\n> +\t\tcd sm &&\n> +\t\techo bar >> foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Update foo\"\n> +\t)\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules ignores submodule' '\n> +\tgit reset &&\n> +\tgit add -u --ignore-submodules &&\n> +\tgit diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules=all ignores submodule' '\n> +\tgit reset &&\n> +\tgit add -u --ignore-submodules=all &&\n> +\tgit diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n> +\tgit reset &&\n> +\tgit config submodule.sm.ignore all &&\n> +\tgit add -u --ignore-submodules=none &&\n> +\ttest_must_fail git diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_done\n> \n"},{"id":"239064","messageId":"53511617.80506@web.de","threadId":"36308","inReplyTo":"5349C314.50500@gmail.com","subject":"Re: [PATCH v4 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-18T12:09:59Z","receivedAt":"2014-04-18T12:09:59Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 13.04.2014 00:49, schrieb Ronald Weiss:\n> Allow ignoring submodules (or not) by command line switch, like diff\n> and status do.\n> \n> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n> but didn't allow to override it from command line.\n> \n> This patch depends on Jens Lehmann's patch \"commit -m: commit staged\n> submodules regardless of ignore config\". Without it,\n> \"commit -m --ignore-submodules\" would not work and tests introduced\n> here would fail.\n\nApart from the flags of the test (see below) I get three failures when\nrunning t7513. And I'm wondering why you are using \"test_might_fail\"\nthere, shouldn't we know exactly if a commit should succeed or not\nand test exactly for that?\n\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n>  Documentation/git-commit.txt        |  7 ++++\n>  builtin/commit.c                    |  8 +++-\n>  t/t7513-commit-ignore-submodules.sh | 78 +++++++++++++++++++++++++++++++++++++\n>  3 files changed, 92 insertions(+), 1 deletion(-)\n>  create mode 100644 t/t7513-commit-ignore-submodules.sh\n> \n> diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\n> index 0bbc8f5..de0e8fe 100644\n> --- a/Documentation/git-commit.txt\n> +++ b/Documentation/git-commit.txt\n> @@ -13,6 +13,7 @@ SYNOPSIS\n>  \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n>  \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n>  \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n> +\t   [--ignore-submodules[=<when>]]\n>  \t   [-i | -o] [-S[<key-id>]] [--] [<file>...]\n>  \n>  DESCRIPTION\n> @@ -277,6 +278,12 @@ The possible options are:\n>  The default can be changed using the status.showUntrackedFiles\n>  configuration variable documented in linkgit:git-config[1].\n>  \n> +--ignore-submodules[=<when>]::\n> +\tCan be used to override any settings of the 'submodule.*.ignore'\n> +\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n> +\t<when> can be either \"none\", \"dirty, \"untracked\" or \"all\", which\n> +\tis the default.\n> +\n>  -v::\n>  --verbose::\n>  \tShow unified diff between the HEAD commit and what\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index a148e28..8c4d05e 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n>  \t */\n>  \tif (all || (also && pathspec.nr)) {\n>  \t\tfd = hold_locked_index(&index_lock, 1);\n> -\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n> +\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n>  \t\trefresh_cache_or_die(refresh_flags);\n>  \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n>  \t\tif (write_cache(fd, active_cache, active_nr) ||\n> @@ -1526,6 +1526,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n>  \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n>  \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n> +\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n> +\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n> +\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n>  \t\t/* end commit contents options */\n>  \n>  \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n> @@ -1564,6 +1567,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>  \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n>  \t\t\t\t\t  builtin_commit_usage,\n>  \t\t\t\t\t  prefix, current_head, &s);\n> +\n> +\ts.ignore_submodule_arg = ignore_submodule_arg;\n> +\n>  \tif (dry_run)\n>  \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n>  \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\n> diff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\n> new file mode 100644\n\nFlags: 100755\n\n> index 0000000..52ab37d\n> --- /dev/null\n> +++ b/t/t7513-commit-ignore-submodules.sh\n> @@ -0,0 +1,78 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2014 Ronald Weiss\n> +#\n> +\n> +test_description='Test of git commit --ignore-submodules'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'create submodule' '\n> +\ttest_create_repo sm && (\n> +\t\tcd sm &&\n> +\t\t>foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Add foo\"\n> +\t) &&\n> +\tgit submodule add ./sm &&\n> +\tgit commit -m \"Add sm\"\n> +'\n> +\n> +update_sm () {\n> +\t(cd sm &&\n> +\t\techo bar >> foo &&\n> +\t\tgit add foo &&\n> +\t\tgit commit -m \"Updated foo\"\n> +\t)\n> +}\n> +\n> +test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n> +\tupdate_sm &&\n> +\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n> +'\n> +\n> +test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n> +\tupdate_sm &&\n> +\tgit config submodule.sm.ignore all &&\n> +\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n> +\tgit diff --exit-code --ignore-submodules=none &&\n> +\tgit diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_expect_success 'commit --ignore-submodules status of submodule with untracked content' '\n> +\tGIT_EDITOR=cat &&\n> +\texport GIT_EDITOR &&\n> +\techo untracked > sm/untracked &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=none > output &&\n> +\ttest_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=untracked > output &&\n> +\ttest_must_fail test_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=dirty > output &&\n> +\ttest_must_fail test_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=all > output &&\n> +\ttest_must_fail test_i18ngrep modified output\n> +'\n> +\n> +test_expect_success 'commit --ignore-submodules status of dirty submodule' '\n> +\tGIT_EDITOR=cat &&\n> +\texport GIT_EDITOR &&\n> +\techo dirty > sm/foo &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=none > output &&\n> +\ttest_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=untracked > output &&\n> +\ttest_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=dirty > output &&\n> +\ttest_must_fail test_i18ngrep modified output &&\n> +\n> +\ttest_might_fail git commit --ignore-submodules=all > output &&\n> +\ttest_must_fail test_i18ngrep modified output\n> +'\n> +\n> +test_done\n> \n"},{"id":"239065","messageId":"53511A59.6000402@web.de","threadId":"36308","inReplyTo":"5349CF3E.7010606@gmail.com","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-18T12:28:09Z","receivedAt":"2014-04-18T12:28:09Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 13.04.2014 01:41, schrieb Ronald Weiss:\n> On 8. 4. 2014 20:26, Jens Lehmann wrote:\n>> Am 07.04.2014 23:46, schrieb Ronald Weiss:\n>>> Then, on top of that, I'll prepare patches for add to honor ignore\n>>> from .gitmodules, and -f implying --ignore-submodules. That might need\n>>> more discussion, let's see.\n>>\n>> Makes sense.\n> \n> I thought more about that, and also played with the code a bit.\n> \n> First, I was confused when I wrote that git add doesn't honor\n> submodules' ignore setting only from .gitmodules, but it does from\n> .git/config. It doesn't, from neither. Sorry for the confusion. However,\n> that doesn't change anything on the fact that it would be nice if add\n> would honor the ignore setting, from both places.\n\nOk, thanks for digging deeper here.\n\n> Second, there are some differences between adding standard ignored\n> files, and ignored submodules:\n> \n> 1) Already tracked files are never ignored, regardless of .gitignore.\n>  However, tracked submodules should be ignored by \"add -u\", if told so\n>  by their ignore setting.\n> \n> 2) So .gitignore seems to only do something when adding new files to\n>  the repo. However, when adding new submodules, they are probably never\n>  ignored (setting the ignore setting for non existent submodule seems\n>  like non-sense, although possible).\n\nWhat about \"diff.ignoreSubmodules=all\"?\n\n> 3) Ignored files can be ignored less explicitely (in global gitignore,\n>  or using a wildcard, or by ignoring parent folder). So it makes sense\n>  to warn the user if he tries to explicitely add an ignored file, as he\n>  might not be aware that the file is ignored. Submodules, however, can\n>  only be ignored explicitely. And when user explicitely specifies the\n>  submodule in an add command, he most probably really wants to add it,\n>  so I don't see the point in warning him and requiring the -f option.\n\nBut we do have \"diff.ignoreSubmodules=all\", so I do not agree with\nyour conclusion.\n\n> So, I think that the use cases are completely different, for submodules\n> and ignored files. So trying to make add behave the same for both, might\n> not be that good idea.\n> \n> I would propose - let's make add honor the ignore setting by just\n> parsing if from config like the other commands do, and pass it to\n> underlying diff invocations. And at the same the, let's override it for\n> submodules explicitely specified on the command line, to never ignore\n> such submodules, without requiring the -f option. That seems to be\n> pretty easy, see below.\n\nWhat about doing that only when '-f' is given? Would that do what we\nwant?\n\n> diff --git a/builtin/add.c b/builtin/add.c\n> index 85f2110..f19e6c8 100644\n> --- a/builtin/add.c\n> +++ b/builtin/add.c\n> @@ -284,6 +284,10 @@ static int add_config(const char *var, const char *value, void *cb)\n>  \t\tignore_add_errors = git_config_bool(var, value);\n>  \t\treturn 0;\n>  \t}\n> +\n> +\tif (starts_with(var, \"submodule.\"))\n> +\t\treturn parse_submodule_config_option(var, value);\n> +\n>  \treturn git_default_config(var, value, cb);\n>  }\n>  \n> @@ -320,6 +324,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \tchar *seen = NULL;\n>  \n>  \tgit_config(add_config, NULL);\n> +\tgitmodules_config();\n\nWrong order, gitmodules_config() must be called before git_config()\nto make the .gitmodules settings overridable by the users config.\n\n>  \targc = parse_options(argc, argv, prefix, builtin_add_options,\n>  \t\t\t  builtin_add_usage, PARSE_OPT_KEEP_ARGV0);\n> @@ -425,6 +430,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\t\t       PATHSPEC_EXCLUDE);\n>  \n>  \t\tfor (i = 0; i < pathspec.nr; i++) {\n> +\t\t\tint cachepos;\n>  \t\t\tconst char *path = pathspec.items[i].match;\n>  \t\t\tif (pathspec.items[i].magic & PATHSPEC_EXCLUDE)\n>  \t\t\t\tcontinue;\n> @@ -440,6 +446,18 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>  \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n>  \t\t\t\t\t    pathspec.items[i].original);\n>  \t\t\t}\n> +\n> +\t\t\t/* disable ignore setting for any submodules specified explicitly in the pathspec */\n> +\t\t\tif (path[0] &&\n> +\t\t\t\t(cachepos = cache_name_pos(path, pathspec.items[i].len)) >= 0 &&\n> +\t\t\t\tS_ISGITLINK(active_cache[cachepos]->ce_mode)) {\n> +\t\t\t\tchar *optname;\n> +\t\t\t\tint optnamelen = pathspec.items[i].len + 17;\n> +\t\t\t\toptname = xcalloc(optnamelen + 1, 1);\n> +\t\t\t\tsnprintf(optname, optnamelen + 1, \"submodule.%s.ignore\", path);\n> +\t\t\t\tparse_submodule_config_option(optname, \"none\");\n\nWe should use \"dirty\" instead of \"none\" here. Modifications inside\nthe submodule cannot be added without committing them there first\nand using \"none\" might incur an extra preformance penalty for\nlooking through the submodule directories for such changes.\n\n> +\t\t\t\tfree(optname);\n> +\t\t\t}\n>  \t\t}\n>  \t\tfree(seen);\n>  \t}\n> --  \n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n> \n"},{"id":"239239","messageId":"53558B66.3080602@gmail.com","threadId":"36308","inReplyTo":"5351123A.9060201@web.de","subject":"Re: [PATCH v4 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-21T21:19:34Z","receivedAt":"2014-04-21T21:19:34Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 18. 4. 2014 13:53, Jens Lehmann wrote:\n> Am 13.04.2014 00:45, schrieb Ronald Weiss:\n>> Allow ignoring submodules (or not) by command line switch, like diff\n>> and status do.\n>>\n>> Git add currently doesn't honor ignore from .gitmodules or .git/config,\n>> which is related functionality, however I'd like to change that in\n>> another patch, coming soon.\n> \n> I think we should drop this paragraph from this commit message. Though\n> I believe it's helpful to add this information after the \"---\" below\n> to inform readers of the list of your future plans.\n> \n>> This commit is also a prerequisite for the next one in series, which\n>> adds the --ignore-submodules switch to git commit.\n> \n> But this information definitely belongs here.\n> \n>> That's why signature\n>> of function add_files_to_cache was changed.\n> \n> But that's necessary for this patch too, no?\n\nNo, for this patch alone, we could just use the global variable, which\nis set up by parse_options(), without changing the public function and\nbreaking compilation in other files.\n\n> \n>> That also requires compilo fixes in checkout.c and commit.c\n> \n> Sorry, but I don't know what a \"compilo fix\" is ;-) .. I suspect you\n> mean that add_files_to_cache() needs a new NULL argument in some\n> places. What about dropping the last two sentences and adding\n> something like \"Add a new argument to add_files_to_cache() to pass\n> the command line option and update all other call sites to pass\n> NULL instead.\" to the first paragraph?\n> \n> Apart from that and the flags of the test (see below) this patch\n> is looking good to me.\n\nOK, I'll update the commit message, and fix the file mode for the added\ntest script. Will repost once we sort out the problems (failing tests)\nYou have with the second patch (for commit).\n\n>> diff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\n>> new file mode 100644\n> \n> The flags should be 100755 here, currently \"make test\" fails because\n> of this.\n\nI'm sorry for this, I was testing it on Windows, where the file mode\ndoesn't matter, that's why I missed it.\n"},{"id":"239252","messageId":"535596D1.6070709@gmail.com","threadId":"36308","inReplyTo":"53511617.80506@web.de","subject":"Re: [PATCH v4 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-21T22:08:17Z","receivedAt":"2014-04-21T22:08:17Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 18. 4. 2014 14:09, Jens Lehmann wrote:\n> Am 13.04.2014 00:49, schrieb Ronald Weiss:\n>> Allow ignoring submodules (or not) by command line switch, like diff\n>> and status do.\n>>\n>> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n>> but didn't allow to override it from command line.\n>>\n>> This patch depends on Jens Lehmann's patch \"commit -m: commit staged\n>> submodules regardless of ignore config\". Without it,\n>> \"commit -m --ignore-submodules\" would not work and tests introduced\n>> here would fail.\n> \n> Apart from the flags of the test (see below) I get three failures when\n> running t7513. And I'm wondering why you are using \"test_might_fail\"\n> there, shouldn't we know exactly if a commit should succeed or not\n> and test exactly for that?\n\nI used \"test_might_fail\" instead of \"test_must_fail\" to denote that this\ntest doesn't care whether \"git commit\" fails or not due to empty commit\nmessage. I found it more appropriate. However, if you disagree, I can\nchange it to \"test_must_fail\", no problem for me.\n\nUnfortunately I don't know why the test fails for you, they pass for me.\nDid you apply it on top of your own patch for \"commit -m\", which is\na prerequisite?\n\nI tried it again, on top of current master (cc29195 [tag: v2.0.0-rc0]).\nFirst, I have applied your patch from here:\n\nhttp://article.gmane.org/gmane.comp.version-control.git/245783\n\nOn top of that, I applied my two patches, and the tests pass fine here.\nUntil now I was testing on Windows, but now I tested on a Linux box,\nand that makes no difference.\n"},{"id":"239369","messageId":"5356BF7C.1010200@web.de","threadId":"36308","inReplyTo":"535596D1.6070709@gmail.com","subject":"Re: [PATCH v4 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2014-04-22T19:14:04Z","receivedAt":"2014-04-22T19:14:04Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 22.04.2014 00:08, schrieb Ronald Weiss:\n> On 18. 4. 2014 14:09, Jens Lehmann wrote:\n>> Am 13.04.2014 00:49, schrieb Ronald Weiss:\n>>> Allow ignoring submodules (or not) by command line switch, like diff\n>>> and status do.\n>>>\n>>> Git commit honors the 'ignore' setting from .gitmodules or .git/config,\n>>> but didn't allow to override it from command line.\n>>>\n>>> This patch depends on Jens Lehmann's patch \"commit -m: commit staged\n>>> submodules regardless of ignore config\". Without it,\n>>> \"commit -m --ignore-submodules\" would not work and tests introduced\n>>> here would fail.\n>>\n>> Apart from the flags of the test (see below) I get three failures when\n>> running t7513. And I'm wondering why you are using \"test_might_fail\"\n>> there, shouldn't we know exactly if a commit should succeed or not\n>> and test exactly for that?\n> \n> I used \"test_might_fail\" instead of \"test_must_fail\" to denote that this\n> test doesn't care whether \"git commit\" fails or not due to empty commit\n> message. I found it more appropriate. However, if you disagree, I can\n> change it to \"test_must_fail\", no problem for me.\n\nI'd rather have them fail because nothing is to be committed (and not\nbecause the commit message is empty) and document we expect that to\nhappen by using test_must_fail (and that for example will catch a later\nchange which accidentally makes commit create empty commits here).\n\n> Unfortunately I don't know why the test fails for you, they pass for me.\n> Did you apply it on top of your own patch for \"commit -m\", which is\n> a prerequisite?\n\nSilly me, I forgot to do that (even though you explicitly mention\nthis dependency in the commit message). Sorry for the noise, all\ntests run fine after rebasing your changes on top of mine.\n\n> I tried it again, on top of current master (cc29195 [tag: v2.0.0-rc0]).\n> First, I have applied your patch from here:\n> \n> http://article.gmane.org/gmane.comp.version-control.git/245783\n> \n> On top of that, I applied my two patches, and the tests pass fine here.\n> Until now I was testing on Windows, but now I tested on a Linux box,\n> and that makes no difference.\n> \n"},{"id":"239383","messageId":"5356DB37.8020209@gmail.com","threadId":"36308","inReplyTo":"5356BF7C.1010200@web.de","subject":"[PATCH v5 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-22T21:12:23Z","receivedAt":"2014-04-22T21:12:23Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nThis commit is also a prerequisite for the next one in series, which\nadds the --ignore-submodules switch to git commit. That's why a new\nargument is added to public function add_files_to_cache(), and it's\ncall sites are updated to pass NULL.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nGit add currently doesn't honor ignore setting from .gitmodules or\n.git/config, which is related functionality, however I'd like to\nchange that in another patch, coming soon.\n\nChanges against v4 of this patch:\n* fixed file mode of added test script (644 -> 755)\n* cleaned up commit message\n\n Documentation/git-add.txt        |  7 ++++++-\n builtin/add.c                    | 16 ++++++++++++--\n builtin/checkout.c               |  2 +-\n builtin/commit.c                 |  2 +-\n cache.h                          |  2 +-\n t/t3704-add-ignore-submodules.sh | 45 ++++++++++++++++++++++++++++++++++++++++\n 6 files changed, 68 insertions(+), 6 deletions(-)\n create mode 100755 t/t3704-add-ignore-submodules.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 9631526..b2c936f 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -11,7 +11,7 @@ SYNOPSIS\n 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n \t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n-\t  [--] [<pathspec>...]\n+\t  [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -164,6 +164,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n \tbe ignored, no matter if they are already present in the work\n \ttree or not.\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", which is the default.\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 459208a..85f2110 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -83,7 +83,8 @@ static void update_callback(struct diff_queue_struct *q,\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \tstruct rev_info rev;\n@@ -99,6 +100,12 @@ int add_files_to_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = &data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n \treturn !!data.add_errors;\n }\n@@ -237,6 +244,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n static int addremove = ADDREMOVE_DEFAULT;\n static int addremove_explicit = -1; /* unspecified */\n \n+static char *ignore_submodule_arg;\n+\n static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n {\n \t/* if we are told to ignore, we are not adding removals */\n@@ -262,6 +271,9 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n \tOPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n \tOPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n+\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \tOPT_END(),\n };\n \n@@ -434,7 +446,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tplug_bulk_checkin();\n \n-\texit_status |= add_files_to_cache(prefix, &pathspec, flags);\n+\texit_status |= add_files_to_cache(prefix, &pathspec, flags, ignore_submodule_arg);\n \n \tif (add_new_files)\n \t\texit_status |= add_files(&dir, flags);\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 07cf555..607af47 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 9cfef6c..a148e28 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\ndiff --git a/cache.h b/cache.h\nindex 107ac61..a6cedc0 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1370,7 +1370,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\nnew file mode 100755\nindex 0000000..db58f0c\n--- /dev/null\n+++ b/t/t3704-add-ignore-submodules.sh\n@@ -0,0 +1,45 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git add with ignoring submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create dirty submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\" && (\n+\t\tcd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Update foo\"\n+\t)\n+'\n+\n+test_expect_success 'add --ignore-submodules ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=all ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules=all &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n+\tgit reset &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit add -u --ignore-submodules=none &&\n+\ttest_must_fail git diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n1.9.1.3.g7790cde.dirty \n"},{"id":"239384","messageId":"5356DB76.50602@gmail.com","threadId":"36308","inReplyTo":"5356BF7C.1010200@web.de","subject":"[PATCH v5 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-22T21:13:26Z","receivedAt":"2014-04-22T21:13:26Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nGit commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line.\n\nThis patch depends on Jens Lehmann's patch \"commit -m: commit staged\nsubmodules regardless of ignore config\". Without it,\n\"commit -m --ignore-submodules\" would not work and tests introduced\nhere would fail.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nChanges against v4 of this patch:\n* fixed file mode of added test script (644 -> 755)\n* replaced test_might_fail with test_must_fail in test script\n\n Documentation/git-commit.txt        |  7 ++++\n builtin/commit.c                    |  8 +++-\n t/t7513-commit-ignore-submodules.sh | 78 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 92 insertions(+), 1 deletion(-)\n create mode 100755 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 0bbc8f5..de0e8fe 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<key-id>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -277,6 +278,12 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\", \"dirty, \"untracked\" or \"all\", which\n+\tis the default.\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex a148e28..8c4d05e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -1526,6 +1526,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1564,6 +1567,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100755\nindex 0000000..52ab37d\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,78 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm && (\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(cd sm &&\n+\t\techo bar >> foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n+\tgit diff --exit-code --ignore-submodules=none &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of submodule with untracked content' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo untracked > sm/untracked &&\n+\n+\ttest_must_fail git commit --ignore-submodules=none > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=untracked > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=dirty > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=all > output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of dirty submodule' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo dirty >> sm/foo &&\n+\n+\ttest_must_fail git commit --ignore-submodules=none > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=untracked > output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=dirty > output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=all > output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_done\n-- \n1.9.1.3.g7790cde.dirty \n"},{"id":"239392","messageId":"5356EB5D.2030503@gmail.com","threadId":"36308","inReplyTo":"53511A59.6000402@web.de","subject":"Re: [PATCH v2.1] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-22T22:21:17Z","receivedAt":"2014-04-22T22:21:17Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"On 18. 4. 2014 14:28, Jens Lehmann wrote:\n> Am 13.04.2014 01:41, schrieb Ronald Weiss:\n>> Second, there are some differences between adding standard ignored\n>> files, and ignored submodules:\n>>\n>> 1) Already tracked files are never ignored, regardless of .gitignore.\n>>   However, tracked submodules should be ignored by \"add -u\", if told so\n>>   by their ignore setting.\n>>\n>> 2) So .gitignore seems to only do something when adding new files to\n>>   the repo. However, when adding new submodules, they are probably never\n>>   ignored (setting the ignore setting for non existent submodule seems\n>>   like non-sense, although possible).\n> \n> What about \"diff.ignoreSubmodules=all\"?\n> \n>> 3) Ignored files can be ignored less explicitely (in global gitignore,\n>>   or using a wildcard, or by ignoring parent folder). So it makes sense\n>>   to warn the user if he tries to explicitely add an ignored file, as he\n>>   might not be aware that the file is ignored. Submodules, however, can\n>>   only be ignored explicitely. And when user explicitely specifies the\n>>   submodule in an add command, he most probably really wants to add it,\n>>   so I don't see the point in warning him and requiring the -f option.\n> \n> But we do have \"diff.ignoreSubmodules=all\", so I do not agree with\n> your conclusion.\n\nAh, I didn't know about diff.ignoreSubmodules. I agree that it defeats\ntwo of my points :-(.\n\nAnd how about the point 1), should submodules never be ignored once\nalready tracked, like standard ignored files? I'm almost sure that in\nthis case the behavior should be different, otherwise it would drop\nthe most useful use case of the proposed change.\n\n>> So, I think that the use cases are completely different, for submodules\n>> and ignored files. So trying to make add behave the same for both, might\n>> not be that good idea.\n>>\n>> I would propose - let's make add honor the ignore setting by just\n>> parsing if from config like the other commands do, and pass it to\n>> underlying diff invocations. And at the same the, let's override it for\n>> submodules explicitely specified on the command line, to never ignore\n>> such submodules, without requiring the -f option. That seems to be\n>> pretty easy, see below.\n> \n> What about doing that only when '-f' is given? Would that do what we\n> want?\n\nOK then, seems right with diff.ignoreSubmodules in mind.\n\nBut one question stays - what to do with submodules not explicitly\nspecified on command line (when their parent folder is being added)?\nYou adviced already to do what we do with standard ignored files. That\nseems to be:\n\nA) if the file is already tracked, add it\nB) if not tracked, without -f, silently ignore it\nC) if not tracked, with -f, add it\n\nA) is same like point 1 above, let's forget it until we settle that one.\nBut B) is even more problematic, we would probably have to modify the\ndirectory parsing code in dir.c to handle ignored submodules. Is that\nwhat we want? If so, then I'm afraid this is getting overly complicated.\n\n>> @@ -320,6 +324,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>>   \tchar *seen = NULL;\n>>   \n>>   \tgit_config(add_config, NULL);\n>> +\tgitmodules_config();\n> \n> Wrong order, gitmodules_config() must be called before git_config()\n> to make the .gitmodules settings overridable by the users config.\n\nRight. I noticed that too just after sending the patch.\n\n>> @@ -440,6 +446,18 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n>>   \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n>>   \t\t\t\t\t    pathspec.items[i].original);\n>>   \t\t\t}\n>> +\n>> +\t\t\t/* disable ignore setting for any submodules specified explicitly in the pathspec */\n>> +\t\t\tif (path[0] &&\n>> +\t\t\t\t(cachepos = cache_name_pos(path, pathspec.items[i].len)) >= 0 &&\n>> +\t\t\t\tS_ISGITLINK(active_cache[cachepos]->ce_mode)) {\n>> +\t\t\t\tchar *optname;\n>> +\t\t\t\tint optnamelen = pathspec.items[i].len + 17;\n>> +\t\t\t\toptname = xcalloc(optnamelen + 1, 1);\n>> +\t\t\t\tsnprintf(optname, optnamelen + 1, \"submodule.%s.ignore\", path);\n>> +\t\t\t\tparse_submodule_config_option(optname, \"none\");\n> \n> We should use \"dirty\" instead of \"none\" here. Modifications inside\n> the submodule cannot be added without committing them there first\n> and using \"none\" might incur an extra preformance penalty for\n> looking through the submodule directories for such changes.\n\nOK, that's right too.\n"},{"id":"239485","messageId":"CAPig+cTyANC34jbeH1EzaWsJMnVemjSGEDB8b2s9VuRqAYwMng@mail.gmail.com","threadId":"36308","inReplyTo":"5356DB37.8020209@gmail.com","subject":"Re: [PATCH v5 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2014-04-23T20:25:05Z","receivedAt":"2014-04-23T20:25:05Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Apr 22, 2014 at 5:12 PM, Ronald Weiss <weiss.ronald@gmail.com> wrote:\n> Allow ignoring submodules (or not) by command line switch, like diff\n> and status do.\n>\n> This commit is also a prerequisite for the next one in series, which\n> adds the --ignore-submodules switch to git commit. That's why a new\n> argument is added to public function add_files_to_cache(), and it's\n\ns/it's/its/\n\n> call sites are updated to pass NULL.\n>\n> Signed-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n> ---\n> diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\n> index 9631526..b2c936f 100644\n> --- a/Documentation/git-add.txt\n> +++ b/Documentation/git-add.txt\n> @@ -11,7 +11,7 @@ SYNOPSIS\n>  'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n>           [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n>           [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n> -         [--] [<pathspec>...]\n> +         [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n>\n>  DESCRIPTION\n>  -----------\n> @@ -164,6 +164,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n>         be ignored, no matter if they are already present in the work\n>         tree or not.\n>\n> +--ignore-submodules[=<when>]::\n> +       Can be used to override any settings of the 'submodule.*.ignore'\n> +       option in linkgit:git-config[1] or linkgit:gitmodules[5].\n> +       <when> can be either \"none\" or \"all\", which is the default.\n\nThe \"which is the default\" clause reads ambiguously. It's not clear\nwhether you mean \"none\" is the default or \"all\" is the default.\n\n>  \\--::\n>         This option can be used to separate command-line options from\n>         the list of files, (useful when filenames might be mistaken\n> diff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\n> new file mode 100755\n> index 0000000..db58f0c\n> --- /dev/null\n> +++ b/t/t3704-add-ignore-submodules.sh\n> @@ -0,0 +1,45 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) 2014 Ronald Weiss\n> +#\n> +\n> +test_description='Test of git add with ignoring submodules'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'create dirty submodule' '\n> +       test_create_repo sm && (\n\nIt's conventional for the opening '(' to be placed on a line by itself.\n\n> +               cd sm &&\n> +               >foo &&\n> +               git add foo &&\n> +               git commit -m \"Add foo\"\n> +       ) &&\n> +       git submodule add ./sm &&\n> +       git commit -m \"Add sm\" && (\n> +               cd sm &&\n> +               echo bar >> foo &&\n\ns/>> />>/\n\n> +               git add foo &&\n> +               git commit -m \"Update foo\"\n> +       )\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules ignores submodule' '\n> +       git reset &&\n> +       git add -u --ignore-submodules &&\n> +       git diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules=all ignores submodule' '\n> +       git reset &&\n> +       git add -u --ignore-submodules=all &&\n> +       git diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n> +       git reset &&\n> +       git config submodule.sm.ignore all &&\n> +       git add -u --ignore-submodules=none &&\n> +       test_must_fail git diff --cached --exit-code --ignore-submodules=none\n> +'\n> +\n> +test_done\n> --\n> 1.9.1.3.g7790cde.dirty\n"},{"id":"239601","messageId":"53596756.7020306@gmail.com","threadId":"36308","inReplyTo":"CAPig+cTyANC34jbeH1EzaWsJMnVemjSGEDB8b2s9VuRqAYwMng@mail.gmail.com","subject":"[PATCH v6 1/2] add: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-24T19:34:46Z","receivedAt":"2014-04-24T19:34:46Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nThis commit is also a prerequisite for the next one in series, which\nadds the --ignore-submodules switch to git commit. That's why a new\nargument is added to public function add_files_to_cache(), and its\ncall sites are updated to pass NULL.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nGit add currently doesn't honor ignore setting from .gitmodules or\n.git/config, which is related functionality, however I'd like to\nchange that in another patch, coming soon.\n\nPatch changelog:\nv6\n* corrected wording and formatting errors (as pointed out by Eric Sunshine)\nv5\n* fixed file mode of added test script (644 -> 755)\n* cleaned up commit message\n\n Documentation/git-add.txt        |  7 +++++-\n builtin/add.c                    | 16 ++++++++++++--\n builtin/checkout.c               |  2 +-\n builtin/commit.c                 |  2 +-\n cache.h                          |  2 +-\n t/t3704-add-ignore-submodules.sh | 47 ++++++++++++++++++++++++++++++++++++++++\n 6 files changed, 70 insertions(+), 6 deletions(-)\n create mode 100755 t/t3704-add-ignore-submodules.sh\n\ndiff --git a/Documentation/git-add.txt b/Documentation/git-add.txt\nindex 9631526..ef69f8b 100644\n--- a/Documentation/git-add.txt\n+++ b/Documentation/git-add.txt\n@@ -11,7 +11,7 @@ SYNOPSIS\n 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]\n \t  [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]\n \t  [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]\n-\t  [--] [<pathspec>...]\n+\t  [--ignore-submodules[=<when>]] [--] [<pathspec>...]\n \n DESCRIPTION\n -----------\n@@ -164,6 +164,11 @@ for \"git add --no-all <pathspec>...\", i.e. ignored removed files.\n \tbe ignored, no matter if they are already present in the work\n \ttree or not.\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\" or \"all\", defaulting to \"all\".\n+\n \\--::\n \tThis option can be used to separate command-line options from\n \tthe list of files, (useful when filenames might be mistaken\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 459208a..85f2110 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -83,7 +83,8 @@ static void update_callback(struct diff_queue_struct *q,\n }\n \n int add_files_to_cache(const char *prefix,\n-\t\t       const struct pathspec *pathspec, int flags)\n+\t\t       const struct pathspec *pathspec, int flags,\n+\t\t       const char *ignore_submodules_arg)\n {\n \tstruct update_callback_data data;\n \tstruct rev_info rev;\n@@ -99,6 +100,12 @@ int add_files_to_cache(const char *prefix,\n \trev.diffopt.format_callback = update_callback;\n \trev.diffopt.format_callback_data = &data;\n \trev.max_count = 0; /* do not compare unmerged paths with stage #2 */\n+\n+\tif (ignore_submodules_arg) {\n+\t\tDIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);\n+\t\thandle_ignore_submodules_arg(&rev.diffopt, ignore_submodules_arg);\n+\t}\n+\n \trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n \treturn !!data.add_errors;\n }\n@@ -237,6 +244,8 @@ static int ignore_add_errors, intent_to_add, ignore_missing;\n static int addremove = ADDREMOVE_DEFAULT;\n static int addremove_explicit = -1; /* unspecified */\n \n+static char *ignore_submodule_arg;\n+\n static int ignore_removal_cb(const struct option *opt, const char *arg, int unset)\n {\n \t/* if we are told to ignore, we are not adding removals */\n@@ -262,6 +271,9 @@ static struct option builtin_add_options[] = {\n \tOPT_BOOL( 0 , \"refresh\", &refresh_only, N_(\"don't add, only refresh the index\")),\n \tOPT_BOOL( 0 , \"ignore-errors\", &ignore_add_errors, N_(\"just skip files which cannot be added because of errors\")),\n \tOPT_BOOL( 0 , \"ignore-missing\", &ignore_missing, N_(\"check if - even missing - files are ignored in dry run\")),\n+\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \tOPT_END(),\n };\n \n@@ -434,7 +446,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \n \tplug_bulk_checkin();\n \n-\texit_status |= add_files_to_cache(prefix, &pathspec, flags);\n+\texit_status |= add_files_to_cache(prefix, &pathspec, flags, ignore_submodule_arg);\n \n \tif (add_new_files)\n \t\texit_status |= add_files(&dir, flags);\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 07cf555..607af47 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -525,7 +525,7 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t\t\t * entries in the index.\n \t\t\t */\n \n-\t\t\tadd_files_to_cache(NULL, NULL, 0);\n+\t\t\tadd_files_to_cache(NULL, NULL, 0, NULL);\n \t\t\t/*\n \t\t\t * NEEDSWORK: carrying over local changes\n \t\t\t * when branches have different end-of-line\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 0ad4d0b..5444111 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\ndiff --git a/cache.h b/cache.h\nindex 107ac61..a6cedc0 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1370,7 +1370,7 @@ void packet_trace_identity(const char *prog);\n  * return 0 if success, 1 - if addition of a file failed and\n  * ADD_FILES_IGNORE_ERRORS was specified in flags\n  */\n-int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags);\n+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, const char *ignore_submodules_arg);\n \n /* diff.c */\n extern int diff_auto_refresh_index;\ndiff --git a/t/t3704-add-ignore-submodules.sh b/t/t3704-add-ignore-submodules.sh\nnew file mode 100755\nindex 0000000..a6d8517\n--- /dev/null\n+++ b/t/t3704-add-ignore-submodules.sh\n@@ -0,0 +1,47 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git add with ignoring submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create dirty submodule' '\n+\ttest_create_repo sm &&\n+\t(\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\" &&\n+\t(\n+\t\tcd sm &&\n+\t\techo bar >>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Update foo\"\n+\t)\n+'\n+\n+test_expect_success 'add --ignore-submodules ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=all ignores submodule' '\n+\tgit reset &&\n+\tgit add -u --ignore-submodules=all &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'add --ignore-submodules=none overrides ignore=all from config' '\n+\tgit reset &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit add -u --ignore-submodules=none &&\n+\ttest_must_fail git diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_done\n-- \n2.0.0.rc0.3.gd50de04 \n"},{"id":"239602","messageId":"53596941.5050207@gmail.com","threadId":"36308","inReplyTo":"53596756.7020306@gmail.com","subject":"[PATCH v6 2/2] commit: add --ignore-submodules[=<when>] parameter","fromName":"Ronald Weiss","fromEmail":"weiss.ronald@gmail.com","sentAt":"2014-04-24T19:42:57Z","receivedAt":"2014-04-24T19:42:57Z","isPatch":true,"sender":{"key":"weiss.ronald@gmail.com","avatar":null},"body":"Allow ignoring submodules (or not) by command line switch, like diff\nand status do.\n\nGit commit honors the 'ignore' setting from .gitmodules or .git/config,\nbut didn't allow to override it from command line.\n\nThis patch depends on Jens Lehmann's patch \"commit -m: commit staged\nsubmodules regardless of ignore config\". Without it,\n\"commit -m --ignore-submodules\" would not work and tests introduced\nhere would fail.\n\nSigned-off-by: Ronald Weiss <weiss.ronald@gmail.com>\n---\nPatch changelog:\nv6\n* corrected wording and formatting errors (as pointed out by Eric Sunshine)\nv5\n* fixed file mode of added test script (644 -> 755)\n* replaced test_might_fail with test_must_fail in test script\n\n Documentation/git-commit.txt        |  7 ++++\n builtin/commit.c                    |  8 +++-\n t/t7513-commit-ignore-submodules.sh | 80 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 94 insertions(+), 1 deletion(-)\n create mode 100755 t/t7513-commit-ignore-submodules.sh\n\ndiff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt\nindex 0bbc8f5..55995be 100644\n--- a/Documentation/git-commit.txt\n+++ b/Documentation/git-commit.txt\n@@ -13,6 +13,7 @@ SYNOPSIS\n \t   [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n \t   [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n \t   [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n+\t   [--ignore-submodules[=<when>]]\n \t   [-i | -o] [-S[<key-id>]] [--] [<file>...]\n \n DESCRIPTION\n@@ -277,6 +278,12 @@ The possible options are:\n The default can be changed using the status.showUntrackedFiles\n configuration variable documented in linkgit:git-config[1].\n \n+--ignore-submodules[=<when>]::\n+\tCan be used to override any settings of the 'submodule.*.ignore'\n+\toption in linkgit:git-config[1] or linkgit:gitmodules[5].\n+\t<when> can be either \"none\", \"dirty, \"untracked\" or \"all\",\n+\tdefaulting to \"all\".\n+\n -v::\n --verbose::\n \tShow unified diff between the HEAD commit and what\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 5444111..dc1d8d0 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -361,7 +361,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,\n \t */\n \tif (all || (also && pathspec.nr)) {\n \t\tfd = hold_locked_index(&index_lock, 1);\n-\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, NULL);\n+\t\tadd_files_to_cache(also ? prefix : NULL, &pathspec, 0, ignore_submodule_arg);\n \t\trefresh_cache_or_die(refresh_flags);\n \t\tupdate_main_cache_tree(WRITE_TREE_SILENT);\n \t\tif (write_cache(fd, active_cache, active_nr) ||\n@@ -1540,6 +1540,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"amend\", &amend, N_(\"amend previous commit\")),\n \t\tOPT_BOOL(0, \"no-post-rewrite\", &no_post_rewrite, N_(\"bypass post-rewrite hook\")),\n \t\t{ OPTION_STRING, 'u', \"untracked-files\", &untracked_files_arg, N_(\"mode\"), N_(\"show untracked files, optional modes: all, normal, no. (Default: all)\"), PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n+\t\t{ OPTION_STRING, 0, \"ignore-submodules\", &ignore_submodule_arg, N_(\"when\"),\n+\t\t  N_(\"ignore changes to submodules, optional when: all, none. (Default: all)\"),\n+\t\t  PARSE_OPT_OPTARG, NULL, (intptr_t)\"all\" },\n \t\t/* end commit contents options */\n \n \t\tOPT_HIDDEN_BOOL(0, \"allow-empty\", &allow_empty,\n@@ -1578,6 +1581,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \targc = parse_and_validate_options(argc, argv, builtin_commit_options,\n \t\t\t\t\t  builtin_commit_usage,\n \t\t\t\t\t  prefix, current_head, &s);\n+\n+\ts.ignore_submodule_arg = ignore_submodule_arg;\n+\n \tif (dry_run)\n \t\treturn dry_run_commit(argc, argv, prefix, current_head, &s);\n \tindex_file = prepare_index(argc, argv, prefix, current_head, 0);\ndiff --git a/t/t7513-commit-ignore-submodules.sh b/t/t7513-commit-ignore-submodules.sh\nnew file mode 100755\nindex 0000000..10ae178\n--- /dev/null\n+++ b/t/t7513-commit-ignore-submodules.sh\n@@ -0,0 +1,80 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2014 Ronald Weiss\n+#\n+\n+test_description='Test of git commit --ignore-submodules'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'create submodule' '\n+\ttest_create_repo sm &&\n+\t(\n+\t\tcd sm &&\n+\t\t>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Add foo\"\n+\t) &&\n+\tgit submodule add ./sm &&\n+\tgit commit -m \"Add sm\"\n+'\n+\n+update_sm () {\n+\t(\n+\t\tcd sm &&\n+\t\techo bar >>foo &&\n+\t\tgit add foo &&\n+\t\tgit commit -m \"Updated foo\"\n+\t)\n+}\n+\n+test_expect_success 'commit -a --ignore-submodules=all ignores dirty submodule' '\n+\tupdate_sm &&\n+\ttest_must_fail git commit -a --ignore-submodules=all -m \"Update sm\"\n+'\n+\n+test_expect_success 'commit -a --ignore-submodules=none overrides ignore=all setting' '\n+\tupdate_sm &&\n+\tgit config submodule.sm.ignore all &&\n+\tgit commit -a --ignore-submodules=none -m \"Update sm\" &&\n+\tgit diff --exit-code --ignore-submodules=none &&\n+\tgit diff --cached --exit-code --ignore-submodules=none\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of submodule with untracked content' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo untracked >sm/untracked &&\n+\n+\ttest_must_fail git commit --ignore-submodules=none >output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=untracked >output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=dirty >output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=all >output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_expect_success 'commit --ignore-submodules status of dirty submodule' '\n+\tGIT_EDITOR=cat &&\n+\texport GIT_EDITOR &&\n+\techo dirty >>sm/foo &&\n+\n+\ttest_must_fail git commit --ignore-submodules=none >output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=untracked >output &&\n+\ttest_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=dirty >output &&\n+\ttest_must_fail test_i18ngrep modified output &&\n+\n+\ttest_must_fail git commit --ignore-submodules=all >output &&\n+\ttest_must_fail test_i18ngrep modified output\n+'\n+\n+test_done\n-- \n2.0.0.rc0.3.gd50de04\n"}]}