Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
Han-Wen Nienhuys writes: >> If your "make test" did not catch this as an error, then we may need >> to fix t/Makefile, as it is supposed to run test-lint. > > I've been running tests individually as > > sh t5409-colorize-remote-messages.sh -v -d During your own development that may be sufficient, but do run "make test" to run tests by other people; it will help you catch new bugs you are introducing whey they notice their expectations are broken. You are breaking 5541 (there may be others, but I noticed a breakage there) perhaps with your debugging cruft.
Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
On Fri, Aug 3, 2018 at 5:52 AM Jonathan Nieder wrote: > > Hi, > > Han-Wen Nienhuys wrote: > > > The colorization is controlled with the config setting "color.remote". > > > > Supported keywords are "error", "warning", "hint" and "success". They > > are highlighted if they appear at the start of the line, which is > > common in error messages, eg. > > > >ERROR: commit is missing Change-Id > > A few questions: > > - should this be documented somewhere in Documentation/technical/*protocol*? > That way, server implementors can know to take advantage of it. The protocol docs seem to work on a much different level. Maybe there should be a "best practices" document or similar? > - how does this interact with (future) internationalization of server > messages? If my server knows that the client speaks French, should > they send "ERROR:" anyway and rely on the client to translate it? > Or are we deferring that question to a later day? It doesn't, and we are deferring that question. > [...] > > The Git push process itself prints lots of non-actionable messages > > (eg. bandwidth statistics, object counters for different phases of the > > process), and my hypothesis is that these obscure the actionable error > > messages that our server sends back. Highlighting keywords in the > > draws more attention to actionable messages. > > I'd be interested in ways to minimize Git's contribution to this as > well. E.g. can we make more use of \r to make client-produced progress > messages take less screen real estate? Should some of the servers > involved (e.g., Gerrit) do so as well? Yes, I'm interested in this too, but I fear it would veer into a territory that is prone to bikeshedding. Gerrit should definitely also send less noise. > > Finally, this solution is backwards compatible: many servers already > > prefix their messages with "error", and they will benefit from this > > change without requiring a server update. > > Yes, this seems like a compelling reason to follow this approach. > > [...] > > --- a/Documentation/config.txt > > +++ b/Documentation/config.txt > > @@ -1229,6 +1229,15 @@ color.push:: > > color.push.error:: > > Use customized color for push errors. > > > > +color.remote:: > > + A boolean to enable/disable colored remote output. If unset, > > + then the value of `color.ui` is used (`auto` by default). > > + > > +color.remote.:: > > + Use customized color for each remote keywords. `` may be > > + `hint`, `warning`, `success` or `error` which match the > > + corresponding keyword. > > What positions in a remote message are matched? If a server prints a > message about something being discouraged because it is error-prone, > would the "error" in error-prone turn red? yes, if it happened to occur after a line-break. We could decide that we will only highlight ':' rest of line or '\n' that would work for the Gerrit case, and would be useful forcing function to uniformize remote error messages. > > +struct kwtable { > > nit: perhaps kwtable_entry? done. > > +/* > > + * Optionally highlight some keywords in remote output if they appear at > > the > > + * start of the line. This should be called for a single line only. > > + */ > > +void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) > > Can this be static? Done. > What does 'n' represent? Can the comment say? (Or if it's the length > of src, can it be renamed to srclen?) Added comment. > Super-pedantic nit: even if there are multiple special words at the > start, this will only highlight one. :) So it could say something > like "Optionally check if the first word on the line is a keyword and > highlight it if so." Super pedantic answer: if people care about it that much, they can read the 20 lines of code below :-) > > +{ > > + int i; > > + if (!want_color_stderr(use_sideband_colors())) { > > nit: whitespace damage (you can check for this with "git show --check"). > There's a bit more elsewhere. ran tabify on whole file. > > + for (i = 0; i < ARRAY_SIZE(keywords); i++) { > > + struct kwtable* p = keywords + i; > > nit: * should attach to the variable, C-style. Done. > You can use "make style" to do some automatic formatting (though this > is a bit experimental, so do double-check the results). sad panda: hanwen@han-wen:~/vc/git$ make style git clang-format --style file --diff --extensions c,h Traceback (most recent call last): File "/usr/bin/git-clang-format", line 580, in main() File "/usr/bin/git-clang-format", line 62, in main config = load_git_config() File "/usr/bin/git-clang-format", line 195, in load_git_config name, value = entry.split('\n', 1) ValueError: need more than 1 value to unpack Makefile:2663: recipe for target 'style' failed make: *** [style] Error 1 > [...] > > @@ -48,8 +145,10 @@ int recv_sideband(const char *me, int in_stream, int > > out) > > len--; > > switch (band)
Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
On Thu, Aug 2, 2018 at 8:22 PM Junio C Hamano wrote: > > > > Helped-by: Duy Nguyen > > Signed-off-by: Han-Wen Nienhuys > > --- > > Documentation/config.txt| 9 +++ > > help.c | 1 + > > help.h | 1 + > > sideband.c | 119 +--- > > t/t5409-colorize-remote-messages.sh | 47 +++ > > 5 files changed, 168 insertions(+), 9 deletions(-) > > create mode 100644 t/t5409-colorize-remote-messages.sh > > I'll "chmod +x" while queuing. > Done. > If your "make test" did not catch this as an error, then we may need > to fix t/Makefile, as it is supposed to run test-lint. I've been running tests individually as sh t5409-colorize-remote-messages.sh -v -d > > +color.remote:: > > + A boolean to enable/disable colored remote output. If unset, > > + then the value of `color.ui` is used (`auto` by default). > > Nobody tells the end-users what "colored remote output" does; > arguably they can find it out themselves by enabling the feature and > observing remote messages, but that is not user friendly. expanded doc. > > +color.remote.:: > > + Use customized color for each remote keywords. `` may be > > Isn't 'each' a singular, i.e. "for each remote keyword"? If so I do > not mind dropping 's' myself while queuing. Done. > > > + `hint`, `warning`, `success` or `error` which match the > > + corresponding keyword. > > We need to say that keywords are painted case insensitively > somewhere in the doc. Either do that here, or in the updated > description of `color.remote`---I am not sure which one results in > more readable text offhand. Done. > > +void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) > > +{ > > + int i; > > In a block with a dozen more more lines, it is easier to have a > blank line between decls and the first statement, i.e. here. Done. > > + if (!want_color_stderr(use_sideband_colors())) { > > The above line is indented with SP followed by HT; don't. Fixed. It would be great if there were a pre-commit hook that I could install to prevent this from ever getting committed. > > + struct kwtable* p = keywords + i; > > struct kwtable *p = keywords + i; Done. > > + int len = strlen(p->keyword); > > +/* > > + * Match case insensitively, so we colorize output from > > existing > > + * servers regardless of the case that they use for their > > + * messages. We only highlight the word precisely, so > > + * "successful" stays uncolored. > > + */ > > Indent with tabs, not a run of spaces, i.e. Done. > Use write_script, i.e. instead of all the above, say Done. > Our tests are not written to demonstrate that our code works as > written. It is to protect our code from getting broken by others > who may not share vision of the original author. Make sure that you > cast what you care about in stone, e.g. include "echo ERROR: bad" or > something in the above to ensure that future updates to the code > will not turn the match into a case sensitive one without breaking > the test suite. Add some more cases. > > + echo 1 >file && > > + git add file && > > + git commit -m 1 && > > + git clone . child && > > + cd child && > > + echo 2 > file && > > + git commit -a -m 2 > > Don't chdir the whole testing environment like this. Depending on > the success and failure in the middle of the above &&-chain, the > next test will start at an unexpected place, which is bad. > > Instead, do something like > > git clone . child && > echo 2 >child/file && > git -C child commit -a -m 2 > > or > Done. > > +test_expect_success 'push' ' > > + git -c color.remote=always push -f origin HEAD:refs/heads/newbranch > > 2>output && > > + test_decode_color decoded && > > + grep "error:" decoded && > > + grep "hint:" decoded && > > + grep "success:" decoded && > > + grep "warning:" decoded && > > + grep "prefixerror: error" decoded > > A comment before this test (which covers both of these two) that > explains why many "grep" invocations are necessary, instead of a > comparison with a single multi-line expected result file. I am > guessing that it is *not* because you cannot rely on the order of > these lines coming out from the update hook, but because the remote > output have lines other than what is given by the update hook and > we cannot afford to write them in the expected result file. Comparing exact outputs is IMO an antipattern in general. It makes the test more fragile than they need to be. (what if we change the "remote: " prefix to something else for example?). If using a golden output, the second test would either require a repetitive, too long golden file, or it would use loose greps anyway. Added a comment. -- Google
Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
Hi, Han-Wen Nienhuys wrote: > The colorization is controlled with the config setting "color.remote". > > Supported keywords are "error", "warning", "hint" and "success". They > are highlighted if they appear at the start of the line, which is > common in error messages, eg. > >ERROR: commit is missing Change-Id A few questions: - should this be documented somewhere in Documentation/technical/*protocol*? That way, server implementors can know to take advantage of it. - how does this interact with (future) internationalization of server messages? If my server knows that the client speaks French, should they send "ERROR:" anyway and rely on the client to translate it? Or are we deferring that question to a later day? [...] > The Git push process itself prints lots of non-actionable messages > (eg. bandwidth statistics, object counters for different phases of the > process), and my hypothesis is that these obscure the actionable error > messages that our server sends back. Highlighting keywords in the > draws more attention to actionable messages. I'd be interested in ways to minimize Git's contribution to this as well. E.g. can we make more use of \r to make client-produced progress messages take less screen real estate? Should some of the servers involved (e.g., Gerrit) do so as well? > The highlighting is done on the client rather than server side, so > servers don't have to grow capabilities to understand terminal escape > codes and terminal state. It also consistent with the current state > where Git is control of the local display (eg. prefixing messages with > "remote: "). As a strawman idea, what would you think of a way to allow the server to do some coloration by using color tags like Erreur: ... ? As an advantage, this would give the server more control. As a disadvantage, it is not so useful as "semantic markup", meaning it is harder to figure out how to present to accessibility tools in a meaningful way. Plus, there's the issue of usefulness with existing servers you mentioned: > Finally, this solution is backwards compatible: many servers already > prefix their messages with "error", and they will benefit from this > change without requiring a server update. Yes, this seems like a compelling reason to follow this approach. [...] > --- a/Documentation/config.txt > +++ b/Documentation/config.txt > @@ -1229,6 +1229,15 @@ color.push:: > color.push.error:: > Use customized color for push errors. > > +color.remote:: > + A boolean to enable/disable colored remote output. If unset, > + then the value of `color.ui` is used (`auto` by default). > + > +color.remote.:: > + Use customized color for each remote keywords. `` may be > + `hint`, `warning`, `success` or `error` which match the > + corresponding keyword. What positions in a remote message are matched? If a server prints a message about something being discouraged because it is error-prone, would the "error" in error-prone turn red? [...] > --- a/sideband.c > +++ b/sideband.c > @@ -1,6 +1,103 @@ > #include "cache.h" > +#include "color.h" > +#include "config.h" > #include "pkt-line.h" > #include "sideband.h" > +#include "help.h" > + > +struct kwtable { nit: perhaps kwtable_entry? > + /* > + * We use keyword as config key so it can't contain funny chars like > + * spaces. When we do that, we need a separate field for slot name in > + * load_sideband_colors(). > + */ > + const char *keyword; > + char color[COLOR_MAXLEN]; > +}; > + > +static struct kwtable keywords[] = { > + { "hint", GIT_COLOR_YELLOW }, [...] > +// Returns a color setting (GIT_COLOR_NEVER, etc). nit: Git uses C89-style /* */ comments. > +static int use_sideband_colors(void) Makes sense. [...] > +void list_config_color_sideband_slots(struct string_list *list, const char > *prefix) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(keywords); i++) > + list_config_item(list, prefix, keywords[i].keyword); > +} Not about this patch: I wonder if we can eliminate this boilerplate some time in the future. [...] > +/* > + * Optionally highlight some keywords in remote output if they appear at the > + * start of the line. This should be called for a single line only. > + */ > +void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) Can this be static? What does 'n' represent? Can the comment say? (Or if it's the length of src, can it be renamed to srclen?) Super-pedantic nit: even if there are multiple special words at the start, this will only highlight one. :) So it could say something like "Optionally check if the first word on the line is a keyword and highlight it if so." > +{ > + int i; > + if (!want_color_stderr(use_sideband_colors())) { nit: whitespace damage (you can check for this with "git show --check"). There's a bit more elsewhere. > + strbuf_add(dest, src, n); > + return; > + } > +
Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
On Thu, Aug 2, 2018 at 8:13 AM Han-Wen Nienhuys wrote: > [PATCH 2/2] sideband: highlight keywords in remote sideband output The -v option of git-format-patch makes it easy to let reviewers know that this is a new version of a previously-submitted patch series. This (I think) is the second attempt; if you need to send again, you could use "git format-patch -v3 ...", which would result in "[PATCH v3 2/2] ...". > The colorization is controlled with the config setting "color.remote". > > Supported keywords are "error", "warning", "hint" and "success". They > are highlighted if they appear at the start of the line, which is > common in error messages, eg. > >ERROR: commit is missing Change-Id > > The rationale for this change is that Gerrit does server-side > processing to create or update code reviews, and actionable error > messages (eg. missing Change-Id) must be communicated back to the user > during the push. User research has shown that new users have trouble > seeing these messages. > [...snip...] Thanks, this commit message is much more helpful than the previous one. If you end up re-rolling, you might consider swapping the order of these paragraphs around a bit to first explain the problem the patch is solving (i.e. the justification), then the solution and relevant details. Documentation/SubmittingPatches has good advice about this. Using Gerrit as the sole rationale is underselling this otherwise general improvement. Instead, the commit message could sell the change on its own merits and can then use Gerrit as an example. > The Git push process itself prints lots of non-actionable messages > (eg. bandwidth statistics, object counters for different phases of the > process), and my hypothesis is that these obscure the actionable error > messages that our server sends back. Highlighting keywords in the > draws more attention to actionable messages. So, for instance, you might want to use a rewrite of this paragraph to open the commit message. Something like this, perhaps: A remote Git operation can print many non-actionable messages (e.g. bandwidth statistics, object counters for different phases of the process, etc.) and such noise can obscure genuine actionable messages, such as warnings and outright errors. As an example, Gerrit does server-side processing to create or update code reviews, and actionable error messages (such as "ERROR: commit is missing Change-Id") must be communicated back to the user during a push operation, but new users often have trouble spotting these error messages amid the noise. Address this problem by upgrading 'sideband' to draw attention to these messages by highlighting them with color. [...and so forth...] > Signed-off-by: Han-Wen Nienhuys > --- > diff --git a/sideband.c b/sideband.c > @@ -1,6 +1,103 @@ > +struct kwtable { > + /* > +* We use keyword as config key so it can't contain funny chars like > +* spaces. When we do that, we need a separate field for slot name in > +* load_sideband_colors(). > +*/ This comment is outdated; load_sideband_colors() does not exist in this patch. I get what the first sentence of this comment is saying, but I'm having trouble understanding what the second sentence is all about. > + const char *keyword; > + char color[COLOR_MAXLEN]; > +}; > + > +static struct kwtable keywords[] = { > + { "hint", GIT_COLOR_YELLOW }, > + { "warning",GIT_COLOR_BOLD_YELLOW }, > + { "success",GIT_COLOR_BOLD_GREEN }, > + { "error", GIT_COLOR_BOLD_RED }, > +}; > + > +// Returns a color setting (GIT_COLOR_NEVER, etc). Use /* old-style C comments */ in this codebase, not // C++ or new-style C. > +static int use_sideband_colors(void) > +{ > + static int use_sideband_colors_cached = -1; > + const char *key = "color.remote"; > + > + if (use_sideband_colors_cached >= 0) > + return use_sideband_colors_cached; > + > + if (!git_config_get_string(key, )) > + use_sideband_colors_cached = git_config_colorbool(key, value); So, if "color.remote" exists, then 'use_sideband_colors_cached' is assigned. However, if "color.remote" does not exist, then it's never assigned. Is this intended behavior? It seems like you'd want to fall back to some other value rather than leaving it unassigned. Which leads to the next question: The documentation says that this falls back to "color.ui" if "color.remote" does not exist, however, where is this fallback happening? Am I overlooking something obvious? > + for (i = 0; i < ARRAY_SIZE(
Re: [PATCH 2/2] sideband: highlight keywords in remote sideband output
Han-Wen Nienhuys writes: > The colorization is controlled with the config setting "color.remote". > ... > Finally, this solution is backwards compatible: many servers already > prefix their messages with "error", and they will benefit from this > change without requiring a server update. By contrast, a server-side > solution would likely require plumbing the TERM variable through the > git protocol, so it would require changes to both server and client. Thanks; quite readable. > > Helped-by: Duy Nguyen > Signed-off-by: Han-Wen Nienhuys > --- > Documentation/config.txt| 9 +++ > help.c | 1 + > help.h | 1 + > sideband.c | 119 +--- > t/t5409-colorize-remote-messages.sh | 47 +++ > 5 files changed, 168 insertions(+), 9 deletions(-) > create mode 100644 t/t5409-colorize-remote-messages.sh I'll "chmod +x" while queuing. Side note: When all problems pointed out are "I'll fix it this way while queuing"-kind, and if you agree to the way I plan to fix them up, then just saying so is sufficient and you do not have to send a new version of the patch(es). If your "make test" did not catch this as an error, then we may need to fix t/Makefile, as it is supposed to run test-lint. > diff --git a/Documentation/config.txt b/Documentation/config.txt > index 43b2de7b5..0783323be 100644 > --- a/Documentation/config.txt > +++ b/Documentation/config.txt > @@ -1229,6 +1229,15 @@ color.push:: > color.push.error:: > Use customized color for push errors. > > +color.remote:: > + A boolean to enable/disable colored remote output. If unset, > + then the value of `color.ui` is used (`auto` by default). Nobody tells the end-users what "colored remote output" does; arguably they can find it out themselves by enabling the feature and observing remote messages, but that is not user friendly. When running commands like `git fetch` and `git push` that interact with a remote repository, certain keywords (see `color.remote.`) that appear at the beginning of a line of message from the remote end can be painted in color. This configuration variable is a boolean to enable/disable the feature. If unset... or something like that, perhaps? You use `always` in your tests to a good effect, but what the value means is not described here. > +color.remote.:: > + Use customized color for each remote keywords. `` may be Isn't 'each' a singular, i.e. "for each remote keyword"? If so I do not mind dropping 's' myself while queuing. > + `hint`, `warning`, `success` or `error` which match the > + corresponding keyword. We need to say that keywords are painted case insensitively somewhere in the doc. Either do that here, or in the updated description of `color.remote`---I am not sure which one results in more readable text offhand. > diff --git a/sideband.c b/sideband.c > index 325bf0e97..5c72db83c 100644 > --- a/sideband.c > +++ b/sideband.c > @@ -1,6 +1,103 @@ > #include "cache.h" > +#include "color.h" > +#include "config.h" > #include "pkt-line.h" > #include "sideband.h" > +#include "help.h" > + > +struct kwtable { > + /* > + * We use keyword as config key so it can't contain funny chars like > + * spaces. When we do that, we need a separate field for slot name in > + * load_sideband_colors(). > + */ > + const char *keyword; > + char color[COLOR_MAXLEN]; > +}; > + > +static struct kwtable keywords[] = { > + { "hint", GIT_COLOR_YELLOW }, > + { "warning",GIT_COLOR_BOLD_YELLOW }, > + { "success",GIT_COLOR_BOLD_GREEN }, > + { "error", GIT_COLOR_BOLD_RED }, > +}; > + > +// Returns a color setting (GIT_COLOR_NEVER, etc). > +static int use_sideband_colors(void) > +{ > + static int use_sideband_colors_cached = -1; > + > + const char *key = "color.remote"; > + struct strbuf sb = STRBUF_INIT; > + char *value; > + int i; > + > + if (use_sideband_colors_cached >= 0) > + return use_sideband_colors_cached; > + > + if (!git_config_get_string(key, )) > + use_sideband_colors_cached = git_config_colorbool(key, value); > + > + for (i = 0; i < ARRAY_SIZE(keywords); i++) { > + strbuf_reset(); > + strbuf_addf(, "%s.%s", key, keywords[i].keyword); > + if (git_config_get_string(sb.buf, )) > + continue; > + if (color_parse(value, keywords[i].color)) > + die(_("expecting a color: %s"), value); > + } > + strbuf_release(); > + return use_sideband_colors_cached; > +} > + > +void list_config_color_sideband_slots(struct string_list *list, const char > *prefix) > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(keywords); i++) > + list_config_item(list, prefix,
[PATCH 2/2] sideband: highlight keywords in remote sideband output
The colorization is controlled with the config setting "color.remote". Supported keywords are "error", "warning", "hint" and "success". They are highlighted if they appear at the start of the line, which is common in error messages, eg. ERROR: commit is missing Change-Id The rationale for this change is that Gerrit does server-side processing to create or update code reviews, and actionable error messages (eg. missing Change-Id) must be communicated back to the user during the push. User research has shown that new users have trouble seeing these messages. The Git push process itself prints lots of non-actionable messages (eg. bandwidth statistics, object counters for different phases of the process), and my hypothesis is that these obscure the actionable error messages that our server sends back. Highlighting keywords in the draws more attention to actionable messages. The highlighting is done on the client rather than server side, so servers don't have to grow capabilities to understand terminal escape codes and terminal state. It also consistent with the current state where Git is control of the local display (eg. prefixing messages with "remote: "). Finally, this solution is backwards compatible: many servers already prefix their messages with "error", and they will benefit from this change without requiring a server update. By contrast, a server-side solution would likely require plumbing the TERM variable through the git protocol, so it would require changes to both server and client. Helped-by: Duy Nguyen Signed-off-by: Han-Wen Nienhuys --- Documentation/config.txt| 9 +++ help.c | 1 + help.h | 1 + sideband.c | 119 +--- t/t5409-colorize-remote-messages.sh | 47 +++ 5 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 t/t5409-colorize-remote-messages.sh diff --git a/Documentation/config.txt b/Documentation/config.txt index 43b2de7b5..0783323be 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1229,6 +1229,15 @@ color.push:: color.push.error:: Use customized color for push errors. +color.remote:: + A boolean to enable/disable colored remote output. If unset, + then the value of `color.ui` is used (`auto` by default). + +color.remote.:: + Use customized color for each remote keywords. `` may be + `hint`, `warning`, `success` or `error` which match the + corresponding keyword. + color.showBranch:: A boolean to enable/disable color in the output of linkgit:git-show-branch[1]. May be set to `always`, diff --git a/help.c b/help.c index 3ebf0568d..b6cafcfc0 100644 --- a/help.c +++ b/help.c @@ -425,6 +425,7 @@ void list_config_help(int for_human) { "color.diff", "", list_config_color_diff_slots }, { "color.grep", "", list_config_color_grep_slots }, { "color.interactive", "", list_config_color_interactive_slots }, + { "color.remote", "", list_config_color_sideband_slots }, { "color.status", "", list_config_color_status_slots }, { "fsck", "", list_config_fsck_msg_ids }, { "receive.fsck", "", list_config_fsck_msg_ids }, diff --git a/help.h b/help.h index f8b15323a..9eab6a3f8 100644 --- a/help.h +++ b/help.h @@ -83,6 +83,7 @@ void list_config_color_diff_slots(struct string_list *list, const char *prefix); void list_config_color_grep_slots(struct string_list *list, const char *prefix); void list_config_color_interactive_slots(struct string_list *list, const char *prefix); void list_config_color_status_slots(struct string_list *list, const char *prefix); +void list_config_color_sideband_slots(struct string_list *list, const char *prefix); void list_config_fsck_msg_ids(struct string_list *list, const char *prefix); #endif /* HELP_H */ diff --git a/sideband.c b/sideband.c index 325bf0e97..5c72db83c 100644 --- a/sideband.c +++ b/sideband.c @@ -1,6 +1,103 @@ #include "cache.h" +#include "color.h" +#include "config.h" #include "pkt-line.h" #include "sideband.h" +#include "help.h" + +struct kwtable { + /* +* We use keyword as config key so it can't contain funny chars like +* spaces. When we do that, we need a separate field for slot name in +* load_sideband_colors(). +*/ + const char *keyword; + char color[COLOR_MAXLEN]; +}; + +static struct kwtable keywords[] = { + { "hint", GIT_COLOR_YELLOW }, + { "warning",GIT_COLOR_BOLD_YELLOW }, + { "success",GIT_COLOR_BOLD_GREEN }, + { "error", GIT_COLOR_BOLD_RED }, +}; + +// Returns a color setting (GIT_COLOR_NEVER, etc). +static int use_sideband_colors(void) +{ + static int use_sideband_colors_cached = -1; + + const char *key = "color.remote"; + struct strbuf sb = STRBUF_INIT; + char *value; +
[PATCH 2/2] sideband: highlight keywords in remote sideband output
The colorization is controlled with the config setting "color.remote". Supported keywords are "error", "warning", "hint" and "success". They are highlighted if they appear at the start of the line, which is common in error messages, eg. ERROR: commit is missing Change-Id The rationale for this change is that Gerrit does server-side processing to create or update code reviews, and actionable error messages (eg. missing Change-Id) must be communicated back to the user during the push. User research has shown that new users have trouble seeing these messages. The Git push process itself prints lots of non-actionable messages (eg. bandwidth statistics, object counters for different phases of the process), and my hypothesis is that these obscure the actionable error messages that our server sends back. Highlighting keywords in the draws more attention to actionable messages. The highlighting is done on the client rather than server side, so servers don't have to grow capabilities to understand terminal escape codes and terminal state. It also consistent with the current state where Git is control of the local display (eg. prefixing messages with "remote: "). Finally, this solution is backwards compatible: many servers already prefix their messages with "error", and they will benefit from this change without requiring a server update. By contrast, a server-side solution would likely require plumbing the TERM variable through the git protocol, so it would require changes to both server and client. Helped-by: Duy Nguyen Signed-off-by: Han-Wen Nienhuys --- Documentation/config.txt| 9 +++ help.c | 1 + help.h | 1 + sideband.c | 119 +--- t/t5409-colorize-remote-messages.sh | 47 +++ 5 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 t/t5409-colorize-remote-messages.sh diff --git a/Documentation/config.txt b/Documentation/config.txt index 43b2de7b5..0783323be 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1229,6 +1229,15 @@ color.push:: color.push.error:: Use customized color for push errors. +color.remote:: + A boolean to enable/disable colored remote output. If unset, + then the value of `color.ui` is used (`auto` by default). + +color.remote.:: + Use customized color for each remote keywords. `` may be + `hint`, `warning`, `success` or `error` which match the + corresponding keyword. + color.showBranch:: A boolean to enable/disable color in the output of linkgit:git-show-branch[1]. May be set to `always`, diff --git a/help.c b/help.c index 3ebf0568d..b6cafcfc0 100644 --- a/help.c +++ b/help.c @@ -425,6 +425,7 @@ void list_config_help(int for_human) { "color.diff", "", list_config_color_diff_slots }, { "color.grep", "", list_config_color_grep_slots }, { "color.interactive", "", list_config_color_interactive_slots }, + { "color.remote", "", list_config_color_sideband_slots }, { "color.status", "", list_config_color_status_slots }, { "fsck", "", list_config_fsck_msg_ids }, { "receive.fsck", "", list_config_fsck_msg_ids }, diff --git a/help.h b/help.h index f8b15323a..9eab6a3f8 100644 --- a/help.h +++ b/help.h @@ -83,6 +83,7 @@ void list_config_color_diff_slots(struct string_list *list, const char *prefix); void list_config_color_grep_slots(struct string_list *list, const char *prefix); void list_config_color_interactive_slots(struct string_list *list, const char *prefix); void list_config_color_status_slots(struct string_list *list, const char *prefix); +void list_config_color_sideband_slots(struct string_list *list, const char *prefix); void list_config_fsck_msg_ids(struct string_list *list, const char *prefix); #endif /* HELP_H */ diff --git a/sideband.c b/sideband.c index 325bf0e97..5c72db83c 100644 --- a/sideband.c +++ b/sideband.c @@ -1,6 +1,103 @@ #include "cache.h" +#include "color.h" +#include "config.h" #include "pkt-line.h" #include "sideband.h" +#include "help.h" + +struct kwtable { + /* +* We use keyword as config key so it can't contain funny chars like +* spaces. When we do that, we need a separate field for slot name in +* load_sideband_colors(). +*/ + const char *keyword; + char color[COLOR_MAXLEN]; +}; + +static struct kwtable keywords[] = { + { "hint", GIT_COLOR_YELLOW }, + { "warning",GIT_COLOR_BOLD_YELLOW }, + { "success",GIT_COLOR_BOLD_GREEN }, + { "error", GIT_COLOR_BOLD_RED }, +}; + +// Returns a color setting (GIT_COLOR_NEVER, etc). +static int use_sideband_colors(void) +{ + static int use_sideband_colors_cached = -1; + + const char *key = "color.remote"; + struct strbuf sb = STRBUF_INIT; + char *value; +