* [PATCH 0/1] Colorize some errors on stderr @ 2018-02-16 12:25 Johannes Schindelin 2018-02-16 12:25 ` [PATCH 1/1] Colorize push errors Johannes Schindelin ` (3 more replies) 0 siblings, 4 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-02-16 12:25 UTC (permalink / raw) To: git; +Cc: Junio C Hamano This is an RFC because it tries to introduce a fundamental new color feature: Coloring messages *on stderr*. So far, pretty much everything in color.[ch] assumed that you want to color only stuff on stdout. However, in this case, a user (who became a contributor!) wanted some messages that are printed to stderr and were missed by his colleagues to be colored. The contribution comes via Pull Request from the Git for Windows project: https://github.com/git-for-windows/git/pull/1429 Now, what would be possible solutions for this? - introduce `int fd` in `want_color()` (and callees) so that we can make a distinction whether we want to detect whether stdout or stderr is connected to a tty - introduce a separate `want_color_stderr()` (we still would need to decide whether we want a config setting for this) - not color stderr, ever Also, I did not have too much time to dig into the question how to test this in Git's test suite. Do we already have tests that generate fake server-side errors onto which I could piggy-back a new test case? Thoughts? Suggestions? Help? Ryan Dammrose (1): Colorize push errors advice.c | 42 +++++++++++++++++++++++++++++++++++++++-- builtin/push.c | 38 +++++++++++++++++++++++++++++++++++++ transport.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 136 insertions(+), 3 deletions(-) base-commit: b2e45c695d09f6a31ce09347ae0a5d2cdfe9dd4e Published-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v1 Fetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v1 -- 2.16.1.windows.4 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/1] Colorize push errors 2018-02-16 12:25 [PATCH 0/1] Colorize some errors on stderr Johannes Schindelin @ 2018-02-16 12:25 ` Johannes Schindelin 2018-02-16 19:21 ` [PATCH 0/1] Colorize some errors on stderr Junio C Hamano ` (2 subsequent siblings) 3 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-02-16 12:25 UTC (permalink / raw) To: git; +Cc: Ryan Dammrose, Junio C Hamano From: Ryan Dammrose <ryandammrose@gmail.com> This is an attempt to resolve an issue I experience with people that are new to Git -- especially colleagues in a team setting -- where they miss that their push to a remote location failed because the failure and success both return a block of white text. An example is if I push something to a remote repository and then a colleague attempts to push to the same remote repository and the push fails because it requires them to pull first, but they don't notice because a success and failure both return a block of white text. They then continue about their business, thinking it has been successfully pushed. My solution was to try to change the stderr and hint colors (red and yellow, respectively) so whenever there is a failure when pushing to a remote repository that fails, it is more noticeable. The challenge was that it seemed that stderr has never been colored and I attempted to utilize what was already established; but this meant using functions like want_color() even if it targets stdout while I wanted to target stderr. Additionally, to check for all rejection types, I did a strstr check in transport.c, but this code could be problematic if there is need for translation. Signed-off-by: Ryan Dammrose ryandammrose@gmail.com Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- advice.c | 42 +++++++++++++++++++++++++++++++++++++++-- builtin/push.c | 38 +++++++++++++++++++++++++++++++++++++ transport.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 136 insertions(+), 3 deletions(-) diff --git a/advice.c b/advice.c index 406efc183ba..42460877ef6 100644 --- a/advice.c +++ b/advice.c @@ -1,5 +1,6 @@ #include "cache.h" #include "config.h" +#include "color.h" int advice_push_update_rejected = 1; int advice_push_non_ff_current = 1; @@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1; int advice_ignored_hook = 1; int advice_waiting_for_editor = 1; +static int advice_use_color = -1; +static char advice_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_YELLOW, /* HINT */ +}; + +enum color_advice { + ADVICE_COLOR_RESET = 0, + ADVICE_COLOR_HINT = 1, +}; + +static int parse_advise_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return ADVICE_COLOR_RESET; + if (!strcasecmp(slot, "advice")) + return ADVICE_COLOR_HINT; + return -1; +} + +static const char *advise_get_color(enum color_advice ix) +{ + if (want_color(advice_use_color)) + return advice_colors[ix]; + return ""; +} + static struct { const char *name; int *preference; @@ -59,7 +87,8 @@ void advise(const char *advice, ...) for (cp = buf.buf; *cp; cp = np) { np = strchrnul(cp, '\n'); - fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp); + fprintf(stderr, _("%shint: %.*s%s\n"), advise_get_color(ADVICE_COLOR_HINT), + (int)(np - cp), cp, advise_get_color(ADVICE_COLOR_RESET)); if (*np) np++; } @@ -68,9 +97,18 @@ void advise(const char *advice, ...) int git_default_advice_config(const char *var, const char *value) { - const char *k; + const char *k, *slot_name; int i; + if (skip_prefix(var, "color.advice.", &slot_name)) { + int slot = parse_advise_color_slot(slot_name); + if (slot < 0) + return 0; + if (!value) + return config_error_nonbool(var); + return color_parse(value, advice_colors[slot]); + } + if (!skip_prefix(var, "advice.", &k)) return 0; diff --git a/builtin/push.c b/builtin/push.c index 1c28427d82e..997ccab52ac 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -12,12 +12,40 @@ #include "submodule.h" #include "submodule-config.h" #include "send-pack.h" +#include "color.h" static const char * const push_usage[] = { N_("git push [<options>] [<repository> [<refspec>...]]"), NULL, }; +static int push_use_color = -1; +static char push_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED, /* ERROR */ +}; + +enum color_push { + PUSH_COLOR_RESET = 0, + PUSH_COLOR_ERROR = 1 +}; + +static int parse_push_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return PUSH_COLOR_RESET; + if (!strcasecmp(slot, "error")) + return PUSH_COLOR_ERROR; + return -1; +} + +static const char *push_get_color(enum color_push ix) +{ + if (want_color(push_use_color)) + return push_colors[ix]; + return ""; +} + static int thin = 1; static int deleterefs; static const char *receivepack; @@ -338,7 +366,9 @@ static int push_with_options(struct transport *transport, int flags) err = transport_push(transport, refspec_nr, refspec, flags, &reject_reasons); if (err != 0) + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR)); error(_("failed to push some refs to '%s'"), transport->url); + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET)); err |= transport_disconnect(transport); if (!err) @@ -467,6 +497,7 @@ static void set_push_cert_flags(int *flags, int v) static int git_push_config(const char *k, const char *v, void *cb) { + const char *slot_name; int *flags = cb; int status; @@ -514,6 +545,13 @@ static int git_push_config(const char *k, const char *v, void *cb) else string_list_append(&push_options_config, v); return 0; + } else if (skip_prefix(k, "color.advice.", &slot_name)) { + int slot = parse_push_color_slot(slot_name); + if (slot < 0) + return 0; + if (!v) + return config_error_nonbool(k); + return color_parse(v, push_colors[slot]); } return git_default_config(k, v, NULL); diff --git a/transport.c b/transport.c index 00d48b5b565..dd98dd84b05 100644 --- a/transport.c +++ b/transport.c @@ -18,6 +18,50 @@ #include "sha1-array.h" #include "sigchain.h" #include "transport-internal.h" +#include "color.h" + +static int transport_use_color = -1; +static char transport_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED /* REJECTED */ +}; + +enum color_transport { + TRANSPORT_COLOR_RESET = 0, + TRANSPORT_COLOR_REJECTED = 1 +}; + +static int transport_color_config(void) +{ + const char *keys[] = { + "transport.color.reset", + "transport.color.rejected" + }; + char *value; + int i; + static int initialized; + + if (initialized) + return 0; + initialized = 1; + + for (i = 0; i < ARRAY_SIZE(keys); i++) + if (!git_config_get_string(keys[i], &value)) { + if (!value) + return config_error_nonbool(keys[i]); + if (color_parse(value, transport_colors[i]) < 0) + return -1; + } + + return 0; +} + +static const char *transport_get_color(enum color_transport ix) +{ + if (want_color(transport_use_color)) + return transport_colors[ix]; + return ""; +} static void set_upstreams(struct transport *transport, struct ref *refs, int pretend) @@ -338,7 +382,11 @@ static void print_ref_status(char flag, const char *summary, else fprintf(stdout, "%s\n", summary); } else { - fprintf(stderr, " %c %-*s ", flag, summary_width, summary); + if (strstr(summary, "rejected") != NULL || strstr(summary, "failure") != NULL) + fprintf(stderr, " %s%c %-*s%s ", transport_get_color(TRANSPORT_COLOR_REJECTED), + flag, summary_width, summary, transport_get_color(TRANSPORT_COLOR_RESET)); + else + fprintf(stderr, " %c %-*s ", flag, summary_width, summary); if (from) fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name)); else @@ -487,6 +535,9 @@ void transport_print_push_status(const char *dest, struct ref *refs, char *head; int summary_width = transport_summary_width(refs); + if (transport_color_config() < 0) + warning(_("could not parse transport.color.* config")); + head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL); if (verbose) { @@ -553,6 +604,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re struct send_pack_args args; int ret; + if (transport_color_config() < 0) + return -1; + if (!data->got_remote_heads) { struct ref *tmp_refs; connect_setup(transport, 1); @@ -997,6 +1051,9 @@ int transport_push(struct transport *transport, *reject_reasons = 0; transport_verify_remote_names(refspec_nr, refspec); + if (transport_color_config() < 0) + return -1; + if (transport->vtable->push_refs) { struct ref *remote_refs; struct ref *local_refs = get_local_heads(); -- 2.16.1.windows.4 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/1] Colorize some errors on stderr 2018-02-16 12:25 [PATCH 0/1] Colorize some errors on stderr Johannes Schindelin 2018-02-16 12:25 ` [PATCH 1/1] Colorize push errors Johannes Schindelin @ 2018-02-16 19:21 ` Junio C Hamano 2018-04-06 11:21 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin 2018-04-06 18:48 ` [PATCH 0/1] Colorize some errors on stderr Ævar Arnfjörð Bjarmason 3 siblings, 1 reply; 22+ messages in thread From: Junio C Hamano @ 2018-02-16 19:21 UTC (permalink / raw) To: Johannes Schindelin; +Cc: git Johannes Schindelin <johannes.schindelin@gmx.de> writes: > Now, what would be possible solutions for this? > > - introduce `int fd` in `want_color()` (and callees) so that we can make > a distinction whether we want to detect whether stdout or stderr is connected > to a tty > > - introduce a separate `want_color_stderr()` (we still would need to decide > whether we want a config setting for this) Between the above two, there probably aren't so big a difference, but in order to avoid disrupting existing callers of want_color() while possibly sharing as much code between the old and new callers, perhaps: extern int want_color_fd(int fd, int colorbool); #define want_color(colorbool) want_color_fd(1, (colorbool)) #define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) We should honor configuration at two levels, just like the colors on stdout, i.e. color in which individual items are painted (e.g. color.diff.filename, color.advice.hint) and whether we use colors in UI at all (e.g. color.ui). I do not think it is necessary or even at the right granularity to allow settings like "do color stdout but do not color errors". > - not color stderr, ever This is my personal preference, but that does not and should not carry too much weight ;-) ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/1] Colorize some errors on stderr 2018-02-16 19:21 ` [PATCH 0/1] Colorize some errors on stderr Junio C Hamano @ 2018-04-06 11:21 ` Johannes Schindelin 0 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-06 11:21 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Hi Junio, [and welcome back, at least I hope you only read this after a good and relaxing vacation] On Fri, 16 Feb 2018, Junio C Hamano wrote: > Johannes Schindelin <johannes.schindelin@gmx.de> writes: > > > Now, what would be possible solutions for this? > > > > - introduce `int fd` in `want_color()` (and callees) so that we can make > > a distinction whether we want to detect whether stdout or stderr is connected > > to a tty > > > > - introduce a separate `want_color_stderr()` (we still would need to decide > > whether we want a config setting for this) > > Between the above two, there probably aren't so big a difference, but > in order to avoid disrupting existing callers of want_color() while > possibly sharing as much code between the old and new callers, > perhaps: > > extern int want_color_fd(int fd, int colorbool); > #define want_color(colorbool) want_color_fd(1, (colorbool)) > #define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) I made it so. Note that I also had to change the check_auto_color() function, and while want_color_fd() can have a "private" record of previous results, check_auto_color() needs to use the global color_stdout_is_tty (so that builtin/config.c can edit it, for use in `git config --colorbool <name> [stdout-is-tty]`). > We should honor configuration at two levels, just like the colors on > stdout, i.e. color in which individual items are painted (e.g. > color.diff.filename, color.advice.hint) and whether we use colors in > UI at all (e.g. color.ui). This is how v2 does it. Thanks for your suggestions, Dscho ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 0/4] Colorize push errors 2018-02-16 12:25 [PATCH 0/1] Colorize some errors on stderr Johannes Schindelin 2018-02-16 12:25 ` [PATCH 1/1] Colorize push errors Johannes Schindelin 2018-02-16 19:21 ` [PATCH 0/1] Colorize some errors on stderr Junio C Hamano @ 2018-04-05 22:48 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 1/4] color: introduce support for colorizing stderr Johannes Schindelin ` (4 more replies) 2018-04-06 18:48 ` [PATCH 0/1] Colorize some errors on stderr Ævar Arnfjörð Bjarmason 3 siblings, 5 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-05 22:48 UTC (permalink / raw) To: git; +Cc: Junio C Hamano To help users discern large chunks of white text (when the push succeeds) from large chunks of white text (when the push fails), let's add some color to the latter. The original contribution came in via Pull Request from the Git for Windows project: https://github.com/git-for-windows/git/pull/1429 Changes since v1: - implemented want_color_fd() as suggested by Junio - added color.{advice,push,transport} to be able to force this thing on - added a test - added documentation to `git config`'s man page - fixed a bug where the push config looked at color.advice.<slot> - fixed a bug where `color.advise.<slot>` was not parsed because git_default_config() would fail to hand `color.advise.*` settings to git_default_advice_config() - wrapped a couple of too-long lines - changed the strstr() hack to detect push failures to use push_had_errors() instead - renamed the transport.color.* settings to color.transport.* (to make them consistent with all the other color.<category>.<slot> settings) Johannes Schindelin (3): color: introduce support for colorizing stderr Add a test to verify that push errors are colorful Document the new color.* settings to colorize push errors/hints Ryan Dammrose (1): push: colorize errors Documentation/config.txt | 28 ++++++++++++++++ advice.c | 49 ++++++++++++++++++++++++++-- builtin/push.c | 44 ++++++++++++++++++++++++- color.c | 20 +++++++----- color.h | 4 ++- config.c | 2 +- t/t5541-http-push-smart.sh | 18 ++++++++++ transport.c | 67 +++++++++++++++++++++++++++++++++++++- 8 files changed, 217 insertions(+), 15 deletions(-) base-commit: 468165c1d8a442994a825f3684528361727cd8c0 Published-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v2 Fetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v2 Interdiff vs v1: diff --git a/Documentation/config.txt b/Documentation/config.txt index 4e0cff87f62..40e3828b85f 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1088,6 +1088,16 @@ clean.requireForce:: A boolean to make git-clean do nothing unless given -f, -i or -n. Defaults to true. +color.advice:: + A boolean to enable/disable color in hints (e.g. when a push + failed, see `advice.*` for a list). May be set to `always`, + `false` (or `never`) or `auto` (or `true`), in which case colors + are used only when the error output goes to a terminal. If + unset, then the value of `color.ui` is used (`auto` by default). + +color.advice.advice:: + Use customized color for hints. + color.branch:: A boolean to enable/disable color in the output of linkgit:git-branch[1]. May be set to `always`, @@ -1190,6 +1200,15 @@ color.pager:: A boolean to enable/disable colored output when the pager is in use (default is true). +color.push:: + A boolean to enable/disable color in push errors. May be set to + `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.push.error:: + Use customized color for push errors. + color.showBranch:: A boolean to enable/disable color in the output of linkgit:git-show-branch[1]. May be set to `always`, @@ -1218,6 +1237,15 @@ color.status.<slot>:: status short-format), or `unmerged` (files which have unmerged changes). +color.transport:: + A boolean to enable/disable color when pushes are rejected. May be + set to `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.transport.rejected:: + Use customized color when a push was rejected. + color.ui:: This variable determines the default value for variables such as `color.diff` and `color.grep` that control the use of color diff --git a/advice.c b/advice.c index 42460877ef6..2121c1811fd 100644 --- a/advice.c +++ b/advice.c @@ -43,7 +43,7 @@ static int parse_advise_color_slot(const char *slot) static const char *advise_get_color(enum color_advice ix) { - if (want_color(advice_use_color)) + if (want_color_stderr(advice_use_color)) return advice_colors[ix]; return ""; } @@ -87,8 +87,10 @@ void advise(const char *advice, ...) for (cp = buf.buf; *cp; cp = np) { np = strchrnul(cp, '\n'); - fprintf(stderr, _("%shint: %.*s%s\n"), advise_get_color(ADVICE_COLOR_HINT), - (int)(np - cp), cp, advise_get_color(ADVICE_COLOR_RESET)); + fprintf(stderr, _("%shint: %.*s%s\n"), + advise_get_color(ADVICE_COLOR_HINT), + (int)(np - cp), cp, + advise_get_color(ADVICE_COLOR_RESET)); if (*np) np++; } @@ -100,6 +102,11 @@ int git_default_advice_config(const char *var, const char *value) const char *k, *slot_name; int i; + if (!strcmp(var, "color.advice")) { + advice_use_color = git_config_colorbool(var, value); + return 0; + } + if (skip_prefix(var, "color.advice.", &slot_name)) { int slot = parse_advise_color_slot(slot_name); if (slot < 0) diff --git a/builtin/push.c b/builtin/push.c index e443dd40de9..ac3705370e1 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -41,7 +41,7 @@ static int parse_push_color_slot(const char *slot) static const char *push_get_color(enum color_push ix) { - if (want_color(push_use_color)) + if (want_color_stderr(push_use_color)) return push_colors[ix]; return ""; } @@ -365,10 +365,11 @@ static int push_with_options(struct transport *transport, int flags) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, &reject_reasons); - if (err != 0) + if (err != 0) { fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR)); error(_("failed to push some refs to '%s'"), transport->url); fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET)); + } err |= transport_disconnect(transport); if (!err) @@ -545,7 +546,10 @@ static int git_push_config(const char *k, const char *v, void *cb) else string_list_append(&push_options_config, v); return 0; - } else if (skip_prefix(k, "color.advice.", &slot_name)) { + } else if (!strcmp(k, "color.push")) { + push_use_color = git_config_colorbool(k, v); + return 0; + } else if (skip_prefix(k, "color.push.", &slot_name)) { int slot = parse_push_color_slot(slot_name); if (slot < 0) return 0; diff --git a/color.c b/color.c index f277e72e4ce..c6c6c4f580f 100644 --- a/color.c +++ b/color.c @@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value) return GIT_COLOR_AUTO; } -static int check_auto_color(void) +static int check_auto_color(int fd) { - if (color_stdout_is_tty < 0) - color_stdout_is_tty = isatty(1); - if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { + static int color_stderr_is_tty = -1; + int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty; + if (*is_tty_p < 0) + *is_tty_p = isatty(fd); + if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) { if (!is_terminal_dumb()) return 1; } return 0; } -int want_color(int var) +int want_color_fd(int fd, int var) { /* * NEEDSWORK: This function is sometimes used from multiple threads, and @@ -339,15 +341,15 @@ int want_color(int var) * is listed in .tsan-suppressions for the time being. */ - static int want_auto = -1; + static int want_auto[3] = { -1, -1, -1 }; if (var < 0) var = git_use_color_default; if (var == GIT_COLOR_AUTO) { - if (want_auto < 0) - want_auto = check_auto_color(); - return want_auto; + if (want_auto[fd] < 0) + want_auto[fd] = check_auto_color(fd); + return want_auto[fd]; } return var; } diff --git a/color.h b/color.h index cd0bcedd084..5b744e1bc68 100644 --- a/color.h +++ b/color.h @@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value); * Return a boolean whether to use color, where the argument 'var' is * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO. */ -int want_color(int var); +int want_color_fd(int fd, int var); +#define want_color(colorbool) want_color_fd(1, (colorbool)) +#define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) /* * Translate a Git color from 'value' into a string that the terminal can diff --git a/config.c b/config.c index b0c20e6cb8a..3bdbe36a638 100644 --- a/config.c +++ b/config.c @@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy) if (starts_with(var, "mailmap.")) return git_default_mailmap_config(var, value); - if (starts_with(var, "advice.")) + if (starts_with(var, "advice.") || starts_with(var, "color.advice")) return git_default_advice_config(var, value); if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 21340e89c96..1c2be98dc2b 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' ' grep "^To $HTTPD_URL/smart/test_repo.git" status ' +test_expect_success 'colorize errors/hints' ' + cd "$ROOT_PATH"/test_repo_clone && + cat >exp <<-EOF && + To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git + <RED>! [rejected] <RESET> origin/master^ -> master (non-fast-forward) + error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\'' + EOF + + test_must_fail git -c color.transport=always -c color.advice=always \ + -c color.push=always \ + push origin origin/master^:master 2>act && + test_decode_color <act >decoded && + test_i18ngrep "<RED>.*rejected.*<RESET>" decoded && + test_i18ngrep "<RED>error: failed to push some refs" decoded && + test_i18ngrep "<YELLOW>hint: " decoded && + test_i18ngrep ! "^hint: " decoded +' + stop_httpd test_done diff --git a/transport.c b/transport.c index dd98dd84b05..4702b9fbc8f 100644 --- a/transport.c +++ b/transport.c @@ -34,9 +34,9 @@ enum color_transport { static int transport_color_config(void) { const char *keys[] = { - "transport.color.reset", - "transport.color.rejected" - }; + "color.transport.reset", + "color.transport.rejected" + }, *key = "color.transport"; char *value; int i; static int initialized; @@ -45,6 +45,12 @@ static int transport_color_config(void) return 0; initialized = 1; + if (!git_config_get_string(key, &value)) + transport_use_color = git_config_colorbool(key, value); + + if (!want_color_stderr(transport_use_color)) + return 0; + for (i = 0; i < ARRAY_SIZE(keys); i++) if (!git_config_get_string(keys[i], &value)) { if (!value) @@ -58,7 +64,7 @@ static int transport_color_config(void) static const char *transport_get_color(enum color_transport ix) { - if (want_color(transport_use_color)) + if (want_color_stderr(transport_use_color)) return transport_colors[ix]; return ""; } @@ -382,11 +388,13 @@ static void print_ref_status(char flag, const char *summary, else fprintf(stdout, "%s\n", summary); } else { - if (strstr(summary, "rejected") != NULL || strstr(summary, "failure") != NULL) - fprintf(stderr, " %s%c %-*s%s ", transport_get_color(TRANSPORT_COLOR_REJECTED), - flag, summary_width, summary, transport_get_color(TRANSPORT_COLOR_RESET)); - else - fprintf(stderr, " %c %-*s ", flag, summary_width, summary); + const char *red = "", *reset = ""; + if (push_had_errors(to)) { + red = transport_get_color(TRANSPORT_COLOR_REJECTED); + reset = transport_get_color(TRANSPORT_COLOR_RESET); + } + fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width, + summary, reset); if (from) fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name)); else -- 2.17.0.windows.1.4.g7e4058d72e3 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 1/4] color: introduce support for colorizing stderr 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin @ 2018-04-05 22:48 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 2/4] push: colorize errors Johannes Schindelin ` (3 subsequent siblings) 4 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-05 22:48 UTC (permalink / raw) To: git; +Cc: Junio C Hamano So far, we only ever asked whether stdout wants to be colorful. In the upcoming patches, we will want to make push errors more prominent, which are printed to stderr, though. So let's refactor the want_color() function into a want_color_fd() function (which expects to be called with fd == 1 or fd == 2 for stdout and stderr, respectively), and then define the macro `want_color()` to use the want_color_fd() function. And then also add a macro `want_color_stderr()`, for convenience and for documentation. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- color.c | 20 +++++++++++--------- color.h | 4 +++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/color.c b/color.c index f277e72e4ce..c6c6c4f580f 100644 --- a/color.c +++ b/color.c @@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value) return GIT_COLOR_AUTO; } -static int check_auto_color(void) +static int check_auto_color(int fd) { - if (color_stdout_is_tty < 0) - color_stdout_is_tty = isatty(1); - if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { + static int color_stderr_is_tty = -1; + int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty; + if (*is_tty_p < 0) + *is_tty_p = isatty(fd); + if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) { if (!is_terminal_dumb()) return 1; } return 0; } -int want_color(int var) +int want_color_fd(int fd, int var) { /* * NEEDSWORK: This function is sometimes used from multiple threads, and @@ -339,15 +341,15 @@ int want_color(int var) * is listed in .tsan-suppressions for the time being. */ - static int want_auto = -1; + static int want_auto[3] = { -1, -1, -1 }; if (var < 0) var = git_use_color_default; if (var == GIT_COLOR_AUTO) { - if (want_auto < 0) - want_auto = check_auto_color(); - return want_auto; + if (want_auto[fd] < 0) + want_auto[fd] = check_auto_color(fd); + return want_auto[fd]; } return var; } diff --git a/color.h b/color.h index cd0bcedd084..5b744e1bc68 100644 --- a/color.h +++ b/color.h @@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value); * Return a boolean whether to use color, where the argument 'var' is * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO. */ -int want_color(int var); +int want_color_fd(int fd, int var); +#define want_color(colorbool) want_color_fd(1, (colorbool)) +#define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) /* * Translate a Git color from 'value' into a string that the terminal can -- 2.17.0.windows.1.4.g7e4058d72e3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 2/4] push: colorize errors 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 1/4] color: introduce support for colorizing stderr Johannes Schindelin @ 2018-04-05 22:48 ` Johannes Schindelin 2018-04-05 23:37 ` Jacob Keller 2018-04-05 22:48 ` [PATCH v2 3/4] Add a test to verify that push errors are colorful Johannes Schindelin ` (2 subsequent siblings) 4 siblings, 1 reply; 22+ messages in thread From: Johannes Schindelin @ 2018-04-05 22:48 UTC (permalink / raw) To: git; +Cc: Ryan Dammrose, Junio C Hamano From: Ryan Dammrose <ryandammrose@gmail.com> This is an attempt to resolve an issue I experience with people that are new to Git -- especially colleagues in a team setting -- where they miss that their push to a remote location failed because the failure and success both return a block of white text. An example is if I push something to a remote repository and then a colleague attempts to push to the same remote repository and the push fails because it requires them to pull first, but they don't notice because a success and failure both return a block of white text. They then continue about their business, thinking it has been successfully pushed. This patch colorizes the errors and hints (in red and yellow, respectively) so whenever there is a failure when pushing to a remote repository that fails, it is more noticeable. [jes: fixed a couple bugs, added the color.{advice,push,transport} settings, refactored to use want_color_stderr().] Signed-off-by: Ryan Dammrose ryandammrose@gmail.com Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> squash! push: colorize errors Stop talking about localized errors --- advice.c | 49 ++++++++++++++++++++++++++++++++++-- builtin/push.c | 44 ++++++++++++++++++++++++++++++++- config.c | 2 +- transport.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 157 insertions(+), 5 deletions(-) diff --git a/advice.c b/advice.c index 406efc183ba..2121c1811fd 100644 --- a/advice.c +++ b/advice.c @@ -1,5 +1,6 @@ #include "cache.h" #include "config.h" +#include "color.h" int advice_push_update_rejected = 1; int advice_push_non_ff_current = 1; @@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1; int advice_ignored_hook = 1; int advice_waiting_for_editor = 1; +static int advice_use_color = -1; +static char advice_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_YELLOW, /* HINT */ +}; + +enum color_advice { + ADVICE_COLOR_RESET = 0, + ADVICE_COLOR_HINT = 1, +}; + +static int parse_advise_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return ADVICE_COLOR_RESET; + if (!strcasecmp(slot, "advice")) + return ADVICE_COLOR_HINT; + return -1; +} + +static const char *advise_get_color(enum color_advice ix) +{ + if (want_color_stderr(advice_use_color)) + return advice_colors[ix]; + return ""; +} + static struct { const char *name; int *preference; @@ -59,7 +87,10 @@ void advise(const char *advice, ...) for (cp = buf.buf; *cp; cp = np) { np = strchrnul(cp, '\n'); - fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp); + fprintf(stderr, _("%shint: %.*s%s\n"), + advise_get_color(ADVICE_COLOR_HINT), + (int)(np - cp), cp, + advise_get_color(ADVICE_COLOR_RESET)); if (*np) np++; } @@ -68,9 +99,23 @@ void advise(const char *advice, ...) int git_default_advice_config(const char *var, const char *value) { - const char *k; + const char *k, *slot_name; int i; + if (!strcmp(var, "color.advice")) { + advice_use_color = git_config_colorbool(var, value); + return 0; + } + + if (skip_prefix(var, "color.advice.", &slot_name)) { + int slot = parse_advise_color_slot(slot_name); + if (slot < 0) + return 0; + if (!value) + return config_error_nonbool(var); + return color_parse(value, advice_colors[slot]); + } + if (!skip_prefix(var, "advice.", &k)) return 0; diff --git a/builtin/push.c b/builtin/push.c index 013c20d6164..ac3705370e1 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -12,12 +12,40 @@ #include "submodule.h" #include "submodule-config.h" #include "send-pack.h" +#include "color.h" static const char * const push_usage[] = { N_("git push [<options>] [<repository> [<refspec>...]]"), NULL, }; +static int push_use_color = -1; +static char push_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED, /* ERROR */ +}; + +enum color_push { + PUSH_COLOR_RESET = 0, + PUSH_COLOR_ERROR = 1 +}; + +static int parse_push_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return PUSH_COLOR_RESET; + if (!strcasecmp(slot, "error")) + return PUSH_COLOR_ERROR; + return -1; +} + +static const char *push_get_color(enum color_push ix) +{ + if (want_color_stderr(push_use_color)) + return push_colors[ix]; + return ""; +} + static int thin = 1; static int deleterefs; static const char *receivepack; @@ -337,8 +365,11 @@ static int push_with_options(struct transport *transport, int flags) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, &reject_reasons); - if (err != 0) + if (err != 0) { + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR)); error(_("failed to push some refs to '%s'"), transport->url); + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET)); + } err |= transport_disconnect(transport); if (!err) @@ -467,6 +498,7 @@ static void set_push_cert_flags(int *flags, int v) static int git_push_config(const char *k, const char *v, void *cb) { + const char *slot_name; int *flags = cb; int status; @@ -514,6 +546,16 @@ static int git_push_config(const char *k, const char *v, void *cb) else string_list_append(&push_options_config, v); return 0; + } else if (!strcmp(k, "color.push")) { + push_use_color = git_config_colorbool(k, v); + return 0; + } else if (skip_prefix(k, "color.push.", &slot_name)) { + int slot = parse_push_color_slot(slot_name); + if (slot < 0) + return 0; + if (!v) + return config_error_nonbool(k); + return color_parse(v, push_colors[slot]); } return git_default_config(k, v, NULL); diff --git a/config.c b/config.c index b0c20e6cb8a..3bdbe36a638 100644 --- a/config.c +++ b/config.c @@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy) if (starts_with(var, "mailmap.")) return git_default_mailmap_config(var, value); - if (starts_with(var, "advice.")) + if (starts_with(var, "advice.") || starts_with(var, "color.advice")) return git_default_advice_config(var, value); if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { diff --git a/transport.c b/transport.c index 00d48b5b565..4702b9fbc8f 100644 --- a/transport.c +++ b/transport.c @@ -18,6 +18,56 @@ #include "sha1-array.h" #include "sigchain.h" #include "transport-internal.h" +#include "color.h" + +static int transport_use_color = -1; +static char transport_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED /* REJECTED */ +}; + +enum color_transport { + TRANSPORT_COLOR_RESET = 0, + TRANSPORT_COLOR_REJECTED = 1 +}; + +static int transport_color_config(void) +{ + const char *keys[] = { + "color.transport.reset", + "color.transport.rejected" + }, *key = "color.transport"; + char *value; + int i; + static int initialized; + + if (initialized) + return 0; + initialized = 1; + + if (!git_config_get_string(key, &value)) + transport_use_color = git_config_colorbool(key, value); + + if (!want_color_stderr(transport_use_color)) + return 0; + + for (i = 0; i < ARRAY_SIZE(keys); i++) + if (!git_config_get_string(keys[i], &value)) { + if (!value) + return config_error_nonbool(keys[i]); + if (color_parse(value, transport_colors[i]) < 0) + return -1; + } + + return 0; +} + +static const char *transport_get_color(enum color_transport ix) +{ + if (want_color_stderr(transport_use_color)) + return transport_colors[ix]; + return ""; +} static void set_upstreams(struct transport *transport, struct ref *refs, int pretend) @@ -338,7 +388,13 @@ static void print_ref_status(char flag, const char *summary, else fprintf(stdout, "%s\n", summary); } else { - fprintf(stderr, " %c %-*s ", flag, summary_width, summary); + const char *red = "", *reset = ""; + if (push_had_errors(to)) { + red = transport_get_color(TRANSPORT_COLOR_REJECTED); + reset = transport_get_color(TRANSPORT_COLOR_RESET); + } + fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width, + summary, reset); if (from) fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name)); else @@ -487,6 +543,9 @@ void transport_print_push_status(const char *dest, struct ref *refs, char *head; int summary_width = transport_summary_width(refs); + if (transport_color_config() < 0) + warning(_("could not parse transport.color.* config")); + head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL); if (verbose) { @@ -553,6 +612,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re struct send_pack_args args; int ret; + if (transport_color_config() < 0) + return -1; + if (!data->got_remote_heads) { struct ref *tmp_refs; connect_setup(transport, 1); @@ -997,6 +1059,9 @@ int transport_push(struct transport *transport, *reject_reasons = 0; transport_verify_remote_names(refspec_nr, refspec); + if (transport_color_config() < 0) + return -1; + if (transport->vtable->push_refs) { struct ref *remote_refs; struct ref *local_refs = get_local_heads(); -- 2.17.0.windows.1.4.g7e4058d72e3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/4] push: colorize errors 2018-04-05 22:48 ` [PATCH v2 2/4] push: colorize errors Johannes Schindelin @ 2018-04-05 23:37 ` Jacob Keller 2018-04-06 11:15 ` Johannes Schindelin 0 siblings, 1 reply; 22+ messages in thread From: Jacob Keller @ 2018-04-05 23:37 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git mailing list, Ryan Dammrose, Junio C Hamano On Thu, Apr 5, 2018 at 3:48 PM, Johannes Schindelin <johannes.schindelin@gmx.de> wrote: > From: Ryan Dammrose <ryandammrose@gmail.com> > > This is an attempt to resolve an issue I experience with people that are > new to Git -- especially colleagues in a team setting -- where they miss > that their push to a remote location failed because the failure and > success both return a block of white text. > > An example is if I push something to a remote repository and then a > colleague attempts to push to the same remote repository and the push > fails because it requires them to pull first, but they don't notice > because a success and failure both return a block of white text. They > then continue about their business, thinking it has been successfully > pushed. > > This patch colorizes the errors and hints (in red and yellow, > respectively) so whenever there is a failure when pushing to a remote > repository that fails, it is more noticeable. > > [jes: fixed a couple bugs, added the color.{advice,push,transport} > settings, refactored to use want_color_stderr().] > > Signed-off-by: Ryan Dammrose ryandammrose@gmail.com > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > > squash! push: colorize errors > > Stop talking about localized errors Guessing you intended to remove this part after squashing? Didn't see anything else to comment on in the actual code. Thanks, Jake ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/4] push: colorize errors 2018-04-05 23:37 ` Jacob Keller @ 2018-04-06 11:15 ` Johannes Schindelin 0 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-06 11:15 UTC (permalink / raw) To: Jacob Keller; +Cc: Git mailing list, Ryan Dammrose, Junio C Hamano Hi Jake, On Thu, 5 Apr 2018, Jacob Keller wrote: > On Thu, Apr 5, 2018 at 3:48 PM, Johannes Schindelin > <johannes.schindelin@gmx.de> wrote: > > From: Ryan Dammrose <ryandammrose@gmail.com> > > > > This is an attempt to resolve an issue I experience with people that are > > new to Git -- especially colleagues in a team setting -- where they miss > > that their push to a remote location failed because the failure and > > success both return a block of white text. > > > > An example is if I push something to a remote repository and then a > > colleague attempts to push to the same remote repository and the push > > fails because it requires them to pull first, but they don't notice > > because a success and failure both return a block of white text. They > > then continue about their business, thinking it has been successfully > > pushed. > > > > This patch colorizes the errors and hints (in red and yellow, > > respectively) so whenever there is a failure when pushing to a remote > > repository that fails, it is more noticeable. > > > > [jes: fixed a couple bugs, added the color.{advice,push,transport} > > settings, refactored to use want_color_stderr().] > > > > Signed-off-by: Ryan Dammrose ryandammrose@gmail.com > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > > > > squash! push: colorize errors > > > > Stop talking about localized errors > > Guessing you intended to remove this part after squashing? Hah! You caught be red-handed. This was intended as a reminder, as you probably guessed, to remove any mentions of "localized errors" because I had verified that there was no localized error message; besides, I replaced the call to strstr() looking at the error message with a call to push_had_errors() (i.e. using the ref_status instead). So there are definitely no issues about localized errors left. > Didn't see anything else to comment on in the actual code. Thank you, Dscho ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 3/4] Add a test to verify that push errors are colorful 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 1/4] color: introduce support for colorizing stderr Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 2/4] push: colorize errors Johannes Schindelin @ 2018-04-05 22:48 ` Johannes Schindelin 2018-04-06 10:50 ` Eric Sunshine 2018-04-05 22:48 ` [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin 4 siblings, 1 reply; 22+ messages in thread From: Johannes Schindelin @ 2018-04-05 22:48 UTC (permalink / raw) To: git; +Cc: Junio C Hamano This actually only tests whether the push errors/hints are colored if the respective color.* config settings are `always`, but in the regular case they default to `auto` (in which case we color the messages when stderr is connected to an interactive terminal), therefore these tests should suffice. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- t/t5541-http-push-smart.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 21340e89c96..1c2be98dc2b 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' ' grep "^To $HTTPD_URL/smart/test_repo.git" status ' +test_expect_success 'colorize errors/hints' ' + cd "$ROOT_PATH"/test_repo_clone && + cat >exp <<-EOF && + To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git + <RED>! [rejected] <RESET> origin/master^ -> master (non-fast-forward) + error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\'' + EOF + + test_must_fail git -c color.transport=always -c color.advice=always \ + -c color.push=always \ + push origin origin/master^:master 2>act && + test_decode_color <act >decoded && + test_i18ngrep "<RED>.*rejected.*<RESET>" decoded && + test_i18ngrep "<RED>error: failed to push some refs" decoded && + test_i18ngrep "<YELLOW>hint: " decoded && + test_i18ngrep ! "^hint: " decoded +' + stop_httpd test_done -- 2.17.0.windows.1.4.g7e4058d72e3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 3/4] Add a test to verify that push errors are colorful 2018-04-05 22:48 ` [PATCH v2 3/4] Add a test to verify that push errors are colorful Johannes Schindelin @ 2018-04-06 10:50 ` Eric Sunshine 2018-04-06 12:13 ` Johannes Schindelin 0 siblings, 1 reply; 22+ messages in thread From: Eric Sunshine @ 2018-04-06 10:50 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git List, Junio C Hamano On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin <johannes.schindelin@gmx.de> wrote: > This actually only tests whether the push errors/hints are colored if > the respective color.* config settings are `always`, but in the regular > case they default to `auto` (in which case we color the messages when > stderr is connected to an interactive terminal), therefore these tests > should suffice. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh > @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' ' > +test_expect_success 'colorize errors/hints' ' > + cd "$ROOT_PATH"/test_repo_clone && > + cat >exp <<-EOF && > + To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git > + <RED>! [rejected] <RESET> origin/master^ -> master (non-fast-forward) > + error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\'' > + EOF This "exp" file is not used by the test. > + test_must_fail git -c color.transport=always -c color.advice=always \ > + -c color.push=always \ > + push origin origin/master^:master 2>act && > + test_decode_color <act >decoded && > + test_i18ngrep "<RED>.*rejected.*<RESET>" decoded && > + test_i18ngrep "<RED>error: failed to push some refs" decoded && > + test_i18ngrep "<YELLOW>hint: " decoded && > + test_i18ngrep ! "^hint: " decoded > +' ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 3/4] Add a test to verify that push errors are colorful 2018-04-06 10:50 ` Eric Sunshine @ 2018-04-06 12:13 ` Johannes Schindelin 0 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-06 12:13 UTC (permalink / raw) To: Eric Sunshine; +Cc: Git List, Junio C Hamano Hi Eric, On Fri, 6 Apr 2018, Eric Sunshine wrote: > On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin > <johannes.schindelin@gmx.de> wrote: > > This actually only tests whether the push errors/hints are colored if > > the respective color.* config settings are `always`, but in the regular > > case they default to `auto` (in which case we color the messages when > > stderr is connected to an interactive terminal), therefore these tests > > should suffice. > > > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > > --- > > diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh > > @@ -377,5 +377,23 @@ test_expect_success 'push status output scrubs password' ' > > +test_expect_success 'colorize errors/hints' ' > > + cd "$ROOT_PATH"/test_repo_clone && > > + cat >exp <<-EOF && > > + To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git > > + <RED>! [rejected] <RESET> origin/master^ -> master (non-fast-forward) > > + error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\'' > > + EOF > > This "exp" file is not used by the test. Indeed! I was *so* sure I had removed it, but a `git stash` must have made that change go away before I could commit it. Will be fixed in v3. Ciao, Dscho ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin ` (2 preceding siblings ...) 2018-04-05 22:48 ` [PATCH v2 3/4] Add a test to verify that push errors are colorful Johannes Schindelin @ 2018-04-05 22:48 ` Johannes Schindelin 2018-04-06 10:56 ` Eric Sunshine 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin 4 siblings, 1 reply; 22+ messages in thread From: Johannes Schindelin @ 2018-04-05 22:48 UTC (permalink / raw) To: git; +Cc: Junio C Hamano Let's make it easier for users to find out how to customize these colors. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- Documentation/config.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 4e0cff87f62..40e3828b85f 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1088,6 +1088,16 @@ clean.requireForce:: A boolean to make git-clean do nothing unless given -f, -i or -n. Defaults to true. +color.advice:: + A boolean to enable/disable color in hints (e.g. when a push + failed, see `advice.*` for a list). May be set to `always`, + `false` (or `never`) or `auto` (or `true`), in which case colors + are used only when the error output goes to a terminal. If + unset, then the value of `color.ui` is used (`auto` by default). + +color.advice.advice:: + Use customized color for hints. + color.branch:: A boolean to enable/disable color in the output of linkgit:git-branch[1]. May be set to `always`, @@ -1190,6 +1200,15 @@ color.pager:: A boolean to enable/disable colored output when the pager is in use (default is true). +color.push:: + A boolean to enable/disable color in push errors. May be set to + `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.push.error:: + Use customized color for push errors. + color.showBranch:: A boolean to enable/disable color in the output of linkgit:git-show-branch[1]. May be set to `always`, @@ -1218,6 +1237,15 @@ color.status.<slot>:: status short-format), or `unmerged` (files which have unmerged changes). +color.transport:: + A boolean to enable/disable color when pushes are rejected. May be + set to `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.transport.rejected:: + Use customized color when a push was rejected. + color.ui:: This variable determines the default value for variables such as `color.diff` and `color.grep` that control the use of color -- 2.17.0.windows.1.4.g7e4058d72e3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints 2018-04-05 22:48 ` [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin @ 2018-04-06 10:56 ` Eric Sunshine 2018-04-06 12:15 ` Johannes Schindelin 0 siblings, 1 reply; 22+ messages in thread From: Eric Sunshine @ 2018-04-06 10:56 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git List, Junio C Hamano On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin <johannes.schindelin@gmx.de> wrote: > Let's make it easier for users to find out how to customize these colors. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > diff --git a/Documentation/config.txt b/Documentation/config.txt > @@ -1088,6 +1088,16 @@ clean.requireForce:: > +color.advice:: > + A boolean to enable/disable color in hints (e.g. when a push > + failed, see `advice.*` for a list). May be set to `always`, > + `false` (or `never`) or `auto` (or `true`), in which case colors > + are used only when the error output goes to a terminal. If > + unset, then the value of `color.ui` is used (`auto` by default). > + > +color.advice.advice:: > + Use customized color for hints. Is "color.advice.advice" correct? ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints 2018-04-06 10:56 ` Eric Sunshine @ 2018-04-06 12:15 ` Johannes Schindelin 2018-04-07 6:55 ` Eric Sunshine 0 siblings, 1 reply; 22+ messages in thread From: Johannes Schindelin @ 2018-04-06 12:15 UTC (permalink / raw) To: Eric Sunshine; +Cc: Git List, Junio C Hamano Hi Eric, On Fri, 6 Apr 2018, Eric Sunshine wrote: > On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin > <johannes.schindelin@gmx.de> wrote: > > Let's make it easier for users to find out how to customize these colors. > > > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > > --- > > diff --git a/Documentation/config.txt b/Documentation/config.txt > > @@ -1088,6 +1088,16 @@ clean.requireForce:: > > +color.advice:: > > + A boolean to enable/disable color in hints (e.g. when a push > > + failed, see `advice.*` for a list). May be set to `always`, > > + `false` (or `never`) or `auto` (or `true`), in which case colors > > + are used only when the error output goes to a terminal. If > > + unset, then the value of `color.ui` is used (`auto` by default). > > + > > +color.advice.advice:: > > + Use customized color for hints. > > Is "color.advice.advice" correct? As per the patch, yes. But you're right, it sounds silly. Will change to `color.advice.hint`, okay? Will be fixed in v3, Dscho ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints 2018-04-06 12:15 ` Johannes Schindelin @ 2018-04-07 6:55 ` Eric Sunshine 0 siblings, 0 replies; 22+ messages in thread From: Eric Sunshine @ 2018-04-07 6:55 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Git List, Junio C Hamano On Fri, Apr 6, 2018 at 8:15 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > On Fri, 6 Apr 2018, Eric Sunshine wrote: >> On Thu, Apr 5, 2018 at 6:48 PM, Johannes Schindelin >> <johannes.schindelin@gmx.de> wrote: >> > +color.advice.advice:: >> > + Use customized color for hints. >> >> Is "color.advice.advice" correct? > > As per the patch, yes. But you're right, it sounds silly. Will change to > `color.advice.hint`, okay? That's more understandable. Thanks. ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 0/4] Colorize push errors 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin ` (3 preceding siblings ...) 2018-04-05 22:48 ` [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin @ 2018-04-21 10:09 ` Johannes Schindelin 2018-04-21 10:09 ` [PATCH v3 1/4] color: introduce support for colorizing stderr Johannes Schindelin ` (3 more replies) 4 siblings, 4 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-21 10:09 UTC (permalink / raw) To: git Cc: Junio C Hamano, Eric Sunshine, Jacob Keller, Ævar Arnfjörð Bjarmason To help users discern large chunks of white text (when the push succeeds) from large chunks of white text (when the push fails), let's add some color to the latter. The original contribution came in via Pull Request from the Git for Windows project: https://github.com/git-for-windows/git/pull/1429 I almost forgot to submit v3. Guess it's a good thing I have a project management system with tickets I can move through a story board... Changes since v2: - removed a bogus "squash! ..." from the commit message of 2/4 - removed the unnecessary here-doc from the test added in 4/4 - renamed color.advice.advice to color.advice.hint in 2/4 and 4/4 Johannes Schindelin (3): color: introduce support for colorizing stderr Add a test to verify that push errors are colorful Document the new color.* settings to colorize push errors/hints Ryan Dammrose (1): push: colorize errors Documentation/config.txt | 28 ++++++++++++++++ advice.c | 49 ++++++++++++++++++++++++++-- builtin/push.c | 44 ++++++++++++++++++++++++- color.c | 20 +++++++----- color.h | 4 ++- config.c | 2 +- t/t5541-http-push-smart.sh | 12 +++++++ transport.c | 67 +++++++++++++++++++++++++++++++++++++- 8 files changed, 211 insertions(+), 15 deletions(-) base-commit: fe0a9eaf31dd0c349ae4308498c33a5c3794b293 Published-As: https://github.com/dscho/git/releases/tag/colorize-push-errors-v3 Fetch-It-Via: git fetch https://github.com/dscho/git colorize-push-errors-v3 Interdiff vs v2: diff --git a/Documentation/config.txt b/Documentation/config.txt index 1fef60a7301..2cea0c6c899 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1095,7 +1095,7 @@ color.advice:: are used only when the error output goes to a terminal. If unset, then the value of `color.ui` is used (`auto` by default). -color.advice.advice:: +color.advice.hint:: Use customized color for hints. color.branch:: diff --git a/advice.c b/advice.c index 2121c1811fd..89fda1de55b 100644 --- a/advice.c +++ b/advice.c @@ -36,7 +36,7 @@ static int parse_advise_color_slot(const char *slot) { if (!strcasecmp(slot, "reset")) return ADVICE_COLOR_RESET; - if (!strcasecmp(slot, "advice")) + if (!strcasecmp(slot, "hint")) return ADVICE_COLOR_HINT; return -1; } diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 1c2be98dc2b..a2af693068f 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -379,12 +379,6 @@ test_expect_success 'push status output scrubs password' ' test_expect_success 'colorize errors/hints' ' cd "$ROOT_PATH"/test_repo_clone && - cat >exp <<-EOF && - To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git - <RED>! [rejected] <RESET> origin/master^ -> master (non-fast-forward) - error: failed to push some refs to '\''http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'\'' - EOF - test_must_fail git -c color.transport=always -c color.advice=always \ -c color.push=always \ push origin origin/master^:master 2>act && -- 2.17.0.windows.1.15.gaa56ade3205 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 1/4] color: introduce support for colorizing stderr 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin @ 2018-04-21 10:09 ` Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 2/4] push: colorize errors Johannes Schindelin ` (2 subsequent siblings) 3 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-21 10:09 UTC (permalink / raw) To: git Cc: Junio C Hamano, Eric Sunshine, Jacob Keller, Ævar Arnfjörð Bjarmason So far, we only ever asked whether stdout wants to be colorful. In the upcoming patches, we will want to make push errors more prominent, which are printed to stderr, though. So let's refactor the want_color() function into a want_color_fd() function (which expects to be called with fd == 1 or fd == 2 for stdout and stderr, respectively), and then define the macro `want_color()` to use the want_color_fd() function. And then also add a macro `want_color_stderr()`, for convenience and for documentation. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- color.c | 20 +++++++++++--------- color.h | 4 +++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/color.c b/color.c index f277e72e4ce..c6c6c4f580f 100644 --- a/color.c +++ b/color.c @@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value) return GIT_COLOR_AUTO; } -static int check_auto_color(void) +static int check_auto_color(int fd) { - if (color_stdout_is_tty < 0) - color_stdout_is_tty = isatty(1); - if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) { + static int color_stderr_is_tty = -1; + int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty; + if (*is_tty_p < 0) + *is_tty_p = isatty(fd); + if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) { if (!is_terminal_dumb()) return 1; } return 0; } -int want_color(int var) +int want_color_fd(int fd, int var) { /* * NEEDSWORK: This function is sometimes used from multiple threads, and @@ -339,15 +341,15 @@ int want_color(int var) * is listed in .tsan-suppressions for the time being. */ - static int want_auto = -1; + static int want_auto[3] = { -1, -1, -1 }; if (var < 0) var = git_use_color_default; if (var == GIT_COLOR_AUTO) { - if (want_auto < 0) - want_auto = check_auto_color(); - return want_auto; + if (want_auto[fd] < 0) + want_auto[fd] = check_auto_color(fd); + return want_auto[fd]; } return var; } diff --git a/color.h b/color.h index cd0bcedd084..5b744e1bc68 100644 --- a/color.h +++ b/color.h @@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value); * Return a boolean whether to use color, where the argument 'var' is * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO. */ -int want_color(int var); +int want_color_fd(int fd, int var); +#define want_color(colorbool) want_color_fd(1, (colorbool)) +#define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) /* * Translate a Git color from 'value' into a string that the terminal can -- 2.17.0.windows.1.15.gaa56ade3205 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 2/4] push: colorize errors 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin 2018-04-21 10:09 ` [PATCH v3 1/4] color: introduce support for colorizing stderr Johannes Schindelin @ 2018-04-21 10:10 ` Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 3/4] Add a test to verify that push errors are colorful Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin 3 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-21 10:10 UTC (permalink / raw) To: git Cc: Ryan Dammrose, Junio C Hamano, Eric Sunshine, Jacob Keller, Ævar Arnfjörð Bjarmason From: Ryan Dammrose <ryandammrose@gmail.com> This is an attempt to resolve an issue I experience with people that are new to Git -- especially colleagues in a team setting -- where they miss that their push to a remote location failed because the failure and success both return a block of white text. An example is if I push something to a remote repository and then a colleague attempts to push to the same remote repository and the push fails because it requires them to pull first, but they don't notice because a success and failure both return a block of white text. They then continue about their business, thinking it has been successfully pushed. This patch colorizes the errors and hints (in red and yellow, respectively) so whenever there is a failure when pushing to a remote repository that fails, it is more noticeable. [jes: fixed a couple bugs, added the color.{advice,push,transport} settings, refactored to use want_color_stderr().] Signed-off-by: Ryan Dammrose ryandammrose@gmail.com Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- advice.c | 49 ++++++++++++++++++++++++++++++++++-- builtin/push.c | 44 ++++++++++++++++++++++++++++++++- config.c | 2 +- transport.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 157 insertions(+), 5 deletions(-) diff --git a/advice.c b/advice.c index 406efc183ba..89fda1de55b 100644 --- a/advice.c +++ b/advice.c @@ -1,5 +1,6 @@ #include "cache.h" #include "config.h" +#include "color.h" int advice_push_update_rejected = 1; int advice_push_non_ff_current = 1; @@ -20,6 +21,33 @@ int advice_add_embedded_repo = 1; int advice_ignored_hook = 1; int advice_waiting_for_editor = 1; +static int advice_use_color = -1; +static char advice_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_YELLOW, /* HINT */ +}; + +enum color_advice { + ADVICE_COLOR_RESET = 0, + ADVICE_COLOR_HINT = 1, +}; + +static int parse_advise_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return ADVICE_COLOR_RESET; + if (!strcasecmp(slot, "hint")) + return ADVICE_COLOR_HINT; + return -1; +} + +static const char *advise_get_color(enum color_advice ix) +{ + if (want_color_stderr(advice_use_color)) + return advice_colors[ix]; + return ""; +} + static struct { const char *name; int *preference; @@ -59,7 +87,10 @@ void advise(const char *advice, ...) for (cp = buf.buf; *cp; cp = np) { np = strchrnul(cp, '\n'); - fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp); + fprintf(stderr, _("%shint: %.*s%s\n"), + advise_get_color(ADVICE_COLOR_HINT), + (int)(np - cp), cp, + advise_get_color(ADVICE_COLOR_RESET)); if (*np) np++; } @@ -68,9 +99,23 @@ void advise(const char *advice, ...) int git_default_advice_config(const char *var, const char *value) { - const char *k; + const char *k, *slot_name; int i; + if (!strcmp(var, "color.advice")) { + advice_use_color = git_config_colorbool(var, value); + return 0; + } + + if (skip_prefix(var, "color.advice.", &slot_name)) { + int slot = parse_advise_color_slot(slot_name); + if (slot < 0) + return 0; + if (!value) + return config_error_nonbool(var); + return color_parse(value, advice_colors[slot]); + } + if (!skip_prefix(var, "advice.", &k)) return 0; diff --git a/builtin/push.c b/builtin/push.c index 013c20d6164..ac3705370e1 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -12,12 +12,40 @@ #include "submodule.h" #include "submodule-config.h" #include "send-pack.h" +#include "color.h" static const char * const push_usage[] = { N_("git push [<options>] [<repository> [<refspec>...]]"), NULL, }; +static int push_use_color = -1; +static char push_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED, /* ERROR */ +}; + +enum color_push { + PUSH_COLOR_RESET = 0, + PUSH_COLOR_ERROR = 1 +}; + +static int parse_push_color_slot(const char *slot) +{ + if (!strcasecmp(slot, "reset")) + return PUSH_COLOR_RESET; + if (!strcasecmp(slot, "error")) + return PUSH_COLOR_ERROR; + return -1; +} + +static const char *push_get_color(enum color_push ix) +{ + if (want_color_stderr(push_use_color)) + return push_colors[ix]; + return ""; +} + static int thin = 1; static int deleterefs; static const char *receivepack; @@ -337,8 +365,11 @@ static int push_with_options(struct transport *transport, int flags) fprintf(stderr, _("Pushing to %s\n"), transport->url); err = transport_push(transport, refspec_nr, refspec, flags, &reject_reasons); - if (err != 0) + if (err != 0) { + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR)); error(_("failed to push some refs to '%s'"), transport->url); + fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET)); + } err |= transport_disconnect(transport); if (!err) @@ -467,6 +498,7 @@ static void set_push_cert_flags(int *flags, int v) static int git_push_config(const char *k, const char *v, void *cb) { + const char *slot_name; int *flags = cb; int status; @@ -514,6 +546,16 @@ static int git_push_config(const char *k, const char *v, void *cb) else string_list_append(&push_options_config, v); return 0; + } else if (!strcmp(k, "color.push")) { + push_use_color = git_config_colorbool(k, v); + return 0; + } else if (skip_prefix(k, "color.push.", &slot_name)) { + int slot = parse_push_color_slot(slot_name); + if (slot < 0) + return 0; + if (!v) + return config_error_nonbool(k); + return color_parse(v, push_colors[slot]); } return git_default_config(k, v, NULL); diff --git a/config.c b/config.c index c698988f5e1..f21317a25a7 100644 --- a/config.c +++ b/config.c @@ -1365,7 +1365,7 @@ int git_default_config(const char *var, const char *value, void *dummy) if (starts_with(var, "mailmap.")) return git_default_mailmap_config(var, value); - if (starts_with(var, "advice.")) + if (starts_with(var, "advice.") || starts_with(var, "color.advice")) return git_default_advice_config(var, value); if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { diff --git a/transport.c b/transport.c index 94eccf29aa3..f72081a5a58 100644 --- a/transport.c +++ b/transport.c @@ -19,6 +19,56 @@ #include "sigchain.h" #include "transport-internal.h" #include "object-store.h" +#include "color.h" + +static int transport_use_color = -1; +static char transport_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_RED /* REJECTED */ +}; + +enum color_transport { + TRANSPORT_COLOR_RESET = 0, + TRANSPORT_COLOR_REJECTED = 1 +}; + +static int transport_color_config(void) +{ + const char *keys[] = { + "color.transport.reset", + "color.transport.rejected" + }, *key = "color.transport"; + char *value; + int i; + static int initialized; + + if (initialized) + return 0; + initialized = 1; + + if (!git_config_get_string(key, &value)) + transport_use_color = git_config_colorbool(key, value); + + if (!want_color_stderr(transport_use_color)) + return 0; + + for (i = 0; i < ARRAY_SIZE(keys); i++) + if (!git_config_get_string(keys[i], &value)) { + if (!value) + return config_error_nonbool(keys[i]); + if (color_parse(value, transport_colors[i]) < 0) + return -1; + } + + return 0; +} + +static const char *transport_get_color(enum color_transport ix) +{ + if (want_color_stderr(transport_use_color)) + return transport_colors[ix]; + return ""; +} static void set_upstreams(struct transport *transport, struct ref *refs, int pretend) @@ -339,7 +389,13 @@ static void print_ref_status(char flag, const char *summary, else fprintf(stdout, "%s\n", summary); } else { - fprintf(stderr, " %c %-*s ", flag, summary_width, summary); + const char *red = "", *reset = ""; + if (push_had_errors(to)) { + red = transport_get_color(TRANSPORT_COLOR_REJECTED); + reset = transport_get_color(TRANSPORT_COLOR_RESET); + } + fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width, + summary, reset); if (from) fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name)); else @@ -488,6 +544,9 @@ void transport_print_push_status(const char *dest, struct ref *refs, char *head; int summary_width = transport_summary_width(refs); + if (transport_color_config() < 0) + warning(_("could not parse transport.color.* config")); + head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL); if (verbose) { @@ -554,6 +613,9 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re struct send_pack_args args; int ret; + if (transport_color_config() < 0) + return -1; + if (!data->got_remote_heads) { struct ref *tmp_refs; connect_setup(transport, 1); @@ -998,6 +1060,9 @@ int transport_push(struct transport *transport, *reject_reasons = 0; transport_verify_remote_names(refspec_nr, refspec); + if (transport_color_config() < 0) + return -1; + if (transport->vtable->push_refs) { struct ref *remote_refs; struct ref *local_refs = get_local_heads(); -- 2.17.0.windows.1.15.gaa56ade3205 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 3/4] Add a test to verify that push errors are colorful 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin 2018-04-21 10:09 ` [PATCH v3 1/4] color: introduce support for colorizing stderr Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 2/4] push: colorize errors Johannes Schindelin @ 2018-04-21 10:10 ` Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin 3 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-21 10:10 UTC (permalink / raw) To: git Cc: Junio C Hamano, Eric Sunshine, Jacob Keller, Ævar Arnfjörð Bjarmason This actually only tests whether the push errors/hints are colored if the respective color.* config settings are `always`, but in the regular case they default to `auto` (in which case we color the messages when stderr is connected to an interactive terminal), therefore these tests should suffice. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- t/t5541-http-push-smart.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 21340e89c96..a2af693068f 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -377,5 +377,17 @@ test_expect_success 'push status output scrubs password' ' grep "^To $HTTPD_URL/smart/test_repo.git" status ' +test_expect_success 'colorize errors/hints' ' + cd "$ROOT_PATH"/test_repo_clone && + test_must_fail git -c color.transport=always -c color.advice=always \ + -c color.push=always \ + push origin origin/master^:master 2>act && + test_decode_color <act >decoded && + test_i18ngrep "<RED>.*rejected.*<RESET>" decoded && + test_i18ngrep "<RED>error: failed to push some refs" decoded && + test_i18ngrep "<YELLOW>hint: " decoded && + test_i18ngrep ! "^hint: " decoded +' + stop_httpd test_done -- 2.17.0.windows.1.15.gaa56ade3205 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v3 4/4] Document the new color.* settings to colorize push errors/hints 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin ` (2 preceding siblings ...) 2018-04-21 10:10 ` [PATCH v3 3/4] Add a test to verify that push errors are colorful Johannes Schindelin @ 2018-04-21 10:10 ` Johannes Schindelin 3 siblings, 0 replies; 22+ messages in thread From: Johannes Schindelin @ 2018-04-21 10:10 UTC (permalink / raw) To: git Cc: Junio C Hamano, Eric Sunshine, Jacob Keller, Ævar Arnfjörð Bjarmason Let's make it easier for users to find out how to customize these colors. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> --- Documentation/config.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 2659153cb37..2cea0c6c899 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1088,6 +1088,16 @@ clean.requireForce:: A boolean to make git-clean do nothing unless given -f, -i or -n. Defaults to true. +color.advice:: + A boolean to enable/disable color in hints (e.g. when a push + failed, see `advice.*` for a list). May be set to `always`, + `false` (or `never`) or `auto` (or `true`), in which case colors + are used only when the error output goes to a terminal. If + unset, then the value of `color.ui` is used (`auto` by default). + +color.advice.hint:: + Use customized color for hints. + color.branch:: A boolean to enable/disable color in the output of linkgit:git-branch[1]. May be set to `always`, @@ -1190,6 +1200,15 @@ color.pager:: A boolean to enable/disable colored output when the pager is in use (default is true). +color.push:: + A boolean to enable/disable color in push errors. May be set to + `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.push.error:: + Use customized color for push errors. + color.showBranch:: A boolean to enable/disable color in the output of linkgit:git-show-branch[1]. May be set to `always`, @@ -1218,6 +1237,15 @@ color.status.<slot>:: status short-format), or `unmerged` (files which have unmerged changes). +color.transport:: + A boolean to enable/disable color when pushes are rejected. May be + set to `always`, `false` (or `never`) or `auto` (or `true`), in which + case colors are used only when the error output goes to a terminal. + If unset, then the value of `color.ui` is used (`auto` by default). + +color.transport.rejected:: + Use customized color when a push was rejected. + color.ui:: This variable determines the default value for variables such as `color.diff` and `color.grep` that control the use of color -- 2.17.0.windows.1.15.gaa56ade3205 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/1] Colorize some errors on stderr 2018-02-16 12:25 [PATCH 0/1] Colorize some errors on stderr Johannes Schindelin ` (2 preceding siblings ...) 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin @ 2018-04-06 18:48 ` Ævar Arnfjörð Bjarmason 3 siblings, 0 replies; 22+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2018-04-06 18:48 UTC (permalink / raw) To: Johannes Schindelin; +Cc: git, Junio C Hamano On Fri, Feb 16 2018, Johannes Schindelin wrote: > This is an RFC because it tries to introduce a fundamental new color feature: > Coloring messages *on stderr*. I missed this the first time around, and don't have anything to add that others haven't covered. Just wanted to say I'd love to get this into git, it's a great UI improvement. ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2018-04-21 10:10 UTC | newest] Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-02-16 12:25 [PATCH 0/1] Colorize some errors on stderr Johannes Schindelin 2018-02-16 12:25 ` [PATCH 1/1] Colorize push errors Johannes Schindelin 2018-02-16 19:21 ` [PATCH 0/1] Colorize some errors on stderr Junio C Hamano 2018-04-06 11:21 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 0/4] Colorize push errors Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 1/4] color: introduce support for colorizing stderr Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 2/4] push: colorize errors Johannes Schindelin 2018-04-05 23:37 ` Jacob Keller 2018-04-06 11:15 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 3/4] Add a test to verify that push errors are colorful Johannes Schindelin 2018-04-06 10:50 ` Eric Sunshine 2018-04-06 12:13 ` Johannes Schindelin 2018-04-05 22:48 ` [PATCH v2 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin 2018-04-06 10:56 ` Eric Sunshine 2018-04-06 12:15 ` Johannes Schindelin 2018-04-07 6:55 ` Eric Sunshine 2018-04-21 10:09 ` [PATCH v3 0/4] Colorize push errors Johannes Schindelin 2018-04-21 10:09 ` [PATCH v3 1/4] color: introduce support for colorizing stderr Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 2/4] push: colorize errors Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 3/4] Add a test to verify that push errors are colorful Johannes Schindelin 2018-04-21 10:10 ` [PATCH v3 4/4] Document the new color.* settings to colorize push errors/hints Johannes Schindelin 2018-04-06 18:48 ` [PATCH 0/1] Colorize some errors on stderr Ævar Arnfjörð Bjarmason
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).