{"thread":{"id":"16337","subject":"[PATCH] Teach/Fix pull/fetch -q/-v options","startedAt":"2008-11-15T00:14:24Z","lastAt":"2008-11-15T19:16:28Z","messageCount":7,"participants":["Tuncer Ayaz","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"95850","messageId":"1226708064-19432-1-git-send-email-tuncer.ayaz@gmail.com","threadId":"16337","inReplyTo":null,"subject":"[PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2008-11-15T00:14:24Z","receivedAt":"2008-11-15T00:14:24Z","isPatch":true,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"Implement git-pull --quiet and git-pull --verbose by\nadding the options to git-pull and fixing verbosity\nhandling in git-fetch.\n---\n Documentation/merge-options.txt |    8 +++++\n builtin-fetch.c                 |   21 +++++++------\n builtin-merge.c                 |   22 ++++++++++----\n git-pull.sh                     |   10 ++++--\n t/t5521-pull-options.sh         |   60 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 101 insertions(+), 20 deletions(-)\n create mode 100755 t/t5521-pull-options.sh\n\ndiff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt\nindex 007909a..427cdef 100644\n--- a/Documentation/merge-options.txt\n+++ b/Documentation/merge-options.txt\n@@ -1,3 +1,11 @@\n+-q::\n+--quiet::\n+\tOperate quietly.\n+\n+-v::\n+--verbose::\n+\tBe verbose.\n+\n --stat::\n \tShow a diffstat at the end of the merge. The diffstat is also\n \tcontrolled by the configuration option merge.stat.\ndiff --git a/builtin-fetch.c b/builtin-fetch.c\nindex f151cfa..efc5801 100644\n--- a/builtin-fetch.c\n+++ b/builtin-fetch.c\n@@ -22,16 +22,17 @@ enum {\n \tTAGS_SET = 2\n };\n \n-static int append, force, keep, update_head_ok, verbose, quiet;\n+static int append, force, keep, update_head_ok;\n static int tags = TAGS_DEFAULT;\n static const char *depth;\n static const char *upload_pack;\n static struct strbuf default_rla = STRBUF_INIT;\n static struct transport *transport;\n+static enum { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;\n \n static struct option builtin_fetch_options[] = {\n-\tOPT__QUIET(&quiet),\n-\tOPT__VERBOSE(&verbose),\n+\tOPT_SET_INT('v', \"verbose\", &verbosity, \"be verbose\", VERBOSE),\n+\tOPT_SET_INT('q', \"quiet\", &verbosity, \"operate quietly\", QUIET),\n \tOPT_BOOLEAN('a', \"append\", &append,\n \t\t    \"append to .git/FETCH_HEAD instead of overwriting\"),\n \tOPT_STRING(0, \"upload-pack\", &upload_pack, \"PATH\",\n@@ -192,7 +193,6 @@ static int s_update_ref(const char *action,\n \n static int update_local_ref(struct ref *ref,\n \t\t\t    const char *remote,\n-\t\t\t    int verbose,\n \t\t\t    char *display)\n {\n \tstruct commit *current = NULL, *updated;\n@@ -210,7 +210,7 @@ static int update_local_ref(struct ref *ref,\n \t\tdie(\"object %s not found\", sha1_to_hex(ref->new_sha1));\n \n \tif (!hashcmp(ref->old_sha1, ref->new_sha1)) {\n-\t\tif (verbose)\n+\t\tif (verbosity == VERBOSE)\n \t\t\tsprintf(display, \"= %-*s %-*s -> %s\", SUMMARY_WIDTH,\n \t\t\t\t\"[up to date]\", REFCOL_WIDTH, remote,\n \t\t\t\tpretty_ref);\n@@ -366,18 +366,19 @@ static int store_updated_refs(const char *url, const char *remote_name,\n \t\t\tnote);\n \n \t\tif (ref)\n-\t\t\trc |= update_local_ref(ref, what, verbose, note);\n+\t\t\trc |= update_local_ref(ref, what, note);\n \t\telse\n \t\t\tsprintf(note, \"* %-*s %-*s -> FETCH_HEAD\",\n \t\t\t\tSUMMARY_WIDTH, *kind ? kind : \"branch\",\n \t\t\t\t REFCOL_WIDTH, *what ? what : \"HEAD\");\n \t\tif (*note) {\n-\t\t\tif (!shown_url) {\n+\t\t\tif (verbosity > QUIET && !shown_url) {\n \t\t\t\tfprintf(stderr, \"From %.*s\\n\",\n \t\t\t\t\t\turl_len, url);\n \t\t\t\tshown_url = 1;\n \t\t\t}\n-\t\t\tfprintf(stderr, \" %s\\n\", note);\n+\t\t\tif (verbosity > QUIET)\n+\t\t\t\tfprintf(stderr, \" %s\\n\", note);\n \t\t}\n \t}\n \tfclose(fp);\n@@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\tremote = remote_get(argv[0]);\n \n \ttransport = transport_get(remote, remote->url[0]);\n-\tif (verbose >= 2)\n+\tif (verbosity == VERBOSE)\n \t\ttransport->verbose = 1;\n-\tif (quiet)\n+\tif (verbosity == QUIET)\n \t\ttransport->verbose = -1;\n \tif (upload_pack)\n \t\tset_option(TRANS_OPT_UPLOADPACK, upload_pack);\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex 5e7910b..a35f944 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];\n static struct strategy **use_strategies;\n static size_t use_strategies_nr, use_strategies_alloc;\n static const char *branch;\n+static enum { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;\n \n static struct strategy all_strategy[] = {\n \t{ \"recursive\",  DEFAULT_TWOHEAD | NO_TRIVIAL },\n@@ -152,6 +153,8 @@ static int option_parse_n(const struct option *opt,\n }\n \n static struct option builtin_merge_options[] = {\n+\tOPT_SET_INT('v', \"verbose\", &verbosity, \"be verbose\", VERBOSE),\n+\tOPT_SET_INT('q', \"quiet\", &verbosity, \"operate quietly\", QUIET),\n \t{ OPTION_CALLBACK, 'n', NULL, NULL, NULL,\n \t\t\"do not show a diffstat at the end of the merge\",\n \t\tPARSE_OPT_NOARG, option_parse_n },\n@@ -250,7 +253,8 @@ static void restore_state(void)\n /* This is called when no merge was necessary. */\n static void finish_up_to_date(const char *msg)\n {\n-\tprintf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n+\tif (verbosity > QUIET)\n+\t\tprintf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n \tdrop_save();\n }\n \n@@ -331,14 +335,15 @@ static void finish(const unsigned char *new_head, const char *msg)\n \tif (!msg)\n \t\tstrbuf_addstr(&reflog_message, getenv(\"GIT_REFLOG_ACTION\"));\n \telse {\n-\t\tprintf(\"%s\\n\", msg);\n+\t\tif (verbosity > QUIET)\n+\t\t\tprintf(\"%s\\n\", msg);\n \t\tstrbuf_addf(&reflog_message, \"%s: %s\",\n \t\t\tgetenv(\"GIT_REFLOG_ACTION\"), msg);\n \t}\n \tif (squash) {\n \t\tsquash_message();\n \t} else {\n-\t\tif (!merge_msg.len)\n+\t\tif (verbosity > QUIET && !merge_msg.len)\n \t\t\tprintf(\"No merge message -- not updating HEAD\\n\");\n \t\telse {\n \t\t\tconst char *argv_gc_auto[] = { \"gc\", \"--auto\", NULL };\n@@ -872,6 +877,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, builtin_merge_options,\n \t\t\tbuiltin_merge_usage, 0);\n+\tif (verbosity == QUIET)\n+\t\tshow_diffstat = 0;\n \n \tif (squash) {\n \t\tif (!allow_fast_forward)\n@@ -1013,10 +1020,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \n \t\tstrcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));\n \n-\t\tprintf(\"Updating %s..%s\\n\",\n-\t\t\thex,\n-\t\t\tfind_unique_abbrev(remoteheads->item->object.sha1,\n-\t\t\tDEFAULT_ABBREV));\n+\t\tif (verbosity > QUIET)\n+\t\t\tprintf(\"Updating %s..%s\\n\",\n+\t\t\t\thex,\n+\t\t\t\tfind_unique_abbrev(remoteheads->item->object.sha1,\n+\t\t\t\tDEFAULT_ABBREV));\n \t\tstrbuf_addstr(&msg, \"Fast forward\");\n \t\tif (have_message)\n \t\t\tstrbuf_addstr(&msg,\ndiff --git a/git-pull.sh b/git-pull.sh\nindex 664fe34..8866f2a 100755\n--- a/git-pull.sh\n+++ b/git-pull.sh\n@@ -16,13 +16,17 @@ cd_to_toplevel\n test -z \"$(git ls-files -u)\" ||\n \tdie \"You are in the middle of a conflicted merge.\"\n \n-strategy_args= no_stat= no_commit= squash= no_ff= log_arg=\n+strategy_args= no_stat= no_commit= squash= no_ff= log_arg= verbosity=\n curr_branch=$(git symbolic-ref -q HEAD)\n curr_branch_short=$(echo \"$curr_branch\" | sed \"s|refs/heads/||\")\n rebase=$(git config --bool branch.$curr_branch_short.rebase)\n while :\n do\n \tcase \"$1\" in\n+\t-q|--quiet)\n+\t\tverbosity=-q ;;\n+\t-v|--verbose)\n+\t\tverbosity=-v ;;\n \t-n|--no-stat|--no-summary)\n \t\tno_stat=-n ;;\n \t--stat|--summary)\n@@ -121,7 +125,7 @@ test true = \"$rebase\" && {\n \t\t\"refs/remotes/$origin/$reflist\" 2>/dev/null)\"\n }\n orig_head=$(git rev-parse --verify HEAD 2>/dev/null)\n-git fetch --update-head-ok \"$@\" || exit 1\n+git fetch $verbosity --update-head-ok \"$@\" || exit 1\n \n curr_head=$(git rev-parse --verify HEAD 2>/dev/null)\n if test -n \"$orig_head\" && test \"$curr_head\" != \"$orig_head\"\n@@ -182,4 +186,4 @@ test true = \"$rebase\" &&\n \texec git-rebase $strategy_args --onto $merge_head \\\n \t${oldremoteref:-$merge_head}\n exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \\\n-\t\"$merge_name\" HEAD $merge_head\n+\t\"$merge_name\" HEAD $merge_head $verbosity\ndiff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh\nnew file mode 100755\nindex 0000000..83e2e8a\n--- /dev/null\n+++ b/t/t5521-pull-options.sh\n@@ -0,0 +1,60 @@\n+#!/bin/sh\n+\n+test_description='pull options'\n+\n+. ./test-lib.sh\n+\n+D=`pwd`\n+\n+test_expect_success 'setup' '\n+\tmkdir parent &&\n+\t(cd parent && git init &&\n+\t echo one >file && git add file &&\n+\t git commit -m one)\n+'\n+\n+cd \"$D\"\n+\n+test_expect_success 'git pull -q' '\n+\tmkdir clonedq &&\n+\tcd clonedq &&\n+\tgit pull -q \"$D/parent\" >out 2>err &&\n+\ttest ! -s out\n+'\n+\n+cd \"$D\"\n+\n+test_expect_success 'git pull' '\n+\tmkdir cloned &&\n+\tcd cloned &&\n+\tgit pull \"$D/parent\" >out 2>err &&\n+\ttest -s out\n+'\n+cd \"$D\"\n+\n+test_expect_success 'git pull -v' '\n+\tmkdir clonedv &&\n+\tcd clonedv &&\n+\tgit pull -v \"$D/parent\" >out 2>err &&\n+\ttest -s out\n+'\n+\n+cd \"$D\"\n+\n+test_expect_success 'git pull -v -q' '\n+\tmkdir clonedvq &&\n+\tcd clonedvq &&\n+\tgit pull -v -q \"$D/parent\" >out 2>err &&\n+\ttest ! -s out\n+'\n+\n+cd \"$D\"\n+\n+test_expect_success 'git pull -q -v' '\n+\tmkdir clonedqv &&\n+\tcd clonedqv &&\n+\tgit pull -q -v \"$D/parent\" >out 2>err &&\n+\ttest -s out\n+'\n+\n+test_done\n-- \n1.6.0.4\n"},{"id":"95852","messageId":"7v7i7594cx.fsf@gitster.siamese.dyndns.org","threadId":"16337","inReplyTo":"1226708064-19432-1-git-send-email-tuncer.ayaz@gmail.com","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-11-15T01:15:26Z","receivedAt":"2008-11-15T01:15:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>  \t\tremote = remote_get(argv[0]);\n>  \n>  \ttransport = transport_get(remote, remote->url[0]);\n> -\tif (verbose >= 2)\n> +\tif (verbosity == VERBOSE)\n>  \t\ttransport->verbose = 1;\n> -\tif (quiet)\n> +\tif (verbosity == QUIET)\n>  \t\ttransport->verbose = -1;\n>  \tif (upload_pack)\n>  \t\tset_option(TRANS_OPT_UPLOADPACK, upload_pack);\n\nIn the original code, the variable verbose can be \">= 2\" when \"-v -v\" is\ngiven, so transport->verbose is not turned on with a single \"-v\" alone\n(this correctly mimics the original behaviour in the scripted version).\n\nThe approach with enum { Q, N, V } cannot express this, unfortunately.\n\nSo let's do something like the attached patch, instead.\n\nThe patch adds OPT__VERBOSITY() that allows you to say \"-v -v\" to increase\nverbosity (and \"-q -q\" to make it really quiet, although we do not use it\nanywhere yet).\n\n builtin-fetch.c |   19 +++++++++----------\n builtin-merge.c |   21 ++++++++++++++-------\n parse-options.c |   22 ++++++++++++++++++++++\n parse-options.h |    6 ++++++\n 4 files changed, 51 insertions(+), 17 deletions(-)\n\ndiff --git c/builtin-fetch.c w/builtin-fetch.c\nindex f151cfa..7568163 100644\n--- c/builtin-fetch.c\n+++ w/builtin-fetch.c\n@@ -22,7 +22,7 @@ enum {\n \tTAGS_SET = 2\n };\n \n-static int append, force, keep, update_head_ok, verbose, quiet;\n+static int append, force, keep, update_head_ok, verbosity;\n static int tags = TAGS_DEFAULT;\n static const char *depth;\n static const char *upload_pack;\n@@ -30,8 +30,7 @@ static struct strbuf default_rla = STRBUF_INIT;\n static struct transport *transport;\n \n static struct option builtin_fetch_options[] = {\n-\tOPT__QUIET(&quiet),\n-\tOPT__VERBOSE(&verbose),\n+\tOPT__VERBOSITY(&verbosity),\n \tOPT_BOOLEAN('a', \"append\", &append,\n \t\t    \"append to .git/FETCH_HEAD instead of overwriting\"),\n \tOPT_STRING(0, \"upload-pack\", &upload_pack, \"PATH\",\n@@ -192,7 +191,6 @@ static int s_update_ref(const char *action,\n \n static int update_local_ref(struct ref *ref,\n \t\t\t    const char *remote,\n-\t\t\t    int verbose,\n \t\t\t    char *display)\n {\n \tstruct commit *current = NULL, *updated;\n@@ -210,7 +208,7 @@ static int update_local_ref(struct ref *ref,\n \t\tdie(\"object %s not found\", sha1_to_hex(ref->new_sha1));\n \n \tif (!hashcmp(ref->old_sha1, ref->new_sha1)) {\n-\t\tif (verbose)\n+\t\tif (verbosity > 0)\n \t\t\tsprintf(display, \"= %-*s %-*s -> %s\", SUMMARY_WIDTH,\n \t\t\t\t\"[up to date]\", REFCOL_WIDTH, remote,\n \t\t\t\tpretty_ref);\n@@ -366,18 +364,19 @@ static int store_updated_refs(const char *url, const char *remote_name,\n \t\t\tnote);\n \n \t\tif (ref)\n-\t\t\trc |= update_local_ref(ref, what, verbose, note);\n+\t\t\trc |= update_local_ref(ref, what, note);\n \t\telse\n \t\t\tsprintf(note, \"* %-*s %-*s -> FETCH_HEAD\",\n \t\t\t\tSUMMARY_WIDTH, *kind ? kind : \"branch\",\n \t\t\t\t REFCOL_WIDTH, *what ? what : \"HEAD\");\n \t\tif (*note) {\n-\t\t\tif (!shown_url) {\n+\t\t\tif (verbosity >= 0 && !shown_url) {\n \t\t\t\tfprintf(stderr, \"From %.*s\\n\",\n \t\t\t\t\t\turl_len, url);\n \t\t\t\tshown_url = 1;\n \t\t\t}\n-\t\t\tfprintf(stderr, \" %s\\n\", note);\n+\t\t\tif (verbosity >= 0)\n+\t\t\t\tfprintf(stderr, \" %s\\n\", note);\n \t\t}\n \t}\n \tfclose(fp);\n@@ -637,9 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n \t\tremote = remote_get(argv[0]);\n \n \ttransport = transport_get(remote, remote->url[0]);\n-\tif (verbose >= 2)\n+\tif (verbosity >= 2)\n \t\ttransport->verbose = 1;\n-\tif (quiet)\n+\tif (verbosity < 0)\n \t\ttransport->verbose = -1;\n \tif (upload_pack)\n \t\tset_option(TRANS_OPT_UPLOADPACK, upload_pack);\ndiff --git c/builtin-merge.c w/builtin-merge.c\nindex 5e7910b..7c2b90c 100644\n--- c/builtin-merge.c\n+++ w/builtin-merge.c\n@@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];\n static struct strategy **use_strategies;\n static size_t use_strategies_nr, use_strategies_alloc;\n static const char *branch;\n+static int verbosity;\n \n static struct strategy all_strategy[] = {\n \t{ \"recursive\",  DEFAULT_TWOHEAD | NO_TRIVIAL },\n@@ -171,6 +172,7 @@ static struct option builtin_merge_options[] = {\n \tOPT_CALLBACK('m', \"message\", &merge_msg, \"message\",\n \t\t\"message to be used for the merge commit (if any)\",\n \t\toption_parse_message),\n+\tOPT__VERBOSITY(&verbosity),\n \tOPT_END()\n };\n \n@@ -250,7 +252,8 @@ static void restore_state(void)\n /* This is called when no merge was necessary. */\n static void finish_up_to_date(const char *msg)\n {\n-\tprintf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n+\tif (verbosity >= 0)\n+\t\tprintf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n \tdrop_save();\n }\n \n@@ -331,14 +334,15 @@ static void finish(const unsigned char *new_head, const char *msg)\n \tif (!msg)\n \t\tstrbuf_addstr(&reflog_message, getenv(\"GIT_REFLOG_ACTION\"));\n \telse {\n-\t\tprintf(\"%s\\n\", msg);\n+\t\tif (verbosity >= 0)\n+\t\t\tprintf(\"%s\\n\", msg);\n \t\tstrbuf_addf(&reflog_message, \"%s: %s\",\n \t\t\tgetenv(\"GIT_REFLOG_ACTION\"), msg);\n \t}\n \tif (squash) {\n \t\tsquash_message();\n \t} else {\n-\t\tif (!merge_msg.len)\n+\t\tif (verbosity >= 0 && !merge_msg.len)\n \t\t\tprintf(\"No merge message -- not updating HEAD\\n\");\n \t\telse {\n \t\t\tconst char *argv_gc_auto[] = { \"gc\", \"--auto\", NULL };\n@@ -872,6 +876,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, builtin_merge_options,\n \t\t\tbuiltin_merge_usage, 0);\n+\tif (verbosity < 0)\n+\t\tshow_diffstat = 0;\n \n \tif (squash) {\n \t\tif (!allow_fast_forward)\n@@ -1013,10 +1019,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \n \t\tstrcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));\n \n-\t\tprintf(\"Updating %s..%s\\n\",\n-\t\t\thex,\n-\t\t\tfind_unique_abbrev(remoteheads->item->object.sha1,\n-\t\t\tDEFAULT_ABBREV));\n+\t\tif (verbosity >= 0)\n+\t\t\tprintf(\"Updating %s..%s\\n\",\n+\t\t\t\thex,\n+\t\t\t\tfind_unique_abbrev(remoteheads->item->object.sha1,\n+\t\t\t\tDEFAULT_ABBREV));\n \t\tstrbuf_addstr(&msg, \"Fast forward\");\n \t\tif (have_message)\n \t\t\tstrbuf_addstr(&msg,\ndiff --git c/parse-options.c w/parse-options.c\nindex fd08bb4..9eb55cc 100644\n--- c/parse-options.c\n+++ w/parse-options.c\n@@ -484,6 +484,28 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n \treturn 0;\n }\n \n+int parse_opt_verbosity_cb(const struct option *opt, const char *arg,\n+\t\t\t   int unset)\n+{\n+\tint *target = opt->value;\n+\n+\tif (unset)\n+\t\t/* --no-quiet, --no-verbose */\n+\t\t*target = 0;\n+\telse if (opt->short_name == 'v') {\n+\t\tif (*target >= 0)\n+\t\t\t(*target)++;\n+\t\telse\n+\t\t\t*target = 1;\n+\t} else {\n+\t\tif (*target <= 0)\n+\t\t\t(*target)--;\n+\t\telse\n+\t\t\t*target = -1;\n+\t}\n+\treturn 0;\n+}\n+\n /*\n  * This should really be OPTION_FILENAME type as a part of\n  * parse_options that take prefix to do this while parsing.\ndiff --git c/parse-options.h w/parse-options.h\nindex 5199950..034162e 100644\n--- c/parse-options.h\n+++ w/parse-options.h\n@@ -150,9 +150,15 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx);\n /*----- some often used options -----*/\n extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n extern int parse_opt_approxidate_cb(const struct option *, const char *, int);\n+extern int parse_opt_verbosity_cb(const struct option *, const char *, int);\n \n #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n+#define OPT__VERBOSITY(var) \\\n+\t{ OPTION_CALLBACK, 'v', \"verbose\", (var), NULL, \"be more verbose\", \\\n+\t  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \\\n+\t{ OPTION_CALLBACK, 'q', \"quiet\", (var), NULL, \"be more quiet\", \\\n+\t  PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }\n #define OPT__DRY_RUN(var)  OPT_BOOLEAN('n', \"dry-run\", (var), \"dry run\")\n #define OPT__ABBREV(var)  \\\n \t{ OPTION_CALLBACK, 0, \"abbrev\", (var), \"n\", \\\n"},{"id":"95853","messageId":"4ac8254d0811141753y18567966h934a5701e168a7bd@mail.gmail.com","threadId":"16337","inReplyTo":"7v7i7594cx.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2008-11-15T01:53:33Z","receivedAt":"2008-11-15T01:53:33Z","isPatch":true,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Sat, Nov 15, 2008 at 2:15 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>>               remote = remote_get(argv[0]);\n>>\n>>       transport = transport_get(remote, remote->url[0]);\n>> -     if (verbose >= 2)\n>> +     if (verbosity == VERBOSE)\n>>               transport->verbose = 1;\n>> -     if (quiet)\n>> +     if (verbosity == QUIET)\n>>               transport->verbose = -1;\n>>       if (upload_pack)\n>>               set_option(TRANS_OPT_UPLOADPACK, upload_pack);\n>\n> In the original code, the variable verbose can be \">= 2\" when \"-v -v\" is\n> given, so transport->verbose is not turned on with a single \"-v\" alone\n> (this correctly mimics the original behaviour in the scripted version).\n>\n> The approach with enum { Q, N, V } cannot express this, unfortunately.\n>\n> So let's do something like the attached patch, instead.\n\nThat's ok. We should not break anything.\n\nDo you want me to resubmit a new patch with the changes?\n\n> The patch adds OPT__VERBOSITY() that allows you to say \"-v -v\" to increase\n> verbosity (and \"-q -q\" to make it really quiet, although we do not use it\n> anywhere yet).\n>\n>  builtin-fetch.c |   19 +++++++++----------\n>  builtin-merge.c |   21 ++++++++++++++-------\n>  parse-options.c |   22 ++++++++++++++++++++++\n>  parse-options.h |    6 ++++++\n>  4 files changed, 51 insertions(+), 17 deletions(-)\n>\n> diff --git c/builtin-fetch.c w/builtin-fetch.c\n> index f151cfa..7568163 100644\n> --- c/builtin-fetch.c\n> +++ w/builtin-fetch.c\n> @@ -22,7 +22,7 @@ enum {\n>        TAGS_SET = 2\n>  };\n>\n> -static int append, force, keep, update_head_ok, verbose, quiet;\n> +static int append, force, keep, update_head_ok, verbosity;\n>  static int tags = TAGS_DEFAULT;\n>  static const char *depth;\n>  static const char *upload_pack;\n> @@ -30,8 +30,7 @@ static struct strbuf default_rla = STRBUF_INIT;\n>  static struct transport *transport;\n>\n>  static struct option builtin_fetch_options[] = {\n> -       OPT__QUIET(&quiet),\n> -       OPT__VERBOSE(&verbose),\n> +       OPT__VERBOSITY(&verbosity),\n>        OPT_BOOLEAN('a', \"append\", &append,\n>                    \"append to .git/FETCH_HEAD instead of overwriting\"),\n>        OPT_STRING(0, \"upload-pack\", &upload_pack, \"PATH\",\n> @@ -192,7 +191,6 @@ static int s_update_ref(const char *action,\n>\n>  static int update_local_ref(struct ref *ref,\n>                            const char *remote,\n> -                           int verbose,\n>                            char *display)\n>  {\n>        struct commit *current = NULL, *updated;\n> @@ -210,7 +208,7 @@ static int update_local_ref(struct ref *ref,\n>                die(\"object %s not found\", sha1_to_hex(ref->new_sha1));\n>\n>        if (!hashcmp(ref->old_sha1, ref->new_sha1)) {\n> -               if (verbose)\n> +               if (verbosity > 0)\n>                        sprintf(display, \"= %-*s %-*s -> %s\", SUMMARY_WIDTH,\n>                                \"[up to date]\", REFCOL_WIDTH, remote,\n>                                pretty_ref);\n> @@ -366,18 +364,19 @@ static int store_updated_refs(const char *url, const char *remote_name,\n>                        note);\n>\n>                if (ref)\n> -                       rc |= update_local_ref(ref, what, verbose, note);\n> +                       rc |= update_local_ref(ref, what, note);\n>                else\n>                        sprintf(note, \"* %-*s %-*s -> FETCH_HEAD\",\n>                                SUMMARY_WIDTH, *kind ? kind : \"branch\",\n>                                 REFCOL_WIDTH, *what ? what : \"HEAD\");\n>                if (*note) {\n> -                       if (!shown_url) {\n> +                       if (verbosity >= 0 && !shown_url) {\n>                                fprintf(stderr, \"From %.*s\\n\",\n>                                                url_len, url);\n>                                shown_url = 1;\n>                        }\n> -                       fprintf(stderr, \" %s\\n\", note);\n> +                       if (verbosity >= 0)\n> +                               fprintf(stderr, \" %s\\n\", note);\n>                }\n>        }\n>        fclose(fp);\n> @@ -637,9 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>                remote = remote_get(argv[0]);\n>\n>        transport = transport_get(remote, remote->url[0]);\n> -       if (verbose >= 2)\n> +       if (verbosity >= 2)\n>                transport->verbose = 1;\n> -       if (quiet)\n> +       if (verbosity < 0)\n>                transport->verbose = -1;\n>        if (upload_pack)\n>                set_option(TRANS_OPT_UPLOADPACK, upload_pack);\n> diff --git c/builtin-merge.c w/builtin-merge.c\n> index 5e7910b..7c2b90c 100644\n> --- c/builtin-merge.c\n> +++ w/builtin-merge.c\n> @@ -50,6 +50,7 @@ static unsigned char head[20], stash[20];\n>  static struct strategy **use_strategies;\n>  static size_t use_strategies_nr, use_strategies_alloc;\n>  static const char *branch;\n> +static int verbosity;\n>\n>  static struct strategy all_strategy[] = {\n>        { \"recursive\",  DEFAULT_TWOHEAD | NO_TRIVIAL },\n> @@ -171,6 +172,7 @@ static struct option builtin_merge_options[] = {\n>        OPT_CALLBACK('m', \"message\", &merge_msg, \"message\",\n>                \"message to be used for the merge commit (if any)\",\n>                option_parse_message),\n> +       OPT__VERBOSITY(&verbosity),\n>        OPT_END()\n>  };\n>\n> @@ -250,7 +252,8 @@ static void restore_state(void)\n>  /* This is called when no merge was necessary. */\n>  static void finish_up_to_date(const char *msg)\n>  {\n> -       printf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n> +       if (verbosity >= 0)\n> +               printf(\"%s%s\\n\", squash ? \" (nothing to squash)\" : \"\", msg);\n>        drop_save();\n>  }\n>\n> @@ -331,14 +334,15 @@ static void finish(const unsigned char *new_head, const char *msg)\n>        if (!msg)\n>                strbuf_addstr(&reflog_message, getenv(\"GIT_REFLOG_ACTION\"));\n>        else {\n> -               printf(\"%s\\n\", msg);\n> +               if (verbosity >= 0)\n> +                       printf(\"%s\\n\", msg);\n>                strbuf_addf(&reflog_message, \"%s: %s\",\n>                        getenv(\"GIT_REFLOG_ACTION\"), msg);\n>        }\n>        if (squash) {\n>                squash_message();\n>        } else {\n> -               if (!merge_msg.len)\n> +               if (verbosity >= 0 && !merge_msg.len)\n>                        printf(\"No merge message -- not updating HEAD\\n\");\n>                else {\n>                        const char *argv_gc_auto[] = { \"gc\", \"--auto\", NULL };\n> @@ -872,6 +876,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>\n>        argc = parse_options(argc, argv, builtin_merge_options,\n>                        builtin_merge_usage, 0);\n> +       if (verbosity < 0)\n> +               show_diffstat = 0;\n>\n>        if (squash) {\n>                if (!allow_fast_forward)\n> @@ -1013,10 +1019,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n>\n>                strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));\n>\n> -               printf(\"Updating %s..%s\\n\",\n> -                       hex,\n> -                       find_unique_abbrev(remoteheads->item->object.sha1,\n> -                       DEFAULT_ABBREV));\n> +               if (verbosity >= 0)\n> +                       printf(\"Updating %s..%s\\n\",\n> +                               hex,\n> +                               find_unique_abbrev(remoteheads->item->object.sha1,\n> +                               DEFAULT_ABBREV));\n>                strbuf_addstr(&msg, \"Fast forward\");\n>                if (have_message)\n>                        strbuf_addstr(&msg,\n> diff --git c/parse-options.c w/parse-options.c\n> index fd08bb4..9eb55cc 100644\n> --- c/parse-options.c\n> +++ w/parse-options.c\n> @@ -484,6 +484,28 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,\n>        return 0;\n>  }\n>\n> +int parse_opt_verbosity_cb(const struct option *opt, const char *arg,\n> +                          int unset)\n> +{\n> +       int *target = opt->value;\n> +\n> +       if (unset)\n> +               /* --no-quiet, --no-verbose */\n> +               *target = 0;\n> +       else if (opt->short_name == 'v') {\n> +               if (*target >= 0)\n> +                       (*target)++;\n> +               else\n> +                       *target = 1;\n> +       } else {\n> +               if (*target <= 0)\n> +                       (*target)--;\n> +               else\n> +                       *target = -1;\n> +       }\n> +       return 0;\n> +}\n> +\n>  /*\n>  * This should really be OPTION_FILENAME type as a part of\n>  * parse_options that take prefix to do this while parsing.\n> diff --git c/parse-options.h w/parse-options.h\n> index 5199950..034162e 100644\n> --- c/parse-options.h\n> +++ w/parse-options.h\n> @@ -150,9 +150,15 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx);\n>  /*----- some often used options -----*/\n>  extern int parse_opt_abbrev_cb(const struct option *, const char *, int);\n>  extern int parse_opt_approxidate_cb(const struct option *, const char *, int);\n> +extern int parse_opt_verbosity_cb(const struct option *, const char *, int);\n>\n>  #define OPT__VERBOSE(var)  OPT_BOOLEAN('v', \"verbose\", (var), \"be verbose\")\n>  #define OPT__QUIET(var)    OPT_BOOLEAN('q', \"quiet\",   (var), \"be quiet\")\n> +#define OPT__VERBOSITY(var) \\\n> +       { OPTION_CALLBACK, 'v', \"verbose\", (var), NULL, \"be more verbose\", \\\n> +         PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \\\n> +       { OPTION_CALLBACK, 'q', \"quiet\", (var), NULL, \"be more quiet\", \\\n> +         PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }\n>  #define OPT__DRY_RUN(var)  OPT_BOOLEAN('n', \"dry-run\", (var), \"dry run\")\n>  #define OPT__ABBREV(var)  \\\n>        { OPTION_CALLBACK, 0, \"abbrev\", (var), \"n\", \\\n>\n"},{"id":"95854","messageId":"7v3aht8z17.fsf@gitster.siamese.dyndns.org","threadId":"16337","inReplyTo":"4ac8254d0811141753y18567966h934a5701e168a7bd@mail.gmail.com","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-11-15T03:10:28Z","receivedAt":"2008-11-15T03:10:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Tuncer Ayaz\" <tuncer.ayaz@gmail.com> writes:\n\n>> The approach with enum { Q, N, V } cannot express this, unfortunately.\n>>\n>> So let's do something like the attached patch, instead.\n>\n> That's ok. We should not break anything.\n>\n> Do you want me to resubmit a new patch with the changes?\n\nAs long as you are happy with the suggested change, there is no need to.\nYou'd need to sign-off the patch, though...\n"},{"id":"95892","messageId":"4ac8254d0811150928o27cb309ard62cc7bb240522bb@mail.gmail.com","threadId":"16337","inReplyTo":"7v3aht8z17.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2008-11-15T17:28:24Z","receivedAt":"2008-11-15T17:28:24Z","isPatch":true,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Sat, Nov 15, 2008 at 4:10 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> \"Tuncer Ayaz\" <tuncer.ayaz@gmail.com> writes:\n>\n>>> The approach with enum { Q, N, V } cannot express this, unfortunately.\n>>>\n>>> So let's do something like the attached patch, instead.\n>>\n>> That's ok. We should not break anything.\n>>\n>> Do you want me to resubmit a new patch with the changes?\n>\n> As long as you are happy with the suggested change, there is no need to.\n> You'd need to sign-off the patch, though...\n>\n\nI forgot to add -s to my commit call this time around.\nI will apply your changes and repost it with the signoff.\n"},{"id":"95893","messageId":"4ac8254d0811150942s7d4f5444xbc2b068beecbb44f@mail.gmail.com","threadId":"16337","inReplyTo":"7v7i7594cx.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2008-11-15T17:42:18Z","receivedAt":"2008-11-15T17:42:18Z","isPatch":true,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Sat, Nov 15, 2008 at 2:15 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>>               remote = remote_get(argv[0]);\n>>\n>>       transport = transport_get(remote, remote->url[0]);\n>> -     if (verbose >= 2)\n>> +     if (verbosity == VERBOSE)\n>>               transport->verbose = 1;\n>> -     if (quiet)\n>> +     if (verbosity == QUIET)\n>>               transport->verbose = -1;\n>>       if (upload_pack)\n>>               set_option(TRANS_OPT_UPLOADPACK, upload_pack);\n>\n> In the original code, the variable verbose can be \">= 2\" when \"-v -v\" is\n> given, so transport->verbose is not turned on with a single \"-v\" alone\n> (this correctly mimics the original behaviour in the scripted version).\n>\n\nDoesn't this also mean that we need to be able to concatenate\nmultiple -v options in git-pull.sh similar to what one of the first\nversions of my patch did?\n\n<snip>\n"},{"id":"95898","messageId":"4ac8254d0811151116l5c52ef59k74927362c6556543@mail.gmail.com","threadId":"16337","inReplyTo":"4ac8254d0811150942s7d4f5444xbc2b068beecbb44f@mail.gmail.com","subject":"Re: [PATCH] Teach/Fix pull/fetch -q/-v options","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2008-11-15T19:16:28Z","receivedAt":"2008-11-15T19:16:28Z","isPatch":true,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Sat, Nov 15, 2008 at 6:42 PM, Tuncer Ayaz <tuncer.ayaz@gmail.com> wrote:\n> On Sat, Nov 15, 2008 at 2:15 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> @@ -637,9 +638,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)\n>>>               remote = remote_get(argv[0]);\n>>>\n>>>       transport = transport_get(remote, remote->url[0]);\n>>> -     if (verbose >= 2)\n>>> +     if (verbosity == VERBOSE)\n>>>               transport->verbose = 1;\n>>> -     if (quiet)\n>>> +     if (verbosity == QUIET)\n>>>               transport->verbose = -1;\n>>>       if (upload_pack)\n>>>               set_option(TRANS_OPT_UPLOADPACK, upload_pack);\n>>\n>> In the original code, the variable verbose can be \">= 2\" when \"-v -v\" is\n>> given, so transport->verbose is not turned on with a single \"-v\" alone\n>> (this correctly mimics the original behaviour in the scripted version).\n>>\n>\n> Doesn't this also mean that we need to be able to concatenate\n> multiple -v options in git-pull.sh similar to what one of the first\n> versions of my patch did?\n>\n> <snip>\n>\n\nThe next patch revision arriving here in a minute or two\nwill do the following in git-pull.sh:\n1) if -q then verbosity=-q\n2) if -v then verbosity=verbosity + -v\n\nThis means that git pull -v -q will reset verbosity to -q\nand allow counting of -v instances. If this is not desired\nor incorrect another change is needed :-).\n"}]}