{"thread":{"id":"13078","subject":"[PATCH v3 0/4] builtin-status: submodule summary support","startedAt":"2008-04-12T15:05:29Z","lastAt":"2008-04-13T19:14:55Z","messageCount":11,"participants":["Ping Yin","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":4},"messages":[{"id":"74204","messageId":"1208012733-18211-1-git-send-email-pkufranky@gmail.com","threadId":"13078","inReplyTo":null,"subject":"[PATCH v3 0/4] builtin-status: submodule summary support","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:05:29Z","receivedAt":"2008-04-12T15:05:29Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"The 2nd patch of v2 are splitted to 2 patches in v3 (the 1st and 3rd one)\nto support bool/int behaviour of status.submodulesummary.\n\nThe other 2 patches are the same as v2.\n\nPing Yin (4):\n      config.c: Add git_config_bool_or_int to handle bool/int variable\n      git-submodule summary: --for-status option\n      builtin-status: submodule summary support\n      buitin-status: Add tests for submodule summary\n"},{"id":"74205","messageId":"1208012733-18211-2-git-send-email-pkufranky@gmail.com","threadId":"13078","inReplyTo":"1208012733-18211-1-git-send-email-pkufranky@gmail.com","subject":"[PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:05:30Z","receivedAt":"2008-04-12T15:05:30Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"With git_config_bool_or_int, the caller can differentiate boolean true\nand integer 1 etc.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n config.c |   15 +++++++++++++++\n 1 files changed, 15 insertions(+), 0 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex 0624494..e614456 100644\n--- a/config.c\n+++ b/config.c\n@@ -316,6 +316,21 @@ int git_config_bool(const char *name, const char *value)\n \treturn git_config_int(name, value) != 0;\n }\n \n+int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n+{\n+\t*is_bool = 1;\n+\tif (!value)\n+\t\treturn 1;\n+\tif (!*value)\n+\t\treturn 0;\n+\tif (!strcasecmp(value, \"true\") || !strcasecmp(value, \"yes\"))\n+\t\treturn 1;\n+\tif (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n+\t\treturn 0;\n+\t*is_bool = 0;\n+\treturn git_config_int(name, value);\n+}\n+\n int git_config_string(const char **dest, const char *var, const char *value)\n {\n \tif (!value)\n-- \n1.5.5.23.g2a5f\n"},{"id":"74206","messageId":"1208012733-18211-3-git-send-email-pkufranky@gmail.com","threadId":"13078","inReplyTo":"1208012733-18211-2-git-send-email-pkufranky@gmail.com","subject":"[PATCH v3 2/4] git-submodule summary: --for-status option","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:05:31Z","receivedAt":"2008-04-12T15:05:31Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"The --for-status option is mainly used by builtin-status/commit.\nIt adds 'Modified submodules:' line at top and  '# ' prefix to all\nfollowing lines.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n git-submodule.sh             |   17 ++++++++++++++++-\n t/t7401-submodule-summary.sh |   13 +++++++++++++\n 2 files changed, 29 insertions(+), 1 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 56ec353..d7937a5 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -342,6 +342,7 @@ set_name_rev () {\n #\n cmd_summary() {\n \tsummary_limit=-1\n+\tfor_status=\n \n \t# parse $args after \"submodule ... summary\".\n \twhile test $# -ne 0\n@@ -350,6 +351,9 @@ cmd_summary() {\n \t\t--cached)\n \t\t\tcached=\"$1\"\n \t\t\t;;\n+\t\t--for-status)\n+\t\t\tfor_status=\"$1\"\n+\t\t\t;;\n \t\t-n|--summary-limit)\n \t\t\tif summary_limit=$(($2 + 0)) 2>/dev/null && test \"$summary_limit\" = \"$2\"\n \t\t\tthen\n@@ -398,6 +402,12 @@ cmd_summary() {\n \t)\n \n \ttest -n \"$modules\" &&\n+\tif test -n \"$for_status\"; then\n+\t\techo \"# Modified submodules:\"\n+\t\techo \"#\"\n+\telse\n+\t\ttrue\n+\tfi &&\n \tgit diff-index $cached --raw $head -- $modules |\n \tgrep -e '^:160000' -e '^:[0-7]* 160000' |\n \tcut -c2- |\n@@ -499,7 +509,12 @@ cmd_summary() {\n \t\t\techo\n \t\tfi\n \t\techo\n-\tdone\n+\tdone |\n+\tif test -n \"$for_status\"; then\n+\t\tsed -e \"s|^|# |\" -e 's|^# $|#|'\n+\telse\n+\t\tcat\n+\tfi\n }\n #\n # List all submodules, prefixed with:\ndiff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh\nindex 0f3c42a..1dbb39d 100755\n--- a/t/t7401-submodule-summary.sh\n+++ b/t/t7401-submodule-summary.sh\n@@ -192,4 +192,17 @@ test_expect_success 'given commit' \"\n EOF\n \"\n \n+test_expect_success '--for-status' \"\n+    git submodule summary --for-status HEAD^ >actual &&\n+    diff actual - <<-EOF\n+# Modified submodules:\n+#\n+# * sm1 $head6...0000000:\n+#\n+# * sm2 0000000...$head7 (2):\n+#   > Add foo9\n+#\n+EOF\n+\"\n+\n test_done\n-- \n1.5.5.23.g2a5f\n"},{"id":"74208","messageId":"1208012733-18211-4-git-send-email-pkufranky@gmail.com","threadId":"13078","inReplyTo":"1208012733-18211-3-git-send-email-pkufranky@gmail.com","subject":"[PATCH v3 3/4] builtin-status: submodule summary support","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:05:32Z","receivedAt":"2008-04-12T15:05:32Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"This commit teaches 'git commit/status' show 'Modified submodules'\nsection given by\n\ngit submodule summary --cached --for-status --summary-limit <limit>\n\njust before 'Untracked files' section.\n\nThe <limit> is given by the config variable status.submodulesummary\nto limit the submodule summary size. status.submodulesummary is a\nbool/int variable with value\n\n  - false or 0 by default to disable the summary or\n  - positive number to limit the summary size or\n  - true or negative number to unlimit the summary size\n\nAlso mention status.submodulesummary in the documentation.\n\nSigned-off-by: Ping Yin <pkufranky@gmail.com>\n---\n Documentation/git-status.txt |    5 +++++\n wt-status.c                  |   42 ++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 47 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-status.txt b/Documentation/git-status.txt\nindex 3ea269a..ea4376a 100644\n--- a/Documentation/git-status.txt\n+++ b/Documentation/git-status.txt\n@@ -52,6 +52,11 @@ If the config variable `status.relativePaths` is set to false, then all\n paths shown are relative to the repository root, not to the current\n directory.\n \n+If `status.submodulesummary` is set to a non zero number or true (identical\n+to -1 or an unlimited number), the submodule summary will be enabled and a\n+summary of commits for modified submodules will be shown (see --summary-limit\n+option of linkgit:git-submodule[1]).\n+\n See Also\n --------\n linkgit:gitignore[5]\ndiff --git a/wt-status.c b/wt-status.c\nindex b3fd57b..3baa128 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -8,9 +8,11 @@\n #include \"revision.h\"\n #include \"diffcore.h\"\n #include \"quote.h\"\n+#include \"run-command.h\"\n \n int wt_status_relative_paths = 1;\n int wt_status_use_color = -1;\n+int wt_status_submodule_summary;\n static char wt_status_colors[][COLOR_MAXLEN] = {\n \t\"\",         /* WT_STATUS_HEADER: normal */\n \t\"\\033[32m\", /* WT_STATUS_UPDATED: green */\n@@ -219,6 +221,38 @@ static void wt_status_print_changed(struct wt_status *s)\n \trev.diffopt.format_callback_data = s;\n \trun_diff_files(&rev, 0);\n }\n+static void wt_status_print_submodule_summary(struct wt_status *s)\n+{\n+\tstruct child_process sm_summary;\n+\tchar summary_limit[64];\n+\tchar index[PATH_MAX];\n+\tconst char *env[] = { index, NULL };\n+\tconst char *argv[] = {\n+\t\t\"submodule\",\n+\t\t\"summary\",\n+\t\t\"--cached\",\n+\t\t\"--for-status\",\n+\t\t\"--summary-limit\",\n+\t\tsummary_limit,\n+\t\ts->amend ? \"HEAD^\" : \"HEAD\",\n+\t\tNULL\n+\t};\n+\n+\tif (!wt_status_submodule_summary)\n+\t\treturn;\n+\n+\tsprintf(summary_limit, \"%d\", wt_status_submodule_summary);\n+\tsnprintf(index, sizeof(index), \"GIT_INDEX_FILE=%s\", s->index_file);\n+\n+\tmemset(&sm_summary, 0, sizeof(sm_summary));\n+\tsm_summary.argv = argv;\n+\tsm_summary.env = env;\n+\tsm_summary.git_cmd = 1;\n+\tsm_summary.no_stdin = 1;\n+\tfflush(s->fp);\n+\tsm_summary.out = dup(fileno(s->fp));    /* run_command closes it */\n+\trun_command(&sm_summary);\n+}\n \n static void wt_status_print_untracked(struct wt_status *s)\n {\n@@ -308,6 +342,7 @@ void wt_status_print(struct wt_status *s)\n \t}\n \n \twt_status_print_changed(s);\n+\twt_status_print_submodule_summary(s);\n \twt_status_print_untracked(s);\n \n \tif (s->verbose && !s->is_initial)\n@@ -330,6 +365,13 @@ void wt_status_print(struct wt_status *s)\n \n int git_status_config(const char *k, const char *v)\n {\n+\tif (!strcmp(k, \"status.submodulesummary\")) {\n+\t\tint is_bool;\n+\t\twt_status_submodule_summary = git_config_bool_or_int(k, v, &is_bool);\n+\t\tif (is_bool && wt_status_submodule_summary)\n+\t\t\twt_status_submodule_summary = -1;\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(k, \"status.color\") || !strcmp(k, \"color.status\")) {\n \t\twt_status_use_color = git_config_colorbool(k, v, -1);\n \t\treturn 0;\n-- \n1.5.5.23.g2a5f\n"},{"id":"74207","messageId":"1208012733-18211-5-git-send-email-pkufranky@gmail.com","threadId":"13078","inReplyTo":"1208012733-18211-4-git-send-email-pkufranky@gmail.com","subject":"[PATCH v3 4/4] buitin-status: Add tests for submodule summary","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:05:33Z","receivedAt":"2008-04-12T15:05:33Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"Signed-off-by: Ping Yin <pkufranky@gmail.com>\n---\n t/t7502-status.sh |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 134 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7502-status.sh b/t/t7502-status.sh\nindex cd08516..33882c9 100755\n--- a/t/t7502-status.sh\n+++ b/t/t7502-status.sh\n@@ -149,4 +149,138 @@ test_expect_success 'status of partial commit excluding new file in index' '\n \ttest_cmp expect output\n '\n \n+test_expect_success \"setup status submodule summary\" '\n+\ttest_create_repo sm &&\n+\tcd sm &&\n+\t: >foo &&\n+\tgit add foo &&\n+\tgit commit -m \"Add foo\" &&\n+\tcd .. &&\n+\tgit add sm\n+'\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary is disabled by default\" '\n+\tgit status > output &&\n+\tgit diff expect output\n+'\n+\n+head=$(cd sm && git rev-parse --short=7 --verify HEAD)\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Modified submodules:\n+#\n+# * sm 0000000...$head (1):\n+#   > Add foo\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary\" '\n+\tgit config status.submodulesummary 10 &&\n+\tgit status > output &&\n+\tgit diff expect output\n+'\n+\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+no changes added to commit (use \"git add\" and/or \"git commit -a\")\n+EOF\n+test_expect_success \"status submodule summary (clean submodule)\" '\n+\tgit commit -m \"commit submodule\" &&\n+\tgit config status.submodulesummary 10 &&\n+\t! git status > output &&\n+\tgit diff expect output\n+'\n+\n+cat > expect <<EOF\n+# On branch master\n+# Changes to be committed:\n+#   (use \"git reset HEAD^1 <file>...\" to unstage)\n+#\n+#\tnew file:   dir2/added\n+#\tnew file:   sm\n+#\n+# Changed but not updated:\n+#   (use \"git add <file>...\" to update what will be committed)\n+#\n+#\tmodified:   dir1/modified\n+#\n+# Modified submodules:\n+#\n+# * sm 0000000...$head (1):\n+#   > Add foo\n+#\n+# Untracked files:\n+#   (use \"git add <file>...\" to include in what will be committed)\n+#\n+#\tdir1/untracked\n+#\tdir2/modified\n+#\tdir2/untracked\n+#\texpect\n+#\toutput\n+#\tuntracked\n+EOF\n+test_expect_success \"status submodule summary (--amend)\" '\n+\tgit config status.submodulesummary 10 &&\n+\tgit status --amend > output &&\n+\tgit diff expect output\n+'\n+\n test_done\n-- \n1.5.5.23.g2a5f\n"},{"id":"74210","messageId":"46dff0320804120813w36da1c9bi4c480849b53895c0@mail.gmail.com","threadId":"13078","inReplyTo":"1208012733-18211-5-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH v3 4/4] buitin-status: Add tests for submodule summary","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-12T15:13:41Z","receivedAt":"2008-04-12T15:13:41Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"s/buitin/builtin/ in the title\n\n\n-- \nPing Yin\n"},{"id":"74241","messageId":"7vmynye0cz.fsf@gitster.siamese.dyndns.org","threadId":"13078","inReplyTo":"1208012733-18211-2-git-send-email-pkufranky@gmail.com","subject":"Re: [PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-04-13T06:26:52Z","receivedAt":"2008-04-13T06:26:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ping Yin <pkufranky@gmail.com> writes:\n\n> With git_config_bool_or_int, the caller can differentiate boolean true\n> and integer 1 etc.\n>\n> Signed-off-by: Ping Yin <pkufranky@gmail.com>\n> ---\n>  config.c |   15 +++++++++++++++\n>  1 files changed, 15 insertions(+), 0 deletions(-)\n>\n> diff --git a/config.c b/config.c\n> index 0624494..e614456 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -316,6 +316,21 @@ int git_config_bool(const char *name, const char *value)\n>  \treturn git_config_int(name, value) != 0;\n>  }\n>  \n> +int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n> +{\n> +\t*is_bool = 1;\n> +\tif (!value)\n> +\t\treturn 1;\n> +\tif (!*value)\n> +\t\treturn 0;\n> +\tif (!strcasecmp(value, \"true\") || !strcasecmp(value, \"yes\"))\n> +\t\treturn 1;\n> +\tif (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n> +\t\treturn 0;\n> +\t*is_bool = 0;\n> +\treturn git_config_int(name, value);\n> +}\n> +\n\nI expected git_config_bool() to be implemented in terms of this new\nfunction to avoid code duplication if we were actually going to do this.\n\nYou also need an external declaration in a header file for its users.\n\n---\n cache.h  |    1 +\n config.c |   10 +++++++++-\n 2 files changed, 10 insertions(+), 1 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 2a1e7ec..50b28fa 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -692,6 +692,7 @@ extern int git_parse_long(const char *, long *);\n extern int git_parse_ulong(const char *, unsigned long *);\n extern int git_config_int(const char *, const char *);\n extern unsigned long git_config_ulong(const char *, const char *);\n+extern int git_config_bool_or_int(const char *, const char *, int *);\n extern int git_config_bool(const char *, const char *);\n extern int git_config_string(const char **, const char *, const char *);\n extern int git_config_set(const char *, const char *);\ndiff --git a/config.c b/config.c\nindex 0624494..5ea18ef 100644\n--- a/config.c\n+++ b/config.c\n@@ -303,8 +303,9 @@ unsigned long git_config_ulong(const char *name, const char *value)\n \treturn ret;\n }\n \n-int git_config_bool(const char *name, const char *value)\n+int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n {\n+\t*is_bool = 1;\n \tif (!value)\n \t\treturn 1;\n \tif (!*value)\n@@ -313,9 +314,16 @@ int git_config_bool(const char *name, const char *value)\n \t\treturn 1;\n \tif (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n \t\treturn 0;\n+\t*is_bool = 0;\n \treturn git_config_int(name, value) != 0;\n }\n \n+int git_config_bool(const char *name, const char *value)\n+{\n+\tint discard;\n+\treturn git_config_bool_or_int(name, value, &discard);\n+}\n+\n int git_config_string(const char **dest, const char *var, const char *value)\n {\n \tif (!value)\n"},{"id":"74243","messageId":"46dff0320804130028l76c69b55jb8d6be79125b6041@mail.gmail.com","threadId":"13078","inReplyTo":"7vmynye0cz.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-13T07:28:20Z","receivedAt":"2008-04-13T07:28:20Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Sun, Apr 13, 2008 at 2:26 PM, Junio C Hamano <junio@pobox.com> wrote:\n> Ping Yin <pkufranky@gmail.com> writes:\n>\n>  > With git_config_bool_or_int, the caller can differentiate boolean true\n>  > and integer 1 etc.\n>  >\n>  > Signed-off-by: Ping Yin <pkufranky@gmail.com>\n>  > ---\n>  >  config.c |   15 +++++++++++++++\n>  >  1 files changed, 15 insertions(+), 0 deletions(-)\n>  >\n>  > diff --git a/config.c b/config.c\n>  > index 0624494..e614456 100644\n>  > --- a/config.c\n>  > +++ b/config.c\n>  > @@ -316,6 +316,21 @@ int git_config_bool(const char *name, const char *value)\n>  >       return git_config_int(name, value) != 0;\n>  >  }\n>  >\n>  > +int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n>  > +{\n>  > +     *is_bool = 1;\n>  > +     if (!value)\n>  > +             return 1;\n>  > +     if (!*value)\n>  > +             return 0;\n>  > +     if (!strcasecmp(value, \"true\") || !strcasecmp(value, \"yes\"))\n>  > +             return 1;\n>  > +     if (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n>  > +             return 0;\n>  > +     *is_bool = 0;\n>  > +     return git_config_int(name, value);\n>  > +}\n>  > +\n>\n>  I expected git_config_bool() to be implemented in terms of this new\n>  function to avoid code duplication if we were actually going to do this.\n>\n>  You also need an external declaration in a header file for its users.\n>\n>  ---\n>   cache.h  |    1 +\n>   config.c |   10 +++++++++-\n>   2 files changed, 10 insertions(+), 1 deletions(-)\n>\n>  diff --git a/cache.h b/cache.h\n>  index 2a1e7ec..50b28fa 100644\n>  --- a/cache.h\n>  +++ b/cache.h\n>  @@ -692,6 +692,7 @@ extern int git_parse_long(const char *, long *);\n>   extern int git_parse_ulong(const char *, unsigned long *);\n>   extern int git_config_int(const char *, const char *);\n>   extern unsigned long git_config_ulong(const char *, const char *);\n>  +extern int git_config_bool_or_int(const char *, const char *, int *);\n>   extern int git_config_bool(const char *, const char *);\n>   extern int git_config_string(const char **, const char *, const char *);\n>   extern int git_config_set(const char *, const char *);\n>\n> diff --git a/config.c b/config.c\n>  index 0624494..5ea18ef 100644\n>\n> --- a/config.c\n>  +++ b/config.c\n>  @@ -303,8 +303,9 @@ unsigned long git_config_ulong(const char *name, const char *value)\n>         return ret;\n>   }\n>\n>  -int git_config_bool(const char *name, const char *value)\n>\n> +int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n>   {\n>  +       *is_bool = 1;\n>         if (!value)\n>                 return 1;\n>         if (!*value)\n>  @@ -313,9 +314,16 @@ int git_config_bool(const char *name, const char *value)\n>\n>                 return 1;\n>         if (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n>                 return 0;\n>  +       *is_bool = 0;\n>\n>         return git_config_int(name, value) != 0;\n>   }\n>\n>  +int git_config_bool(const char *name, const char *value)\n>  +{\n>  +       int discard;\n>  +       return git_config_bool_or_int(name, value, &discard);\n\nIs it better to use\n+       return git_config_bool_or_int(name, value, &discard) != 0;\n\nsince git_config_bool_or_int(name, value, &discard) may return an\ninterger neither 0 nor 1\n\n\n-- \nPing Yin\n"},{"id":"74244","messageId":"46dff0320804130030q19dd9f23j66d9b7adc7d305d3@mail.gmail.com","threadId":"13078","inReplyTo":"7vmynye0cz.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-04-13T07:30:28Z","receivedAt":"2008-04-13T07:30:28Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Sun, Apr 13, 2008 at 2:26 PM, Junio C Hamano <junio@pobox.com> wrote:\n> Ping Yin <pkufranky@gmail.com> writes:\n\n>  -int git_config_bool(const char *name, const char *value)\n>\n> +int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n>   {\n>  +       *is_bool = 1;\n>         if (!value)\n>                 return 1;\n>         if (!*value)\n>  @@ -313,9 +314,16 @@ int git_config_bool(const char *name, const char *value)\n>\n>                 return 1;\n>         if (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n>                 return 0;\n>  +       *is_bool = 0;\n>\n>         return git_config_int(name, value) != 0;\n>   }\n\nShould return an interger if *is_bool==0\ns/!=0//\n\n\n>  +int git_config_bool(const char *name, const char *value)\n>  +{\n>  +       int discard;\n>  +       return git_config_bool_or_int(name, value, &discard);\n>\n>\n> +}\n>  +\n>   int git_config_string(const char **dest, const char *var, const char *value)\n>   {\n>         if (!value)\n>\n>\n\n\n\n-- \nPing Yin\n"},{"id":"74245","messageId":"7vprsucej4.fsf@gitster.siamese.dyndns.org","threadId":"13078","inReplyTo":"46dff0320804130030q19dd9f23j66d9b7adc7d305d3@mail.gmail.com","subject":"Re: [PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-13T09:03:43Z","receivedAt":"2008-04-13T09:03:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Ping Yin\" <pkufranky@gmail.com> writes:\n\n>>         return git_config_int(name, value) != 0;\n>>   }\n>\n> Should return an interger if *is_bool==0\n> s/!=0//\n\nYeah, you are right.  I do not know where that \"!= 0\" came from.\n"},{"id":"74265","messageId":"7vy77hbm8g.fsf@gitster.siamese.dyndns.org","threadId":"13078","inReplyTo":"7vprsucej4.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH v3 1/4] config.c: Add git_config_bool_or_int to handle bool/int variable","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-13T19:14:55Z","receivedAt":"2008-04-13T19:14:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"Ping Yin\" <pkufranky@gmail.com> writes:\n>\n>>>         return git_config_int(name, value) != 0;\n>>>   }\n>>\n>> Should return an interger if *is_bool==0\n>> s/!=0//\n>\n> Yeah, you are right.  I do not know where that \"!= 0\" came from.\n\nSorry about the breakage.\n\nThe real reason the breakage did not get caught was there was nothing that\ncatches the breakage.  Hence this adds tests for this new feature.\n\n-- >8 --\nFrom: Junio C Hamano <gitster@pobox.com>\nDate: Sun, 13 Apr 2008 12:11:11 -0700\nSubject: [PATCH] Fix git_config_bool_or_int\n\nThe earlier one botched the return value logic between config_bool and\nconfig_bool_and_int.  The former should normalize between 0 and 1 while\nthe latter should give back full range of integer values.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n builtin-config.c       |   22 ++++++++++++++++-\n config.c               |    4 +-\n t/t1300-repo-config.sh |   58 ++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 80 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin-config.c b/builtin-config.c\nindex c34bc8b..10447a7 100644\n--- a/builtin-config.c\n+++ b/builtin-config.c\n@@ -3,7 +3,7 @@\n #include \"color.h\"\n \n static const char git_config_set_usage[] =\n-\"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]\";\n+\"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]\";\n \n static char *key;\n static regex_t *key_regexp;\n@@ -16,7 +16,7 @@ static int seen;\n static char delim = '=';\n static char key_delim = ' ';\n static char term = '\\n';\n-static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;\n+static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;\n \n static int show_all_config(const char *key_, const char *value_)\n {\n@@ -53,6 +53,14 @@ static int show_config(const char* key_, const char* value_)\n \t\tsprintf(value, \"%d\", git_config_int(key_, value_?value_:\"\"));\n \telse if (type == T_BOOL)\n \t\tvptr = git_config_bool(key_, value_) ? \"true\" : \"false\";\n+\telse if (type == T_BOOL_OR_INT) {\n+\t\tint is_bool, v;\n+\t\tv = git_config_bool_or_int(key_, value_, &is_bool);\n+\t\tif (is_bool)\n+\t\t\tvptr = v ? \"true\" : \"false\";\n+\t\telse\n+\t\t\tsprintf(value, \"%d\", v);\n+\t}\n \telse\n \t\tvptr = value_?value_:\"\";\n \tseen++;\n@@ -157,6 +165,14 @@ char *normalize_value(const char *key, const char *value)\n \t\telse if (type == T_BOOL)\n \t\t\tsprintf(normalized, \"%s\",\n \t\t\t\tgit_config_bool(key, value) ? \"true\" : \"false\");\n+\t\telse if (type == T_BOOL_OR_INT) {\n+\t\t\tint is_bool, v;\n+\t\t\tv = git_config_bool_or_int(key, value, &is_bool);\n+\t\t\tif (!is_bool)\n+\t\t\t\tsprintf(normalized, \"%d\", v);\n+\t\t\telse\n+\t\t\t\tsprintf(normalized, \"%s\", v ? \"true\" : \"false\");\n+\t\t}\n \t}\n \n \treturn normalized;\n@@ -273,6 +289,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)\n \t\t\ttype = T_INT;\n \t\telse if (!strcmp(argv[1], \"--bool\"))\n \t\t\ttype = T_BOOL;\n+\t\telse if (!strcmp(argv[1], \"--bool-or-int\"))\n+\t\t\ttype = T_BOOL_OR_INT;\n \t\telse if (!strcmp(argv[1], \"--list\") || !strcmp(argv[1], \"-l\")) {\n \t\t\tif (argc != 2)\n \t\t\t\tusage(git_config_set_usage);\ndiff --git a/config.c b/config.c\nindex 5ea18ef..b0ada51 100644\n--- a/config.c\n+++ b/config.c\n@@ -315,13 +315,13 @@ int git_config_bool_or_int(const char *name, const char *value, int *is_bool)\n \tif (!strcasecmp(value, \"false\") || !strcasecmp(value, \"no\"))\n \t\treturn 0;\n \t*is_bool = 0;\n-\treturn git_config_int(name, value) != 0;\n+\treturn git_config_int(name, value);\n }\n \n int git_config_bool(const char *name, const char *value)\n {\n \tint discard;\n-\treturn git_config_bool_or_int(name, value, &discard);\n+\treturn !!git_config_bool_or_int(name, value, &discard);\n }\n \n int git_config_string(const char **dest, const char *var, const char *value)\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex b36a901..a675cbb 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -595,6 +595,64 @@ test_expect_success 'set --int' '\n \n rm .git/config\n \n+cat >expect <<\\EOF\n+[bool]\n+\ttrue1 = true\n+\ttrue2 = true\n+\tfalse1 = false\n+\tfalse2 = false\n+[int]\n+\tint1 = 0\n+\tint2 = 1\n+\tint3 = -1\n+EOF\n+\n+test_expect_success 'get --bool-or-int' '\n+\t(\n+\t\techo \"[bool]\"\n+\t\techo true1\n+\t\techo true2 = true\n+\t\techo false = false\n+\t\techo \"[int]\"\n+\t\techo int1 = 0\n+\t\techo int2 = 1\n+\t\techo int3 = -1\n+\t) >>.git/config &&\n+\ttest $(git config --bool-or-int bool.true1) = true &&\n+\ttest $(git config --bool-or-int bool.true2) = true &&\n+\ttest $(git config --bool-or-int bool.false) = false &&\n+\ttest $(git config --bool-or-int int.int1) = 0 &&\n+\ttest $(git config --bool-or-int int.int2) = 1 &&\n+\ttest $(git config --bool-or-int int.int3) = -1\n+\n+'\n+\n+rm .git/config\n+cat >expect <<\\EOF\n+[bool]\n+\ttrue1 = true\n+\tfalse1 = false\n+\ttrue2 = true\n+\tfalse2 = false\n+[int]\n+\tint1 = 0\n+\tint2 = 1\n+\tint3 = -1\n+EOF\n+\n+test_expect_success 'set --bool-or-int' '\n+\tgit config --bool-or-int bool.true1 true &&\n+\tgit config --bool-or-int bool.false1 false &&\n+\tgit config --bool-or-int bool.true2 yes &&\n+\tgit config --bool-or-int bool.false2 no &&\n+\tgit config --bool-or-int int.int1 0 &&\n+\tgit config --bool-or-int int.int2 1 &&\n+\tgit config --bool-or-int int.int3 -1 &&\n+\ttest_cmp expect .git/config\n+'\n+\n+rm .git/config\n+\n git config quote.leading \" test\"\n git config quote.ending \"test \"\n git config quote.semicolon \"test;test\"\n-- \n1.5.5.104.ge4331\n"}]}