{"thread":{"id":"47863","subject":"[PATCH 0/1] Colorize some errors on stderr","startedAt":"2018-02-16T12:25:54Z","lastAt":"2018-04-21T10:10:16Z","messageCount":22,"participants":["Johannes Schindelin","Junio C Hamano","Jacob Keller","Eric Sunshine","Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"339532","messageId":"cover.1518783709.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":null,"subject":"[PATCH 0/1] Colorize some errors on stderr","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-02-16T12:25:44Z","receivedAt":"2018-02-16T12:25:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This is an RFC because it tries to introduce a fundamental new color feature:\nColoring messages *on stderr*.\n\nSo far, pretty much everything in color.[ch] assumed that you want to color\nonly stuff on stdout.\n\nHowever, in this case, a user (who became a contributor!) wanted some messages\nthat are printed to stderr and were missed by his colleagues to be colored.\n\nThe contribution comes via Pull Request from the Git for Windows project:\n\n\thttps://github.com/git-for-windows/git/pull/1429\n\nNow, what would be possible solutions for this?\n\n- introduce `int fd` in `want_color()` (and callees) so that we can make\n  a distinction whether we want to detect whether stdout or stderr is connected\n  to a tty\n\n- introduce a separate `want_color_stderr()` (we still would need to decide\n  whether we want a config setting for this)\n\n- not color stderr, ever\n\nAlso, I did not have too much time to dig into the question how to test this in\nGit's test suite. Do we already have tests that generate fake server-side errors\nonto which I could piggy-back a new test case?\n\nThoughts? Suggestions? Help?\n\n\nRyan Dammrose (1):\n  Colorize push errors\n\n advice.c       | 42 +++++++++++++++++++++++++++++++++++++++--\n builtin/push.c | 38 +++++++++++++++++++++++++++++++++++++\n transport.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 136 insertions(+), 3 deletions(-)\n\n\nbase-commit: b2e45c695d09f6a31ce09347ae0a5d2cdfe9dd4e\nPublished-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v1\nFetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v1\n-- \n2.16.1.windows.4\n\n"},{"id":"339533","messageId":"cfdb79a05018ad113b43e620d86b4f667486ba5d.1518783709.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1518783709.git.johannes.schindelin@gmx.de","subject":"[PATCH 1/1] Colorize push errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-02-16T12:25:50Z","receivedAt":"2018-02-16T12:26:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Ryan Dammrose <ryandammrose@gmail.com>\n\nThis is an attempt to resolve an issue I experience with people that are\nnew to Git -- especially colleagues in a team setting -- where they miss\nthat their push to a remote location failed because the failure and\nsuccess both return a block of white text.\n\nAn example is if I push something to a remote repository and then a\ncolleague attempts to push to the same remote repository and the push\nfails because it requires them to pull first, but they don't notice\nbecause a success and failure both return a block of white text. They\nthen continue about their business, thinking it has been successfully\npushed.\n\nMy solution was to try to change the stderr and hint colors (red and\nyellow, respectively) so whenever there is a failure when pushing to a\nremote repository that fails, it is more noticeable.\n\nThe challenge was that it seemed that stderr has never been colored and\nI attempted to utilize what was already established; but this meant\nusing functions like want_color() even if it targets stdout while I\nwanted to target stderr.\n\nAdditionally, to check for all rejection types, I did a strstr check in\ntransport.c, but this code could be problematic if there is need for\ntranslation.\n\nSigned-off-by: Ryan Dammrose ryandammrose@gmail.com\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n advice.c       | 42 +++++++++++++++++++++++++++++++++++++++--\n builtin/push.c | 38 +++++++++++++++++++++++++++++++++++++\n transport.c    | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 136 insertions(+), 3 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 406efc183ba..42460877ef6 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"color.h\"\n \n int advice_push_update_rejected = 1;\n int advice_push_non_ff_current = 1;\n@@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1;\n int advice_ignored_hook = 1;\n int advice_waiting_for_editor = 1;\n \n+static int advice_use_color = -1;\n+static char advice_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_YELLOW,\t/* HINT */\n+};\n+\n+enum color_advice {\n+\tADVICE_COLOR_RESET = 0,\n+\tADVICE_COLOR_HINT = 1,\n+};\n+\n+static int parse_advise_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn ADVICE_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"advice\"))\n+\t\treturn ADVICE_COLOR_HINT;\n+\treturn -1;\n+}\n+\n+static const char *advise_get_color(enum color_advice ix)\n+{\n+\tif (want_color(advice_use_color))\n+\t\treturn advice_colors[ix];\n+\treturn \"\";\n+}\n+\n static struct {\n \tconst char *name;\n \tint *preference;\n@@ -59,7 +87,8 @@ void advise(const char *advice, ...)\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n-\t\tfprintf(stderr,\t_(\"hint: %.*s\\n\"), (int)(np - cp), cp);\n+\t\tfprintf(stderr,\t_(\"%shint: %.*s%s\\n\"), advise_get_color(ADVICE_COLOR_HINT),\n+\t\t\t(int)(np - cp), cp, advise_get_color(ADVICE_COLOR_RESET));\n \t\tif (*np)\n \t\t\tnp++;\n \t}\n@@ -68,9 +97,18 @@ void advise(const char *advice, ...)\n \n int git_default_advice_config(const char *var, const char *value)\n {\n-\tconst char *k;\n+\tconst char *k, *slot_name;\n \tint i;\n \n+\tif (skip_prefix(var, \"color.advice.\", &slot_name)) {\n+\t\tint slot = parse_advise_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\treturn color_parse(value, advice_colors[slot]);\n+\t}\n+\n \tif (!skip_prefix(var, \"advice.\", &k))\n \t\treturn 0;\n \ndiff --git a/builtin/push.c b/builtin/push.c\nindex 1c28427d82e..997ccab52ac 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -12,12 +12,40 @@\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n #include \"send-pack.h\"\n+#include \"color.h\"\n \n static const char * const push_usage[] = {\n \tN_(\"git push [<options>] [<repository> [<refspec>...]]\"),\n \tNULL,\n };\n \n+static int push_use_color = -1;\n+static char push_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED,\t/* ERROR */\n+};\n+\n+enum color_push {\n+\tPUSH_COLOR_RESET = 0,\n+\tPUSH_COLOR_ERROR = 1\n+};\n+\n+static int parse_push_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn PUSH_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"error\"))\n+\t\treturn PUSH_COLOR_ERROR;\n+\treturn -1;\n+}\n+\n+static const char *push_get_color(enum color_push ix)\n+{\n+\tif (want_color(push_use_color))\n+\t\treturn push_colors[ix];\n+\treturn \"\";\n+}\n+\n static int thin = 1;\n static int deleterefs;\n static const char *receivepack;\n@@ -338,7 +366,9 @@ static int push_with_options(struct transport *transport, int flags)\n \terr = transport_push(transport, refspec_nr, refspec, flags,\n \t\t\t     &reject_reasons);\n \tif (err != 0)\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_ERROR));\n \t\terror(_(\"failed to push some refs to '%s'\"), transport->url);\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_RESET));\n \n \terr |= transport_disconnect(transport);\n \tif (!err)\n@@ -467,6 +497,7 @@ static void set_push_cert_flags(int *flags, int v)\n \n static int git_push_config(const char *k, const char *v, void *cb)\n {\n+\tconst char *slot_name;\n \tint *flags = cb;\n \tint status;\n \n@@ -514,6 +545,13 @@ static int git_push_config(const char *k, const char *v, void *cb)\n \t\t\telse\n \t\t\t\tstring_list_append(&push_options_config, v);\n \t\treturn 0;\n+\t} else if (skip_prefix(k, \"color.advice.\", &slot_name)) {\n+\t\tint slot = parse_push_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!v)\n+\t\t\treturn config_error_nonbool(k);\n+\t\treturn color_parse(v, push_colors[slot]);\n \t}\n \n \treturn git_default_config(k, v, NULL);\ndiff --git a/transport.c b/transport.c\nindex 00d48b5b565..dd98dd84b05 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -18,6 +18,50 @@\n #include \"sha1-array.h\"\n #include \"sigchain.h\"\n #include \"transport-internal.h\"\n+#include \"color.h\"\n+\n+static int transport_use_color = -1;\n+static char transport_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED\t\t/* REJECTED */\n+};\n+\n+enum color_transport {\n+\tTRANSPORT_COLOR_RESET = 0,\n+\tTRANSPORT_COLOR_REJECTED = 1\n+};\n+\n+static int transport_color_config(void)\n+{\n+\tconst char *keys[] = {\n+\t\t\"transport.color.reset\",\n+\t\t\"transport.color.rejected\"\n+\t};\n+\tchar *value;\n+\tint i;\n+\tstatic int initialized;\n+\n+\tif (initialized)\n+\t\treturn 0;\n+\tinitialized = 1;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(keys); i++)\n+\t\tif (!git_config_get_string(keys[i], &value)) {\n+\t\t\tif (!value)\n+\t\t\t\treturn config_error_nonbool(keys[i]);\n+\t\t\tif (color_parse(value, transport_colors[i]) < 0)\n+\t\t\t\treturn -1;\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+static const char *transport_get_color(enum color_transport ix)\n+{\n+\tif (want_color(transport_use_color))\n+\t\treturn transport_colors[ix];\n+\treturn \"\";\n+}\n \n static void set_upstreams(struct transport *transport, struct ref *refs,\n \tint pretend)\n@@ -338,7 +382,11 @@ static void print_ref_status(char flag, const char *summary,\n \t\telse\n \t\t\tfprintf(stdout, \"%s\\n\", summary);\n \t} else {\n-\t\tfprintf(stderr, \" %c %-*s \", flag, summary_width, summary);\n+\t\tif (strstr(summary, \"rejected\") != NULL || strstr(summary, \"failure\") != NULL)\n+\t\t\tfprintf(stderr, \" %s%c %-*s%s \", transport_get_color(TRANSPORT_COLOR_REJECTED),\n+\t\t\t\tflag, summary_width, summary, transport_get_color(TRANSPORT_COLOR_RESET));\n+\t\telse\n+\t\t\tfprintf(stderr, \" %c %-*s \", flag, summary_width, summary);\n \t\tif (from)\n \t\t\tfprintf(stderr, \"%s -> %s\", prettify_refname(from->name), prettify_refname(to->name));\n \t\telse\n@@ -487,6 +535,9 @@ void transport_print_push_status(const char *dest, struct ref *refs,\n \tchar *head;\n \tint summary_width = transport_summary_width(refs);\n \n+\tif (transport_color_config() < 0)\n+\t\twarning(_(\"could not parse transport.color.* config\"));\n+\n \thead = resolve_refdup(\"HEAD\", RESOLVE_REF_READING, NULL, NULL);\n \n \tif (verbose) {\n@@ -553,6 +604,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re\n \tstruct send_pack_args args;\n \tint ret;\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (!data->got_remote_heads) {\n \t\tstruct ref *tmp_refs;\n \t\tconnect_setup(transport, 1);\n@@ -997,6 +1051,9 @@ int transport_push(struct transport *transport,\n \t*reject_reasons = 0;\n \ttransport_verify_remote_names(refspec_nr, refspec);\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (transport->vtable->push_refs) {\n \t\tstruct ref *remote_refs;\n \t\tstruct ref *local_refs = get_local_heads();\n-- \n2.16.1.windows.4\n"},{"id":"339570","messageId":"xmqqwozc68r2.fsf@gitster-ct.c.googlers.com","threadId":"47863","inReplyTo":"cover.1518783709.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 0/1] Colorize some errors on stderr","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-02-16T19:21:21Z","receivedAt":"2018-02-16T19:21:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Now, what would be possible solutions for this?\n>\n> - introduce `int fd` in `want_color()` (and callees) so that we can make\n>   a distinction whether we want to detect whether stdout or stderr is connected\n>   to a tty\n>\n> - introduce a separate `want_color_stderr()` (we still would need to decide\n>   whether we want a config setting for this)\n\nBetween the above two, there probably aren't so big a difference, but\nin order to avoid disrupting existing callers of want_color() while\npossibly sharing as much code between the old and new callers,\nperhaps:\n\n\textern int want_color_fd(int fd, int colorbool);\n\t#define want_color(colorbool) want_color_fd(1, (colorbool))\n\t#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))\n\nWe should honor configuration at two levels, just like the colors on\nstdout, i.e. color in which individual items are painted (e.g.\ncolor.diff.filename, color.advice.hint) and whether we use colors in\nUI at all (e.g. color.ui).  I do not think it is necessary or even\nat the right granularity to allow settings like \"do color stdout but\ndo not color errors\".\n\n> - not color stderr, ever\n\nThis is my personal preference, but that does not and should not\ncarry too much weight ;-)\n"},{"id":"343911","messageId":"cover.1522968472.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1518783709.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 0/4] Colorize push errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-05T22:48:33Z","receivedAt":"2018-04-05T22:48:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"To help users discern large chunks of white text (when the push\nsucceeds) from large chunks of white text (when the push fails), let's\nadd some color to the latter.\n\nThe original contribution came in via Pull Request from the Git for\nWindows project:\n\n\thttps://github.com/git-for-windows/git/pull/1429\n\nChanges since v1:\n\n- implemented want_color_fd() as suggested by Junio\n\n- added color.{advice,push,transport} to be able to force this thing on\n\n- added a test\n\n- added documentation to `git config`'s man page\n\n- fixed a bug where the push config looked at color.advice.<slot>\n\n- fixed a bug where `color.advise.<slot>` was not parsed because\n  git_default_config() would fail to hand `color.advise.*` settings to\n  git_default_advice_config()\n\n- wrapped a couple of too-long lines\n\n- changed the strstr() hack to detect push failures to use push_had_errors()\n  instead\n\n- renamed the transport.color.* settings to color.transport.* (to make them\n  consistent with all the other color.<category>.<slot> settings)\n\n\nJohannes Schindelin (3):\n  color: introduce support for colorizing stderr\n  Add a test to verify that push errors are colorful\n  Document the new color.* settings to colorize push errors/hints\n\nRyan Dammrose (1):\n  push: colorize errors\n\n Documentation/config.txt   | 28 ++++++++++++++++\n advice.c                   | 49 ++++++++++++++++++++++++++--\n builtin/push.c             | 44 ++++++++++++++++++++++++-\n color.c                    | 20 +++++++-----\n color.h                    |  4 ++-\n config.c                   |  2 +-\n t/t5541-http-push-smart.sh | 18 ++++++++++\n transport.c                | 67 +++++++++++++++++++++++++++++++++++++-\n 8 files changed, 217 insertions(+), 15 deletions(-)\n\n\nbase-commit: 468165c1d8a442994a825f3684528361727cd8c0\nPublished-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v2\nFetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v2\n\nInterdiff vs v1:\n diff --git a/Documentation/config.txt b/Documentation/config.txt\n index 4e0cff87f62..40e3828b85f 100644\n --- a/Documentation/config.txt\n +++ b/Documentation/config.txt\n @@ -1088,6 +1088,16 @@ clean.requireForce::\n  \tA boolean to make git-clean do nothing unless given -f,\n  \t-i or -n.   Defaults to true.\n  \n +color.advice::\n +\tA boolean to enable/disable color in hints (e.g. when a push\n +\tfailed, see `advice.*` for a list).  May be set to `always`,\n +\t`false` (or `never`) or `auto` (or `true`), in which case colors\n +\tare used only when the error output goes to a terminal. If\n +\tunset, then the value of `color.ui` is used (`auto` by default).\n +\n +color.advice.advice::\n +\tUse customized color for hints.\n +\n  color.branch::\n  \tA boolean to enable/disable color in the output of\n  \tlinkgit:git-branch[1]. May be set to `always`,\n @@ -1190,6 +1200,15 @@ color.pager::\n  \tA boolean to enable/disable colored output when the pager is in\n  \tuse (default is true).\n  \n +color.push::\n +\tA boolean to enable/disable color in push errors. May be set to\n +\t`always`, `false` (or `never`) or `auto` (or `true`), in which\n +\tcase colors are used only when the error output goes to a terminal.\n +\tIf unset, then the value of `color.ui` is used (`auto` by default).\n +\n +color.push.error::\n +\tUse customized color for push errors.\n +\n  color.showBranch::\n  \tA boolean to enable/disable color in the output of\n  \tlinkgit:git-show-branch[1]. May be set to `always`,\n @@ -1218,6 +1237,15 @@ color.status.<slot>::\n  \tstatus short-format), or\n  \t`unmerged` (files which have unmerged changes).\n  \n +color.transport::\n +\tA boolean to enable/disable color when pushes are rejected. May be\n +\tset to `always`, `false` (or `never`) or `auto` (or `true`), in which\n +\tcase colors are used only when the error output goes to a terminal.\n +\tIf unset, then the value of `color.ui` is used (`auto` by default).\n +\n +color.transport.rejected::\n +\tUse customized color when a push was rejected.\n +\n  color.ui::\n  \tThis variable determines the default value for variables such\n  \tas `color.diff` and `color.grep` that control the use of color\n diff --git a/advice.c b/advice.c\n index 42460877ef6..2121c1811fd 100644\n --- a/advice.c\n +++ b/advice.c\n @@ -43,7 +43,7 @@ static int parse_advise_color_slot(const char *slot)\n  \n  static const char *advise_get_color(enum color_advice ix)\n  {\n -\tif (want_color(advice_use_color))\n +\tif (want_color_stderr(advice_use_color))\n  \t\treturn advice_colors[ix];\n  \treturn \"\";\n  }\n @@ -87,8 +87,10 @@ void advise(const char *advice, ...)\n  \n  \tfor (cp = buf.buf; *cp; cp = np) {\n  \t\tnp = strchrnul(cp, '\\n');\n -\t\tfprintf(stderr,\t_(\"%shint: %.*s%s\\n\"), advise_get_color(ADVICE_COLOR_HINT),\n -\t\t\t(int)(np - cp), cp, advise_get_color(ADVICE_COLOR_RESET));\n +\t\tfprintf(stderr,\t_(\"%shint: %.*s%s\\n\"),\n +\t\t\tadvise_get_color(ADVICE_COLOR_HINT),\n +\t\t\t(int)(np - cp), cp,\n +\t\t\tadvise_get_color(ADVICE_COLOR_RESET));\n  \t\tif (*np)\n  \t\t\tnp++;\n  \t}\n @@ -100,6 +102,11 @@ int git_default_advice_config(const char *var, const char *value)\n  \tconst char *k, *slot_name;\n  \tint i;\n  \n +\tif (!strcmp(var, \"color.advice\")) {\n +\t\tadvice_use_color = git_config_colorbool(var, value);\n +\t\treturn 0;\n +\t}\n +\n  \tif (skip_prefix(var, \"color.advice.\", &slot_name)) {\n  \t\tint slot = parse_advise_color_slot(slot_name);\n  \t\tif (slot < 0)\n diff --git a/builtin/push.c b/builtin/push.c\n index e443dd40de9..ac3705370e1 100644\n --- a/builtin/push.c\n +++ b/builtin/push.c\n @@ -41,7 +41,7 @@ static int parse_push_color_slot(const char *slot)\n  \n  static const char *push_get_color(enum color_push ix)\n  {\n -\tif (want_color(push_use_color))\n +\tif (want_color_stderr(push_use_color))\n  \t\treturn push_colors[ix];\n  \treturn \"\";\n  }\n @@ -365,10 +365,11 @@ static int push_with_options(struct transport *transport, int flags)\n  \t\tfprintf(stderr, _(\"Pushing to %s\\n\"), transport->url);\n  \terr = transport_push(transport, refspec_nr, refspec, flags,\n  \t\t\t     &reject_reasons);\n -\tif (err != 0)\n +\tif (err != 0) {\n  \t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_ERROR));\n  \t\terror(_(\"failed to push some refs to '%s'\"), transport->url);\n  \t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_RESET));\n +\t}\n  \n  \terr |= transport_disconnect(transport);\n  \tif (!err)\n @@ -545,7 +546,10 @@ static int git_push_config(const char *k, const char *v, void *cb)\n  \t\t\telse\n  \t\t\t\tstring_list_append(&push_options_config, v);\n  \t\treturn 0;\n -\t} else if (skip_prefix(k, \"color.advice.\", &slot_name)) {\n +\t} else if (!strcmp(k, \"color.push\")) {\n +\t\tpush_use_color = git_config_colorbool(k, v);\n +\t\treturn 0;\n +\t} else if (skip_prefix(k, \"color.push.\", &slot_name)) {\n  \t\tint slot = parse_push_color_slot(slot_name);\n  \t\tif (slot < 0)\n  \t\t\treturn 0;\n diff --git a/color.c b/color.c\n index f277e72e4ce..c6c6c4f580f 100644\n --- a/color.c\n +++ b/color.c\n @@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value)\n  \treturn GIT_COLOR_AUTO;\n  }\n  \n -static int check_auto_color(void)\n +static int check_auto_color(int fd)\n  {\n -\tif (color_stdout_is_tty < 0)\n -\t\tcolor_stdout_is_tty = isatty(1);\n -\tif (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {\n +\tstatic int color_stderr_is_tty = -1;\n +\tint *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;\n +\tif (*is_tty_p < 0)\n +\t\t*is_tty_p = isatty(fd);\n +\tif (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {\n  \t\tif (!is_terminal_dumb())\n  \t\t\treturn 1;\n  \t}\n  \treturn 0;\n  }\n  \n -int want_color(int var)\n +int want_color_fd(int fd, int var)\n  {\n  \t/*\n  \t * NEEDSWORK: This function is sometimes used from multiple threads, and\n @@ -339,15 +341,15 @@ int want_color(int var)\n  \t * is listed in .tsan-suppressions for the time being.\n  \t */\n  \n -\tstatic int want_auto = -1;\n +\tstatic int want_auto[3] = { -1, -1, -1 };\n  \n  \tif (var < 0)\n  \t\tvar = git_use_color_default;\n  \n  \tif (var == GIT_COLOR_AUTO) {\n -\t\tif (want_auto < 0)\n -\t\t\twant_auto = check_auto_color();\n -\t\treturn want_auto;\n +\t\tif (want_auto[fd] < 0)\n +\t\t\twant_auto[fd] = check_auto_color(fd);\n +\t\treturn want_auto[fd];\n  \t}\n  \treturn var;\n  }\n diff --git a/color.h b/color.h\n index cd0bcedd084..5b744e1bc68 100644\n --- a/color.h\n +++ b/color.h\n @@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value);\n   * Return a boolean whether to use color, where the argument 'var' is\n   * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO.\n   */\n -int want_color(int var);\n +int want_color_fd(int fd, int var);\n +#define want_color(colorbool) want_color_fd(1, (colorbool))\n +#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))\n  \n  /*\n   * Translate a Git color from 'value' into a string that the terminal can\n diff --git a/config.c b/config.c\n index b0c20e6cb8a..3bdbe36a638 100644\n --- a/config.c\n +++ b/config.c\n @@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy)\n  \tif (starts_with(var, \"mailmap.\"))\n  \t\treturn git_default_mailmap_config(var, value);\n  \n -\tif (starts_with(var, \"advice.\"))\n +\tif (starts_with(var, \"advice.\") || starts_with(var, \"color.advice\"))\n  \t\treturn git_default_advice_config(var, value);\n  \n  \tif (!strcmp(var, \"pager.color\") || !strcmp(var, \"color.pager\")) {\n diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\n index 21340e89c96..1c2be98dc2b 100755\n --- a/t/t5541-http-push-smart.sh\n +++ b/t/t5541-http-push-smart.sh\n @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' '\n  \tgrep \"^To $HTTPD_URL/smart/test_repo.git\" status\n  '\n  \n +test_expect_success 'colorize errors/hints' '\n +\tcd \"$ROOT_PATH\"/test_repo_clone &&\n +\tcat >exp <<-EOF &&\n +\tTo http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git\n +\t <RED>! [rejected]       <RESET> origin/master^ -> master (non-fast-forward)\n +\terror: failed to push some refs to '\\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\\''\n +\tEOF\n +\n +\ttest_must_fail git -c color.transport=always -c color.advice=always \\\n +\t\t-c color.push=always \\\n +\t\tpush origin origin/master^:master 2>act &&\n +\ttest_decode_color <act >decoded &&\n +\ttest_i18ngrep \"<RED>.*rejected.*<RESET>\" decoded &&\n +\ttest_i18ngrep \"<RED>error: failed to push some refs\" decoded &&\n +\ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n +\ttest_i18ngrep ! \"^hint: \" decoded\n +'\n +\n  stop_httpd\n  test_done\n diff --git a/transport.c b/transport.c\n index dd98dd84b05..4702b9fbc8f 100644\n --- a/transport.c\n +++ b/transport.c\n @@ -34,9 +34,9 @@ enum color_transport {\n  static int transport_color_config(void)\n  {\n  \tconst char *keys[] = {\n -\t\t\"transport.color.reset\",\n -\t\t\"transport.color.rejected\"\n -\t};\n +\t\t\"color.transport.reset\",\n +\t\t\"color.transport.rejected\"\n +\t}, *key = \"color.transport\";\n  \tchar *value;\n  \tint i;\n  \tstatic int initialized;\n @@ -45,6 +45,12 @@ static int transport_color_config(void)\n  \t\treturn 0;\n  \tinitialized = 1;\n  \n +\tif (!git_config_get_string(key, &value))\n +\t\ttransport_use_color = git_config_colorbool(key, value);\n +\n +\tif (!want_color_stderr(transport_use_color))\n +\t\treturn 0;\n +\n  \tfor (i = 0; i < ARRAY_SIZE(keys); i++)\n  \t\tif (!git_config_get_string(keys[i], &value)) {\n  \t\t\tif (!value)\n @@ -58,7 +64,7 @@ static int transport_color_config(void)\n  \n  static const char *transport_get_color(enum color_transport ix)\n  {\n -\tif (want_color(transport_use_color))\n +\tif (want_color_stderr(transport_use_color))\n  \t\treturn transport_colors[ix];\n  \treturn \"\";\n  }\n @@ -382,11 +388,13 @@ static void print_ref_status(char flag, const char *summary,\n  \t\telse\n  \t\t\tfprintf(stdout, \"%s\\n\", summary);\n  \t} else {\n -\t\tif (strstr(summary, \"rejected\") != NULL || strstr(summary, \"failure\") != NULL)\n -\t\t\tfprintf(stderr, \" %s%c %-*s%s \", transport_get_color(TRANSPORT_COLOR_REJECTED),\n -\t\t\t\tflag, summary_width, summary, transport_get_color(TRANSPORT_COLOR_RESET));\n -\t\telse\n -\t\t\tfprintf(stderr, \" %c %-*s \", flag, summary_width, summary);\n +\t\tconst char *red = \"\", *reset = \"\";\n +\t\tif (push_had_errors(to)) {\n +\t\t\tred = transport_get_color(TRANSPORT_COLOR_REJECTED);\n +\t\t\treset = transport_get_color(TRANSPORT_COLOR_RESET);\n +\t\t}\n +\t\tfprintf(stderr, \" %s%c %-*s%s \", red, flag, summary_width,\n +\t\t\tsummary, reset);\n  \t\tif (from)\n  \t\t\tfprintf(stderr, \"%s -> %s\", prettify_refname(from->name), prettify_refname(to->name));\n  \t\telse\n-- \n2.17.0.windows.1.4.g7e4058d72e3\n\n"},{"id":"343912","messageId":"8cae2e4c924bab3696f2cf72c4dc4ec49b893c0b.1522968472.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1522968472.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 1/4] color: introduce support for colorizing stderr","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-05T22:48:38Z","receivedAt":"2018-04-05T22:48:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"So far, we only ever asked whether stdout wants to be colorful. In the\nupcoming patches, we will want to make push errors more prominent, which\nare printed to stderr, though.\n\nSo let's refactor the want_color() function into a want_color_fd()\nfunction (which expects to be called with fd == 1 or fd == 2 for stdout\nand stderr, respectively), and then define the macro `want_color()` to\nuse the want_color_fd() function.\n\nAnd then also add a macro `want_color_stderr()`, for convenience and\nfor documentation.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n color.c | 20 +++++++++++---------\n color.h |  4 +++-\n 2 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/color.c b/color.c\nindex f277e72e4ce..c6c6c4f580f 100644\n--- a/color.c\n+++ b/color.c\n@@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value)\n \treturn GIT_COLOR_AUTO;\n }\n \n-static int check_auto_color(void)\n+static int check_auto_color(int fd)\n {\n-\tif (color_stdout_is_tty < 0)\n-\t\tcolor_stdout_is_tty = isatty(1);\n-\tif (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {\n+\tstatic int color_stderr_is_tty = -1;\n+\tint *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;\n+\tif (*is_tty_p < 0)\n+\t\t*is_tty_p = isatty(fd);\n+\tif (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {\n \t\tif (!is_terminal_dumb())\n \t\t\treturn 1;\n \t}\n \treturn 0;\n }\n \n-int want_color(int var)\n+int want_color_fd(int fd, int var)\n {\n \t/*\n \t * NEEDSWORK: This function is sometimes used from multiple threads, and\n@@ -339,15 +341,15 @@ int want_color(int var)\n \t * is listed in .tsan-suppressions for the time being.\n \t */\n \n-\tstatic int want_auto = -1;\n+\tstatic int want_auto[3] = { -1, -1, -1 };\n \n \tif (var < 0)\n \t\tvar = git_use_color_default;\n \n \tif (var == GIT_COLOR_AUTO) {\n-\t\tif (want_auto < 0)\n-\t\t\twant_auto = check_auto_color();\n-\t\treturn want_auto;\n+\t\tif (want_auto[fd] < 0)\n+\t\t\twant_auto[fd] = check_auto_color(fd);\n+\t\treturn want_auto[fd];\n \t}\n \treturn var;\n }\ndiff --git a/color.h b/color.h\nindex cd0bcedd084..5b744e1bc68 100644\n--- a/color.h\n+++ b/color.h\n@@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value);\n  * Return a boolean whether to use color, where the argument 'var' is\n  * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO.\n  */\n-int want_color(int var);\n+int want_color_fd(int fd, int var);\n+#define want_color(colorbool) want_color_fd(1, (colorbool))\n+#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))\n \n /*\n  * Translate a Git color from 'value' into a string that the terminal can\n-- \n2.17.0.windows.1.4.g7e4058d72e3\n\n\n"},{"id":"343913","messageId":"b2771f9d8e441b6f902924a3b4f037b3874e4191.1522968472.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1522968472.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 2/4] push: colorize errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-05T22:48:44Z","receivedAt":"2018-04-05T22:48:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Ryan Dammrose <ryandammrose@gmail.com>\n\nThis is an attempt to resolve an issue I experience with people that are\nnew to Git -- especially colleagues in a team setting -- where they miss\nthat their push to a remote location failed because the failure and\nsuccess both return a block of white text.\n\nAn example is if I push something to a remote repository and then a\ncolleague attempts to push to the same remote repository and the push\nfails because it requires them to pull first, but they don't notice\nbecause a success and failure both return a block of white text. They\nthen continue about their business, thinking it has been successfully\npushed.\n\nThis patch colorizes the errors and hints (in red and yellow,\nrespectively) so whenever there is a failure when pushing to a remote\nrepository that fails, it is more noticeable.\n\n[jes: fixed a couple bugs, added the color.{advice,push,transport}\nsettings, refactored to use want_color_stderr().]\n\nSigned-off-by: Ryan Dammrose ryandammrose@gmail.com\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n\nsquash! push: colorize errors\n\nStop talking about localized errors\n---\n advice.c       | 49 ++++++++++++++++++++++++++++++++++--\n builtin/push.c | 44 ++++++++++++++++++++++++++++++++-\n config.c       |  2 +-\n transport.c    | 67 +++++++++++++++++++++++++++++++++++++++++++++++++-\n 4 files changed, 157 insertions(+), 5 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 406efc183ba..2121c1811fd 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"color.h\"\n \n int advice_push_update_rejected = 1;\n int advice_push_non_ff_current = 1;\n@@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1;\n int advice_ignored_hook = 1;\n int advice_waiting_for_editor = 1;\n \n+static int advice_use_color = -1;\n+static char advice_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_YELLOW,\t/* HINT */\n+};\n+\n+enum color_advice {\n+\tADVICE_COLOR_RESET = 0,\n+\tADVICE_COLOR_HINT = 1,\n+};\n+\n+static int parse_advise_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn ADVICE_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"advice\"))\n+\t\treturn ADVICE_COLOR_HINT;\n+\treturn -1;\n+}\n+\n+static const char *advise_get_color(enum color_advice ix)\n+{\n+\tif (want_color_stderr(advice_use_color))\n+\t\treturn advice_colors[ix];\n+\treturn \"\";\n+}\n+\n static struct {\n \tconst char *name;\n \tint *preference;\n@@ -59,7 +87,10 @@ void advise(const char *advice, ...)\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n-\t\tfprintf(stderr,\t_(\"hint: %.*s\\n\"), (int)(np - cp), cp);\n+\t\tfprintf(stderr,\t_(\"%shint: %.*s%s\\n\"),\n+\t\t\tadvise_get_color(ADVICE_COLOR_HINT),\n+\t\t\t(int)(np - cp), cp,\n+\t\t\tadvise_get_color(ADVICE_COLOR_RESET));\n \t\tif (*np)\n \t\t\tnp++;\n \t}\n@@ -68,9 +99,23 @@ void advise(const char *advice, ...)\n \n int git_default_advice_config(const char *var, const char *value)\n {\n-\tconst char *k;\n+\tconst char *k, *slot_name;\n \tint i;\n \n+\tif (!strcmp(var, \"color.advice\")) {\n+\t\tadvice_use_color = git_config_colorbool(var, value);\n+\t\treturn 0;\n+\t}\n+\n+\tif (skip_prefix(var, \"color.advice.\", &slot_name)) {\n+\t\tint slot = parse_advise_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\treturn color_parse(value, advice_colors[slot]);\n+\t}\n+\n \tif (!skip_prefix(var, \"advice.\", &k))\n \t\treturn 0;\n \ndiff --git a/builtin/push.c b/builtin/push.c\nindex 013c20d6164..ac3705370e1 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -12,12 +12,40 @@\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n #include \"send-pack.h\"\n+#include \"color.h\"\n \n static const char * const push_usage[] = {\n \tN_(\"git push [<options>] [<repository> [<refspec>...]]\"),\n \tNULL,\n };\n \n+static int push_use_color = -1;\n+static char push_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED,\t/* ERROR */\n+};\n+\n+enum color_push {\n+\tPUSH_COLOR_RESET = 0,\n+\tPUSH_COLOR_ERROR = 1\n+};\n+\n+static int parse_push_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn PUSH_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"error\"))\n+\t\treturn PUSH_COLOR_ERROR;\n+\treturn -1;\n+}\n+\n+static const char *push_get_color(enum color_push ix)\n+{\n+\tif (want_color_stderr(push_use_color))\n+\t\treturn push_colors[ix];\n+\treturn \"\";\n+}\n+\n static int thin = 1;\n static int deleterefs;\n static const char *receivepack;\n@@ -337,8 +365,11 @@ static int push_with_options(struct transport *transport, int flags)\n \t\tfprintf(stderr, _(\"Pushing to %s\\n\"), transport->url);\n \terr = transport_push(transport, refspec_nr, refspec, flags,\n \t\t\t     &reject_reasons);\n-\tif (err != 0)\n+\tif (err != 0) {\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_ERROR));\n \t\terror(_(\"failed to push some refs to '%s'\"), transport->url);\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_RESET));\n+\t}\n \n \terr |= transport_disconnect(transport);\n \tif (!err)\n@@ -467,6 +498,7 @@ static void set_push_cert_flags(int *flags, int v)\n \n static int git_push_config(const char *k, const char *v, void *cb)\n {\n+\tconst char *slot_name;\n \tint *flags = cb;\n \tint status;\n \n@@ -514,6 +546,16 @@ static int git_push_config(const char *k, const char *v, void *cb)\n \t\t\telse\n \t\t\t\tstring_list_append(&push_options_config, v);\n \t\treturn 0;\n+\t} else if (!strcmp(k, \"color.push\")) {\n+\t\tpush_use_color = git_config_colorbool(k, v);\n+\t\treturn 0;\n+\t} else if (skip_prefix(k, \"color.push.\", &slot_name)) {\n+\t\tint slot = parse_push_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!v)\n+\t\t\treturn config_error_nonbool(k);\n+\t\treturn color_parse(v, push_colors[slot]);\n \t}\n \n \treturn git_default_config(k, v, NULL);\ndiff --git a/config.c b/config.c\nindex b0c20e6cb8a..3bdbe36a638 100644\n--- a/config.c\n+++ b/config.c\n@@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy)\n \tif (starts_with(var, \"mailmap.\"))\n \t\treturn git_default_mailmap_config(var, value);\n \n-\tif (starts_with(var, \"advice.\"))\n+\tif (starts_with(var, \"advice.\") || starts_with(var, \"color.advice\"))\n \t\treturn git_default_advice_config(var, value);\n \n \tif (!strcmp(var, \"pager.color\") || !strcmp(var, \"color.pager\")) {\ndiff --git a/transport.c b/transport.c\nindex 00d48b5b565..4702b9fbc8f 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -18,6 +18,56 @@\n #include \"sha1-array.h\"\n #include \"sigchain.h\"\n #include \"transport-internal.h\"\n+#include \"color.h\"\n+\n+static int transport_use_color = -1;\n+static char transport_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED\t\t/* REJECTED */\n+};\n+\n+enum color_transport {\n+\tTRANSPORT_COLOR_RESET = 0,\n+\tTRANSPORT_COLOR_REJECTED = 1\n+};\n+\n+static int transport_color_config(void)\n+{\n+\tconst char *keys[] = {\n+\t\t\"color.transport.reset\",\n+\t\t\"color.transport.rejected\"\n+\t}, *key = \"color.transport\";\n+\tchar *value;\n+\tint i;\n+\tstatic int initialized;\n+\n+\tif (initialized)\n+\t\treturn 0;\n+\tinitialized = 1;\n+\n+\tif (!git_config_get_string(key, &value))\n+\t\ttransport_use_color = git_config_colorbool(key, value);\n+\n+\tif (!want_color_stderr(transport_use_color))\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(keys); i++)\n+\t\tif (!git_config_get_string(keys[i], &value)) {\n+\t\t\tif (!value)\n+\t\t\t\treturn config_error_nonbool(keys[i]);\n+\t\t\tif (color_parse(value, transport_colors[i]) < 0)\n+\t\t\t\treturn -1;\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+static const char *transport_get_color(enum color_transport ix)\n+{\n+\tif (want_color_stderr(transport_use_color))\n+\t\treturn transport_colors[ix];\n+\treturn \"\";\n+}\n \n static void set_upstreams(struct transport *transport, struct ref *refs,\n \tint pretend)\n@@ -338,7 +388,13 @@ static void print_ref_status(char flag, const char *summary,\n \t\telse\n \t\t\tfprintf(stdout, \"%s\\n\", summary);\n \t} else {\n-\t\tfprintf(stderr, \" %c %-*s \", flag, summary_width, summary);\n+\t\tconst char *red = \"\", *reset = \"\";\n+\t\tif (push_had_errors(to)) {\n+\t\t\tred = transport_get_color(TRANSPORT_COLOR_REJECTED);\n+\t\t\treset = transport_get_color(TRANSPORT_COLOR_RESET);\n+\t\t}\n+\t\tfprintf(stderr, \" %s%c %-*s%s \", red, flag, summary_width,\n+\t\t\tsummary, reset);\n \t\tif (from)\n \t\t\tfprintf(stderr, \"%s -> %s\", prettify_refname(from->name), prettify_refname(to->name));\n \t\telse\n@@ -487,6 +543,9 @@ void transport_print_push_status(const char *dest, struct ref *refs,\n \tchar *head;\n \tint summary_width = transport_summary_width(refs);\n \n+\tif (transport_color_config() < 0)\n+\t\twarning(_(\"could not parse transport.color.* config\"));\n+\n \thead = resolve_refdup(\"HEAD\", RESOLVE_REF_READING, NULL, NULL);\n \n \tif (verbose) {\n@@ -553,6 +612,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re\n \tstruct send_pack_args args;\n \tint ret;\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (!data->got_remote_heads) {\n \t\tstruct ref *tmp_refs;\n \t\tconnect_setup(transport, 1);\n@@ -997,6 +1059,9 @@ int transport_push(struct transport *transport,\n \t*reject_reasons = 0;\n \ttransport_verify_remote_names(refspec_nr, refspec);\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (transport->vtable->push_refs) {\n \t\tstruct ref *remote_refs;\n \t\tstruct ref *local_refs = get_local_heads();\n-- \n2.17.0.windows.1.4.g7e4058d72e3\n\n\n"},{"id":"343914","messageId":"021133cae0d27359a5e3ee520fc26f58b7030f59.1522968472.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1522968472.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 3/4] Add a test to verify that push errors are colorful","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-05T22:48:48Z","receivedAt":"2018-04-05T22:49:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This actually only tests whether the push errors/hints are colored if\nthe respective color.* config settings are `always`, but in the regular\ncase they default to `auto` (in which case we color the messages when\nstderr is connected to an interactive terminal), therefore these tests\nshould suffice.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t5541-http-push-smart.sh | 18 ++++++++++++++++++\n 1 file changed, 18 insertions(+)\n\ndiff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\nindex 21340e89c96..1c2be98dc2b 100755\n--- a/t/t5541-http-push-smart.sh\n+++ b/t/t5541-http-push-smart.sh\n@@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' '\n \tgrep \"^To $HTTPD_URL/smart/test_repo.git\" status\n '\n \n+test_expect_success 'colorize errors/hints' '\n+\tcd \"$ROOT_PATH\"/test_repo_clone &&\n+\tcat >exp <<-EOF &&\n+\tTo http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git\n+\t <RED>! [rejected]       <RESET> origin/master^ -> master (non-fast-forward)\n+\terror: failed to push some refs to '\\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\\''\n+\tEOF\n+\n+\ttest_must_fail git -c color.transport=always -c color.advice=always \\\n+\t\t-c color.push=always \\\n+\t\tpush origin origin/master^:master 2>act &&\n+\ttest_decode_color <act >decoded &&\n+\ttest_i18ngrep \"<RED>.*rejected.*<RESET>\" decoded &&\n+\ttest_i18ngrep \"<RED>error: failed to push some refs\" decoded &&\n+\ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n+\ttest_i18ngrep ! \"^hint: \" decoded\n+'\n+\n stop_httpd\n test_done\n-- \n2.17.0.windows.1.4.g7e4058d72e3\n\n\n"},{"id":"343915","messageId":"516b28e82ace0a0b6831c644f246c19dad1187ac.1522968472.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1522968472.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-05T22:48:52Z","receivedAt":"2018-04-05T22:49:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Let's make it easier for users to find out how to customize these colors.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config.txt | 28 ++++++++++++++++++++++++++++\n 1 file changed, 28 insertions(+)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 4e0cff87f62..40e3828b85f 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1088,6 +1088,16 @@ clean.requireForce::\n \tA boolean to make git-clean do nothing unless given -f,\n \t-i or -n.   Defaults to true.\n \n+color.advice::\n+\tA boolean to enable/disable color in hints (e.g. when a push\n+\tfailed, see `advice.*` for a list).  May be set to `always`,\n+\t`false` (or `never`) or `auto` (or `true`), in which case colors\n+\tare used only when the error output goes to a terminal. If\n+\tunset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.advice.advice::\n+\tUse customized color for hints.\n+\n color.branch::\n \tA boolean to enable/disable color in the output of\n \tlinkgit:git-branch[1]. May be set to `always`,\n@@ -1190,6 +1200,15 @@ color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\n \n+color.push::\n+\tA boolean to enable/disable color in push errors. May be set to\n+\t`always`, `false` (or `never`) or `auto` (or `true`), in which\n+\tcase colors are used only when the error output goes to a terminal.\n+\tIf unset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.push.error::\n+\tUse customized color for push errors.\n+\n color.showBranch::\n \tA boolean to enable/disable color in the output of\n \tlinkgit:git-show-branch[1]. May be set to `always`,\n@@ -1218,6 +1237,15 @@ color.status.<slot>::\n \tstatus short-format), or\n \t`unmerged` (files which have unmerged changes).\n \n+color.transport::\n+\tA boolean to enable/disable color when pushes are rejected. May be\n+\tset to `always`, `false` (or `never`) or `auto` (or `true`), in which\n+\tcase colors are used only when the error output goes to a terminal.\n+\tIf unset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.transport.rejected::\n+\tUse customized color when a push was rejected.\n+\n color.ui::\n \tThis variable determines the default value for variables such\n \tas `color.diff` and `color.grep` that control the use of color\n-- \n2.17.0.windows.1.4.g7e4058d72e3\n"},{"id":"343921","messageId":"CA+P7+xp6fDbabGVKDsRFhixkWRKTuUo_A3UqbQscsBbKiOJmmA@mail.gmail.com","threadId":"47863","inReplyTo":"b2771f9d8e441b6f902924a3b4f037b3874e4191.1522968472.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 2/4] push: colorize errors","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2018-04-05T23:37:23Z","receivedAt":"2018-04-05T23:37:49Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Thu, Apr 5, 2018 at 3:48 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> From: Ryan Dammrose <ryandammrose@gmail.com>\n>\n> This is an attempt to resolve an issue I experience with people that are\n> new to Git -- especially colleagues in a team setting -- where they miss\n> that their push to a remote location failed because the failure and\n> success both return a block of white text.\n>\n> An example is if I push something to a remote repository and then a\n> colleague attempts to push to the same remote repository and the push\n> fails because it requires them to pull first, but they don't notice\n> because a success and failure both return a block of white text. They\n> then continue about their business, thinking it has been successfully\n> pushed.\n>\n> This patch colorizes the errors and hints (in red and yellow,\n> respectively) so whenever there is a failure when pushing to a remote\n> repository that fails, it is more noticeable.\n>\n> [jes: fixed a couple bugs, added the color.{advice,push,transport}\n> settings, refactored to use want_color_stderr().]\n>\n> Signed-off-by: Ryan Dammrose ryandammrose@gmail.com\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n>\n> squash! push: colorize errors\n>\n> Stop talking about localized errors\n\nGuessing you intended to remove this part after squashing?\n\nDidn't see anything else to comment on in the actual code.\n\nThanks,\nJake\n"},{"id":"343951","messageId":"CAPig+cRL1t78W+58HnN3bFJhZa7b9iu=vQxfAq=rF79p1NgeHw@mail.gmail.com","threadId":"47863","inReplyTo":"021133cae0d27359a5e3ee520fc26f58b7030f59.1522968472.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 3/4] Add a test to verify that push errors are colorful","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-04-06T10:50:22Z","receivedAt":"2018-04-06T10:50:28Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> This actually only tests whether the push errors/hints are colored if\n> the respective color.* config settings are `always`, but in the regular\n> case they default to `auto` (in which case we color the messages when\n> stderr is connected to an interactive terminal), therefore these tests\n> should suffice.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n> diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\n> @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' '\n> +test_expect_success 'colorize errors/hints' '\n> +       cd \"$ROOT_PATH\"/test_repo_clone &&\n> +       cat >exp <<-EOF &&\n> +       To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git\n> +        <RED>! [rejected]       <RESET> origin/master^ -> master (non-fast-forward)\n> +       error: failed to push some refs to '\\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\\''\n> +       EOF\n\nThis \"exp\" file is not used by the test.\n\n> +       test_must_fail git -c color.transport=always -c color.advice=always \\\n> +               -c color.push=always \\\n> +               push origin origin/master^:master 2>act &&\n> +       test_decode_color <act >decoded &&\n> +       test_i18ngrep \"<RED>.*rejected.*<RESET>\" decoded &&\n> +       test_i18ngrep \"<RED>error: failed to push some refs\" decoded &&\n> +       test_i18ngrep \"<YELLOW>hint: \" decoded &&\n> +       test_i18ngrep ! \"^hint: \" decoded\n> +'\n"},{"id":"343952","messageId":"CAPig+cRW6VhZGrV3qN5gDyMu1Oc=hjDOpyo_OY43jyoQNc6Q1A@mail.gmail.com","threadId":"47863","inReplyTo":"516b28e82ace0a0b6831c644f246c19dad1187ac.1522968472.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-04-06T10:56:20Z","receivedAt":"2018-04-06T10:56:25Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> Let's make it easier for users to find out how to customize these colors.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n> diff --git a/Documentation/config.txt b/Documentation/config.txt\n> @@ -1088,6 +1088,16 @@ clean.requireForce::\n> +color.advice::\n> +       A boolean to enable/disable color in hints (e.g. when a push\n> +       failed, see `advice.*` for a list).  May be set to `always`,\n> +       `false` (or `never`) or `auto` (or `true`), in which case colors\n> +       are used only when the error output goes to a terminal. If\n> +       unset, then the value of `color.ui` is used (`auto` by default).\n> +\n> +color.advice.advice::\n> +       Use customized color for hints.\n\nIs \"color.advice.advice\" correct?\n"},{"id":"343953","messageId":"nycvar.QRO.7.76.6.1804061313070.55@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47863","inReplyTo":"CA+P7+xp6fDbabGVKDsRFhixkWRKTuUo_A3UqbQscsBbKiOJmmA@mail.gmail.com","subject":"Re: [PATCH v2 2/4] push: colorize errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-06T11:15:20Z","receivedAt":"2018-04-06T11:15:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Jake,\n\nOn Thu, 5 Apr 2018, Jacob Keller wrote:\n\n> On Thu, Apr 5, 2018 at 3:48 PM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n> > From: Ryan Dammrose <ryandammrose@gmail.com>\n> >\n> > This is an attempt to resolve an issue I experience with people that are\n> > new to Git -- especially colleagues in a team setting -- where they miss\n> > that their push to a remote location failed because the failure and\n> > success both return a block of white text.\n> >\n> > An example is if I push something to a remote repository and then a\n> > colleague attempts to push to the same remote repository and the push\n> > fails because it requires them to pull first, but they don't notice\n> > because a success and failure both return a block of white text. They\n> > then continue about their business, thinking it has been successfully\n> > pushed.\n> >\n> > This patch colorizes the errors and hints (in red and yellow,\n> > respectively) so whenever there is a failure when pushing to a remote\n> > repository that fails, it is more noticeable.\n> >\n> > [jes: fixed a couple bugs, added the color.{advice,push,transport}\n> > settings, refactored to use want_color_stderr().]\n> >\n> > Signed-off-by: Ryan Dammrose ryandammrose@gmail.com\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> >\n> > squash! push: colorize errors\n> >\n> > Stop talking about localized errors\n> \n> Guessing you intended to remove this part after squashing?\n\nHah! You caught be red-handed.\n\nThis was intended as a reminder, as you probably guessed, to remove any\nmentions of \"localized errors\" because I had verified that there was no\nlocalized error message; besides, I replaced the call to strstr() looking\nat the error message with a call to push_had_errors() (i.e. using the\nref_status instead). So there are definitely no issues about localized\nerrors left.\n\n> Didn't see anything else to comment on in the actual code.\n\nThank you,\nDscho\n"},{"id":"343954","messageId":"nycvar.QRO.7.76.6.1804061315500.55@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47863","inReplyTo":"xmqqwozc68r2.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 0/1] Colorize some errors on stderr","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-06T11:21:01Z","receivedAt":"2018-04-06T11:21:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\n[and welcome back, at least I hope you only read this after a good and\nrelaxing vacation]\n\nOn Fri, 16 Feb 2018, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Now, what would be possible solutions for this?\n> >\n> > - introduce `int fd` in `want_color()` (and callees) so that we can make\n> >   a distinction whether we want to detect whether stdout or stderr is connected\n> >   to a tty\n> >\n> > - introduce a separate `want_color_stderr()` (we still would need to decide\n> >   whether we want a config setting for this)\n> \n> Between the above two, there probably aren't so big a difference, but\n> in order to avoid disrupting existing callers of want_color() while\n> possibly sharing as much code between the old and new callers,\n> perhaps:\n> \n> \textern int want_color_fd(int fd, int colorbool);\n> \t#define want_color(colorbool) want_color_fd(1, (colorbool))\n> \t#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))\n\nI made it so.\n\nNote that I also had to change the check_auto_color() function, and while\nwant_color_fd() can have a \"private\" record of previous results,\ncheck_auto_color() needs to use the global color_stdout_is_tty (so that\nbuiltin/config.c can edit it, for use in `git config --colorbool <name>\n[stdout-is-tty]`).\n\n> We should honor configuration at two levels, just like the colors on\n> stdout, i.e. color in which individual items are painted (e.g.\n> color.diff.filename, color.advice.hint) and whether we use colors in\n> UI at all (e.g. color.ui).\n\nThis is how v2 does it.\n\nThanks for your suggestions,\nDscho\n"},{"id":"343956","messageId":"nycvar.QRO.7.76.6.1804061410100.55@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47863","inReplyTo":"CAPig+cRL1t78W+58HnN3bFJhZa7b9iu=vQxfAq=rF79p1NgeHw@mail.gmail.com","subject":"Re: [PATCH v2 3/4] Add a test to verify that push errors are colorful","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-06T12:13:26Z","receivedAt":"2018-04-06T12:13:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Eric,\n\n\nOn Fri, 6 Apr 2018, Eric Sunshine wrote:\n\n> On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n> > This actually only tests whether the push errors/hints are colored if\n> > the respective color.* config settings are `always`, but in the regular\n> > case they default to `auto` (in which case we color the messages when\n> > stderr is connected to an interactive terminal), therefore these tests\n> > should suffice.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> > diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\n> > @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' '\n> > +test_expect_success 'colorize errors/hints' '\n> > +       cd \"$ROOT_PATH\"/test_repo_clone &&\n> > +       cat >exp <<-EOF &&\n> > +       To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git\n> > +        <RED>! [rejected]       <RESET> origin/master^ -> master (non-fast-forward)\n> > +       error: failed to push some refs to '\\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\\''\n> > +       EOF\n> \n> This \"exp\" file is not used by the test.\n\nIndeed! I was *so* sure I had removed it, but a `git stash` must have made\nthat change go away before I could commit it.\n\nWill be fixed in v3.\n\nCiao,\nDscho\n"},{"id":"343957","messageId":"nycvar.QRO.7.76.6.1804061414330.55@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47863","inReplyTo":"CAPig+cRW6VhZGrV3qN5gDyMu1Oc=hjDOpyo_OY43jyoQNc6Q1A@mail.gmail.com","subject":"Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-06T12:15:03Z","receivedAt":"2018-04-06T12:15:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Eric,\n\nOn Fri, 6 Apr 2018, Eric Sunshine wrote:\n\n> On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n> > Let's make it easier for users to find out how to customize these colors.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> > diff --git a/Documentation/config.txt b/Documentation/config.txt\n> > @@ -1088,6 +1088,16 @@ clean.requireForce::\n> > +color.advice::\n> > +       A boolean to enable/disable color in hints (e.g. when a push\n> > +       failed, see `advice.*` for a list).  May be set to `always`,\n> > +       `false` (or `never`) or `auto` (or `true`), in which case colors\n> > +       are used only when the error output goes to a terminal. If\n> > +       unset, then the value of `color.ui` is used (`auto` by default).\n> > +\n> > +color.advice.advice::\n> > +       Use customized color for hints.\n> \n> Is \"color.advice.advice\" correct?\n\nAs per the patch, yes. But you're right, it sounds silly. Will change to\n`color.advice.hint`, okay?\n\nWill be fixed in v3,\nDscho\n"},{"id":"343980","messageId":"87vad4yxw7.fsf@evledraar.gmail.com","threadId":"47863","inReplyTo":"cover.1518783709.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 0/1] Colorize some errors on stderr","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-04-06T18:48:08Z","receivedAt":"2018-04-06T18:48:14Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Feb 16 2018, Johannes Schindelin wrote:\n\n> This is an RFC because it tries to introduce a fundamental new color feature:\n> Coloring messages *on stderr*.\n\nI missed this the first time around, and don't have anything to add that\nothers haven't covered. Just wanted to say I'd love to get this into\ngit, it's a great UI improvement.\n"},{"id":"344053","messageId":"CAPig+cR+=8fWYtiOyuvuRoLPRSUUAVz_iU3p64Jttff+2xdHYg@mail.gmail.com","threadId":"47863","inReplyTo":"nycvar.QRO.7.76.6.1804061414330.55@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","subject":"Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2018-04-07T06:55:44Z","receivedAt":"2018-04-07T06:55:49Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Apr 6, 2018 at 8:15 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On Fri, 6 Apr 2018, Eric Sunshine wrote:\n>> On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin\n>> <johannes.schindelin@gmx.de> wrote:\n>> > +color.advice.advice::\n>> > +       Use customized color for hints.\n>>\n>> Is \"color.advice.advice\" correct?\n>\n> As per the patch, yes. But you're right, it sounds silly. Will change to\n> `color.advice.hint`, okay?\n\nThat's more understandable. Thanks.\n"},{"id":"345340","messageId":"cover.1524305353.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1522968472.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 0/4] Colorize push errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-21T10:09:52Z","receivedAt":"2018-04-21T10:10:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"To help users discern large chunks of white text (when the push\nsucceeds) from large chunks of white text (when the push fails), let's\nadd some color to the latter.\n\nThe original contribution came in via Pull Request from the Git for\nWindows project:\n\n\thttps://github.com/git-for-windows/git/pull/1429\n\nI almost forgot to submit v3. Guess it's a good thing I have a project\nmanagement system with tickets I can move through a story board...\n\nChanges since v2:\n\n- removed a bogus \"squash! ...\" from the commit message of 2/4\n\n- removed the unnecessary here-doc from the test added in 4/4\n\n- renamed color.advice.advice to color.advice.hint in 2/4 and 4/4\n\n\nJohannes Schindelin (3):\n  color: introduce support for colorizing stderr\n  Add a test to verify that push errors are colorful\n  Document the new color.* settings to colorize push errors/hints\n\nRyan Dammrose (1):\n  push: colorize errors\n\n Documentation/config.txt   | 28 ++++++++++++++++\n advice.c                   | 49 ++++++++++++++++++++++++++--\n builtin/push.c             | 44 ++++++++++++++++++++++++-\n color.c                    | 20 +++++++-----\n color.h                    |  4 ++-\n config.c                   |  2 +-\n t/t5541-http-push-smart.sh | 12 +++++++\n transport.c                | 67 +++++++++++++++++++++++++++++++++++++-\n 8 files changed, 211 insertions(+), 15 deletions(-)\n\n\nbase-commit: fe0a9eaf31dd0c349ae4308498c33a5c3794b293\nPublished-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v3\nFetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v3\n\nInterdiff vs v2:\n diff --git a/Documentation/config.txt b/Documentation/config.txt\n index 1fef60a7301..2cea0c6c899 100644\n --- a/Documentation/config.txt\n +++ b/Documentation/config.txt\n @@ -1095,7 +1095,7 @@ color.advice::\n  \tare used only when the error output goes to a terminal. If\n  \tunset, then the value of `color.ui` is used (`auto` by default).\n  \n -color.advice.advice::\n +color.advice.hint::\n  \tUse customized color for hints.\n  \n  color.branch::\n diff --git a/advice.c b/advice.c\n index 2121c1811fd..89fda1de55b 100644\n --- a/advice.c\n +++ b/advice.c\n @@ -36,7 +36,7 @@ static int parse_advise_color_slot(const char *slot)\n  {\n  \tif (!strcasecmp(slot, \"reset\"))\n  \t\treturn ADVICE_COLOR_RESET;\n -\tif (!strcasecmp(slot, \"advice\"))\n +\tif (!strcasecmp(slot, \"hint\"))\n  \t\treturn ADVICE_COLOR_HINT;\n  \treturn -1;\n  }\n diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\n index 1c2be98dc2b..a2af693068f 100755\n --- a/t/t5541-http-push-smart.sh\n +++ b/t/t5541-http-push-smart.sh\n @@ -379,12 +379,6 @@ test_expect_success 'push status output scrubs password' '\n  \n  test_expect_success 'colorize errors/hints' '\n  \tcd \"$ROOT_PATH\"/test_repo_clone &&\n -\tcat >exp <<-EOF &&\n -\tTo http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git\n -\t <RED>! [rejected]       <RESET> origin/master^ -> master (non-fast-forward)\n -\terror: failed to push some refs to '\\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\\''\n -\tEOF\n -\n  \ttest_must_fail git -c color.transport=always -c color.advice=always \\\n  \t\t-c color.push=always \\\n  \t\tpush origin origin/master^:master 2>act &&\n-- \n2.17.0.windows.1.15.gaa56ade3205\n\n"},{"id":"345341","messageId":"52e3348f7741cc5cd9b37a116954305cea6d4358.1524305353.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1524305353.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 1/4] color: introduce support for colorizing stderr","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-21T10:09:57Z","receivedAt":"2018-04-21T10:10:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"So far, we only ever asked whether stdout wants to be colorful. In the\nupcoming patches, we will want to make push errors more prominent, which\nare printed to stderr, though.\n\nSo let's refactor the want_color() function into a want_color_fd()\nfunction (which expects to be called with fd == 1 or fd == 2 for stdout\nand stderr, respectively), and then define the macro `want_color()` to\nuse the want_color_fd() function.\n\nAnd then also add a macro `want_color_stderr()`, for convenience and\nfor documentation.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n color.c | 20 +++++++++++---------\n color.h |  4 +++-\n 2 files changed, 14 insertions(+), 10 deletions(-)\n\ndiff --git a/color.c b/color.c\nindex f277e72e4ce..c6c6c4f580f 100644\n--- a/color.c\n+++ b/color.c\n@@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value)\n \treturn GIT_COLOR_AUTO;\n }\n \n-static int check_auto_color(void)\n+static int check_auto_color(int fd)\n {\n-\tif (color_stdout_is_tty < 0)\n-\t\tcolor_stdout_is_tty = isatty(1);\n-\tif (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {\n+\tstatic int color_stderr_is_tty = -1;\n+\tint *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;\n+\tif (*is_tty_p < 0)\n+\t\t*is_tty_p = isatty(fd);\n+\tif (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {\n \t\tif (!is_terminal_dumb())\n \t\t\treturn 1;\n \t}\n \treturn 0;\n }\n \n-int want_color(int var)\n+int want_color_fd(int fd, int var)\n {\n \t/*\n \t * NEEDSWORK: This function is sometimes used from multiple threads, and\n@@ -339,15 +341,15 @@ int want_color(int var)\n \t * is listed in .tsan-suppressions for the time being.\n \t */\n \n-\tstatic int want_auto = -1;\n+\tstatic int want_auto[3] = { -1, -1, -1 };\n \n \tif (var < 0)\n \t\tvar = git_use_color_default;\n \n \tif (var == GIT_COLOR_AUTO) {\n-\t\tif (want_auto < 0)\n-\t\t\twant_auto = check_auto_color();\n-\t\treturn want_auto;\n+\t\tif (want_auto[fd] < 0)\n+\t\t\twant_auto[fd] = check_auto_color(fd);\n+\t\treturn want_auto[fd];\n \t}\n \treturn var;\n }\ndiff --git a/color.h b/color.h\nindex cd0bcedd084..5b744e1bc68 100644\n--- a/color.h\n+++ b/color.h\n@@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value);\n  * Return a boolean whether to use color, where the argument 'var' is\n  * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO.\n  */\n-int want_color(int var);\n+int want_color_fd(int fd, int var);\n+#define want_color(colorbool) want_color_fd(1, (colorbool))\n+#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))\n \n /*\n  * Translate a Git color from 'value' into a string that the terminal can\n-- \n2.17.0.windows.1.15.gaa56ade3205\n\n\n"},{"id":"345342","messageId":"00115ad6b3c10608353d7242669c8de7c4d13cd7.1524305353.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1524305353.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 2/4] push: colorize errors","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-21T10:10:00Z","receivedAt":"2018-04-21T10:10:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"From: Ryan Dammrose <ryandammrose@gmail.com>\n\nThis is an attempt to resolve an issue I experience with people that are\nnew to Git -- especially colleagues in a team setting -- where they miss\nthat their push to a remote location failed because the failure and\nsuccess both return a block of white text.\n\nAn example is if I push something to a remote repository and then a\ncolleague attempts to push to the same remote repository and the push\nfails because it requires them to pull first, but they don't notice\nbecause a success and failure both return a block of white text. They\nthen continue about their business, thinking it has been successfully\npushed.\n\nThis patch colorizes the errors and hints (in red and yellow,\nrespectively) so whenever there is a failure when pushing to a remote\nrepository that fails, it is more noticeable.\n\n[jes: fixed a couple bugs, added the color.{advice,push,transport}\nsettings, refactored to use want_color_stderr().]\n\nSigned-off-by: Ryan Dammrose ryandammrose@gmail.com\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n advice.c       | 49 ++++++++++++++++++++++++++++++++++--\n builtin/push.c | 44 ++++++++++++++++++++++++++++++++-\n config.c       |  2 +-\n transport.c    | 67 +++++++++++++++++++++++++++++++++++++++++++++++++-\n 4 files changed, 157 insertions(+), 5 deletions(-)\n\ndiff --git a/advice.c b/advice.c\nindex 406efc183ba..89fda1de55b 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"config.h\"\n+#include \"color.h\"\n \n int advice_push_update_rejected = 1;\n int advice_push_non_ff_current = 1;\n@@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1;\n int advice_ignored_hook = 1;\n int advice_waiting_for_editor = 1;\n \n+static int advice_use_color = -1;\n+static char advice_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_YELLOW,\t/* HINT */\n+};\n+\n+enum color_advice {\n+\tADVICE_COLOR_RESET = 0,\n+\tADVICE_COLOR_HINT = 1,\n+};\n+\n+static int parse_advise_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn ADVICE_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"hint\"))\n+\t\treturn ADVICE_COLOR_HINT;\n+\treturn -1;\n+}\n+\n+static const char *advise_get_color(enum color_advice ix)\n+{\n+\tif (want_color_stderr(advice_use_color))\n+\t\treturn advice_colors[ix];\n+\treturn \"\";\n+}\n+\n static struct {\n \tconst char *name;\n \tint *preference;\n@@ -59,7 +87,10 @@ void advise(const char *advice, ...)\n \n \tfor (cp = buf.buf; *cp; cp = np) {\n \t\tnp = strchrnul(cp, '\\n');\n-\t\tfprintf(stderr,\t_(\"hint: %.*s\\n\"), (int)(np - cp), cp);\n+\t\tfprintf(stderr,\t_(\"%shint: %.*s%s\\n\"),\n+\t\t\tadvise_get_color(ADVICE_COLOR_HINT),\n+\t\t\t(int)(np - cp), cp,\n+\t\t\tadvise_get_color(ADVICE_COLOR_RESET));\n \t\tif (*np)\n \t\t\tnp++;\n \t}\n@@ -68,9 +99,23 @@ void advise(const char *advice, ...)\n \n int git_default_advice_config(const char *var, const char *value)\n {\n-\tconst char *k;\n+\tconst char *k, *slot_name;\n \tint i;\n \n+\tif (!strcmp(var, \"color.advice\")) {\n+\t\tadvice_use_color = git_config_colorbool(var, value);\n+\t\treturn 0;\n+\t}\n+\n+\tif (skip_prefix(var, \"color.advice.\", &slot_name)) {\n+\t\tint slot = parse_advise_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\treturn color_parse(value, advice_colors[slot]);\n+\t}\n+\n \tif (!skip_prefix(var, \"advice.\", &k))\n \t\treturn 0;\n \ndiff --git a/builtin/push.c b/builtin/push.c\nindex 013c20d6164..ac3705370e1 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -12,12 +12,40 @@\n #include \"submodule.h\"\n #include \"submodule-config.h\"\n #include \"send-pack.h\"\n+#include \"color.h\"\n \n static const char * const push_usage[] = {\n \tN_(\"git push [<options>] [<repository> [<refspec>...]]\"),\n \tNULL,\n };\n \n+static int push_use_color = -1;\n+static char push_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED,\t/* ERROR */\n+};\n+\n+enum color_push {\n+\tPUSH_COLOR_RESET = 0,\n+\tPUSH_COLOR_ERROR = 1\n+};\n+\n+static int parse_push_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"reset\"))\n+\t\treturn PUSH_COLOR_RESET;\n+\tif (!strcasecmp(slot, \"error\"))\n+\t\treturn PUSH_COLOR_ERROR;\n+\treturn -1;\n+}\n+\n+static const char *push_get_color(enum color_push ix)\n+{\n+\tif (want_color_stderr(push_use_color))\n+\t\treturn push_colors[ix];\n+\treturn \"\";\n+}\n+\n static int thin = 1;\n static int deleterefs;\n static const char *receivepack;\n@@ -337,8 +365,11 @@ static int push_with_options(struct transport *transport, int flags)\n \t\tfprintf(stderr, _(\"Pushing to %s\\n\"), transport->url);\n \terr = transport_push(transport, refspec_nr, refspec, flags,\n \t\t\t     &reject_reasons);\n-\tif (err != 0)\n+\tif (err != 0) {\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_ERROR));\n \t\terror(_(\"failed to push some refs to '%s'\"), transport->url);\n+\t\tfprintf(stderr, \"%s\", push_get_color(PUSH_COLOR_RESET));\n+\t}\n \n \terr |= transport_disconnect(transport);\n \tif (!err)\n@@ -467,6 +498,7 @@ static void set_push_cert_flags(int *flags, int v)\n \n static int git_push_config(const char *k, const char *v, void *cb)\n {\n+\tconst char *slot_name;\n \tint *flags = cb;\n \tint status;\n \n@@ -514,6 +546,16 @@ static int git_push_config(const char *k, const char *v, void *cb)\n \t\t\telse\n \t\t\t\tstring_list_append(&push_options_config, v);\n \t\treturn 0;\n+\t} else if (!strcmp(k, \"color.push\")) {\n+\t\tpush_use_color = git_config_colorbool(k, v);\n+\t\treturn 0;\n+\t} else if (skip_prefix(k, \"color.push.\", &slot_name)) {\n+\t\tint slot = parse_push_color_slot(slot_name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!v)\n+\t\t\treturn config_error_nonbool(k);\n+\t\treturn color_parse(v, push_colors[slot]);\n \t}\n \n \treturn git_default_config(k, v, NULL);\ndiff --git a/config.c b/config.c\nindex c698988f5e1..f21317a25a7 100644\n--- a/config.c\n+++ b/config.c\n@@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy)\n \tif (starts_with(var, \"mailmap.\"))\n \t\treturn git_default_mailmap_config(var, value);\n \n-\tif (starts_with(var, \"advice.\"))\n+\tif (starts_with(var, \"advice.\") || starts_with(var, \"color.advice\"))\n \t\treturn git_default_advice_config(var, value);\n \n \tif (!strcmp(var, \"pager.color\") || !strcmp(var, \"color.pager\")) {\ndiff --git a/transport.c b/transport.c\nindex 94eccf29aa3..f72081a5a58 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -19,6 +19,56 @@\n #include \"sigchain.h\"\n #include \"transport-internal.h\"\n #include \"object-store.h\"\n+#include \"color.h\"\n+\n+static int transport_use_color = -1;\n+static char transport_colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_RESET,\n+\tGIT_COLOR_RED\t\t/* REJECTED */\n+};\n+\n+enum color_transport {\n+\tTRANSPORT_COLOR_RESET = 0,\n+\tTRANSPORT_COLOR_REJECTED = 1\n+};\n+\n+static int transport_color_config(void)\n+{\n+\tconst char *keys[] = {\n+\t\t\"color.transport.reset\",\n+\t\t\"color.transport.rejected\"\n+\t}, *key = \"color.transport\";\n+\tchar *value;\n+\tint i;\n+\tstatic int initialized;\n+\n+\tif (initialized)\n+\t\treturn 0;\n+\tinitialized = 1;\n+\n+\tif (!git_config_get_string(key, &value))\n+\t\ttransport_use_color = git_config_colorbool(key, value);\n+\n+\tif (!want_color_stderr(transport_use_color))\n+\t\treturn 0;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(keys); i++)\n+\t\tif (!git_config_get_string(keys[i], &value)) {\n+\t\t\tif (!value)\n+\t\t\t\treturn config_error_nonbool(keys[i]);\n+\t\t\tif (color_parse(value, transport_colors[i]) < 0)\n+\t\t\t\treturn -1;\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+static const char *transport_get_color(enum color_transport ix)\n+{\n+\tif (want_color_stderr(transport_use_color))\n+\t\treturn transport_colors[ix];\n+\treturn \"\";\n+}\n \n static void set_upstreams(struct transport *transport, struct ref *refs,\n \tint pretend)\n@@ -339,7 +389,13 @@ static void print_ref_status(char flag, const char *summary,\n \t\telse\n \t\t\tfprintf(stdout, \"%s\\n\", summary);\n \t} else {\n-\t\tfprintf(stderr, \" %c %-*s \", flag, summary_width, summary);\n+\t\tconst char *red = \"\", *reset = \"\";\n+\t\tif (push_had_errors(to)) {\n+\t\t\tred = transport_get_color(TRANSPORT_COLOR_REJECTED);\n+\t\t\treset = transport_get_color(TRANSPORT_COLOR_RESET);\n+\t\t}\n+\t\tfprintf(stderr, \" %s%c %-*s%s \", red, flag, summary_width,\n+\t\t\tsummary, reset);\n \t\tif (from)\n \t\t\tfprintf(stderr, \"%s -> %s\", prettify_refname(from->name), prettify_refname(to->name));\n \t\telse\n@@ -488,6 +544,9 @@ void transport_print_push_status(const char *dest, struct ref *refs,\n \tchar *head;\n \tint summary_width = transport_summary_width(refs);\n \n+\tif (transport_color_config() < 0)\n+\t\twarning(_(\"could not parse transport.color.* config\"));\n+\n \thead = resolve_refdup(\"HEAD\", RESOLVE_REF_READING, NULL, NULL);\n \n \tif (verbose) {\n@@ -554,6 +613,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re\n \tstruct send_pack_args args;\n \tint ret;\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (!data->got_remote_heads) {\n \t\tstruct ref *tmp_refs;\n \t\tconnect_setup(transport, 1);\n@@ -998,6 +1060,9 @@ int transport_push(struct transport *transport,\n \t*reject_reasons = 0;\n \ttransport_verify_remote_names(refspec_nr, refspec);\n \n+\tif (transport_color_config() < 0)\n+\t\treturn -1;\n+\n \tif (transport->vtable->push_refs) {\n \t\tstruct ref *remote_refs;\n \t\tstruct ref *local_refs = get_local_heads();\n-- \n2.17.0.windows.1.15.gaa56ade3205\n\n\n"},{"id":"345343","messageId":"7f24ee9bf59f91505b8e7cf92715724511f4026e.1524305353.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1524305353.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 3/4] Add a test to verify that push errors are colorful","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-21T10:10:04Z","receivedAt":"2018-04-21T10:10:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This actually only tests whether the push errors/hints are colored if\nthe respective color.* config settings are `always`, but in the regular\ncase they default to `auto` (in which case we color the messages when\nstderr is connected to an interactive terminal), therefore these tests\nshould suffice.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t5541-http-push-smart.sh | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n\ndiff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh\nindex 21340e89c96..a2af693068f 100755\n--- a/t/t5541-http-push-smart.sh\n+++ b/t/t5541-http-push-smart.sh\n@@ -377,5 +377,17 @@ test_expect_success 'push status output scrubs password' '\n \tgrep \"^To $HTTPD_URL/smart/test_repo.git\" status\n '\n \n+test_expect_success 'colorize errors/hints' '\n+\tcd \"$ROOT_PATH\"/test_repo_clone &&\n+\ttest_must_fail git -c color.transport=always -c color.advice=always \\\n+\t\t-c color.push=always \\\n+\t\tpush origin origin/master^:master 2>act &&\n+\ttest_decode_color <act >decoded &&\n+\ttest_i18ngrep \"<RED>.*rejected.*<RESET>\" decoded &&\n+\ttest_i18ngrep \"<RED>error: failed to push some refs\" decoded &&\n+\ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n+\ttest_i18ngrep ! \"^hint: \" decoded\n+'\n+\n stop_httpd\n test_done\n-- \n2.17.0.windows.1.15.gaa56ade3205\n\n\n"},{"id":"345344","messageId":"b192099ce0e251f4aa35b2c6388a31c9666e723f.1524305353.git.johannes.schindelin@gmx.de","threadId":"47863","inReplyTo":"cover.1524305353.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 4/4] Document the new color.* settings to colorize push errors/hints","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-21T10:10:07Z","receivedAt":"2018-04-21T10:10:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Let's make it easier for users to find out how to customize these colors.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n Documentation/config.txt | 28 ++++++++++++++++++++++++++++\n 1 file changed, 28 insertions(+)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 2659153cb37..2cea0c6c899 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1088,6 +1088,16 @@ clean.requireForce::\n \tA boolean to make git-clean do nothing unless given -f,\n \t-i or -n.   Defaults to true.\n \n+color.advice::\n+\tA boolean to enable/disable color in hints (e.g. when a push\n+\tfailed, see `advice.*` for a list).  May be set to `always`,\n+\t`false` (or `never`) or `auto` (or `true`), in which case colors\n+\tare used only when the error output goes to a terminal. If\n+\tunset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.advice.hint::\n+\tUse customized color for hints.\n+\n color.branch::\n \tA boolean to enable/disable color in the output of\n \tlinkgit:git-branch[1]. May be set to `always`,\n@@ -1190,6 +1200,15 @@ color.pager::\n \tA boolean to enable/disable colored output when the pager is in\n \tuse (default is true).\n \n+color.push::\n+\tA boolean to enable/disable color in push errors. May be set to\n+\t`always`, `false` (or `never`) or `auto` (or `true`), in which\n+\tcase colors are used only when the error output goes to a terminal.\n+\tIf unset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.push.error::\n+\tUse customized color for push errors.\n+\n color.showBranch::\n \tA boolean to enable/disable color in the output of\n \tlinkgit:git-show-branch[1]. May be set to `always`,\n@@ -1218,6 +1237,15 @@ color.status.<slot>::\n \tstatus short-format), or\n \t`unmerged` (files which have unmerged changes).\n \n+color.transport::\n+\tA boolean to enable/disable color when pushes are rejected. May be\n+\tset to `always`, `false` (or `never`) or `auto` (or `true`), in which\n+\tcase colors are used only when the error output goes to a terminal.\n+\tIf unset, then the value of `color.ui` is used (`auto` by default).\n+\n+color.transport.rejected::\n+\tUse customized color when a push was rejected.\n+\n color.ui::\n \tThis variable determines the default value for variables such\n \tas `color.diff` and `color.grep` that control the use of color\n-- \n2.17.0.windows.1.15.gaa56ade3205\n"}]}