Skip to content

Commit 21638c1

Browse files
committed
Merge branch 'hn/highlight-sideband-keywords' into pu
The sideband code learned to optionally paint selected keywords at the beginning of incoming lines on the receiving end. * hn/highlight-sideband-keywords: sideband: highlight keywords in remote output
2 parents d16229f + 53d2a08 commit 21638c1

File tree

5 files changed

+163
-9
lines changed

5 files changed

+163
-9
lines changed

Documentation/config.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,15 @@ color.push::
12801280
color.push.error::
12811281
Use customized color for push errors.
12821282

1283+
color.remote::
1284+
A boolean to enable/disable colored remote output. If unset,
1285+
then the value of `color.ui` is used (`auto` by default).
1286+
1287+
color.remote.<slot>::
1288+
Use customized color for each remote keywords. `<slot>` may be
1289+
`hint`, `warning`, `success` or `error` which match the
1290+
corresponding keyword.
1291+
12831292
color.showBranch::
12841293
A boolean to enable/disable color in the output of
12851294
linkgit:git-show-branch[1]. May be set to `always`,

help.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ void list_config_help(int for_human)
425425
{ "color.diff", "<slot>", list_config_color_diff_slots },
426426
{ "color.grep", "<slot>", list_config_color_grep_slots },
427427
{ "color.interactive", "<slot>", list_config_color_interactive_slots },
428+
{ "color.remote", "<slot>", list_config_color_sideband_slots },
428429
{ "color.status", "<slot>", list_config_color_status_slots },
429430
{ "fsck", "<msg-id>", list_config_fsck_msg_ids },
430431
{ "receive.fsck", "<msg-id>", list_config_fsck_msg_ids },

help.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void list_config_color_diff_slots(struct string_list *list, const char *prefix);
8383
void list_config_color_grep_slots(struct string_list *list, const char *prefix);
8484
void list_config_color_interactive_slots(struct string_list *list, const char *prefix);
8585
void list_config_color_status_slots(struct string_list *list, const char *prefix);
86+
void list_config_color_sideband_slots(struct string_list *list, const char *prefix);
8687
void list_config_fsck_msg_ids(struct string_list *list, const char *prefix);
8788

8889
#endif /* HELP_H */

sideband.c

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,97 @@
11
#include "cache.h"
2+
#include "color.h"
3+
#include "config.h"
24
#include "pkt-line.h"
35
#include "sideband.h"
6+
#include "help.h"
7+
8+
struct kwtable {
9+
/*
10+
* We use keyword as config key so it can't contain funny chars like
11+
* spaces. When we do that, we need a separate field for slot name in
12+
* load_sideband_colors().
13+
*/
14+
const char *keyword;
15+
char color[COLOR_MAXLEN];
16+
};
17+
18+
static struct kwtable keywords[] = {
19+
{ "hint", GIT_COLOR_YELLOW },
20+
{ "warning", GIT_COLOR_BOLD_YELLOW },
21+
{ "success", GIT_COLOR_BOLD_GREEN },
22+
{ "error", GIT_COLOR_BOLD_RED },
23+
};
24+
25+
static int sideband_use_color = -1;
26+
27+
static void load_sideband_colors(void)
28+
{
29+
const char *key = "color.remote";
30+
struct strbuf sb = STRBUF_INIT;
31+
char *value;
32+
int i;
33+
34+
if (sideband_use_color >= 0)
35+
return;
36+
37+
if (!git_config_get_string(key, &value))
38+
sideband_use_color = git_config_colorbool(key, value);
39+
40+
for (i = 0; i < ARRAY_SIZE(keywords); i++) {
41+
strbuf_reset(&sb);
42+
strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword);
43+
if (git_config_get_string(sb.buf, &value))
44+
continue;
45+
if (color_parse(value, keywords[i].color))
46+
die(_("expecting a color: %s"), value);
47+
}
48+
strbuf_release(&sb);
49+
}
50+
51+
void list_config_color_sideband_slots(struct string_list *list, const char *prefix)
52+
{
53+
int i;
54+
55+
for (i = 0; i < ARRAY_SIZE(keywords); i++)
56+
list_config_item(list, prefix, keywords[i].keyword);
57+
}
58+
59+
/*
60+
* Optionally highlight some keywords in remote output if they appear at the
61+
* start of the line.
62+
*/
63+
static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
64+
{
65+
int i;
66+
67+
load_sideband_colors();
68+
if (!want_color_stderr(sideband_use_color)) {
69+
strbuf_add(dest, src, n);
70+
return;
71+
}
72+
73+
while (isspace(*src)) {
74+
strbuf_addch(dest, *src);
75+
src++;
76+
n--;
77+
}
78+
79+
for (i = 0; i < ARRAY_SIZE(keywords); i++) {
80+
struct kwtable* p = keywords + i;
81+
int len = strlen(p->keyword);
82+
if (!strncasecmp(p->keyword, src, len) && !isalnum(src[len])) {
83+
strbuf_addstr(dest, p->color);
84+
strbuf_add(dest, src, len);
85+
strbuf_addstr(dest, GIT_COLOR_RESET);
86+
n -= len;
87+
src += len;
88+
break;
89+
}
90+
}
91+
92+
strbuf_add(dest, src, n);
93+
}
94+
495

596
/*
697
* Receive multiplexed output stream over git native protocol.
@@ -48,8 +139,10 @@ int recv_sideband(const char *me, int in_stream, int out)
48139
len--;
49140
switch (band) {
50141
case 3:
51-
strbuf_addf(&outbuf, "%s%s%s", outbuf.len ? "\n" : "",
52-
DISPLAY_PREFIX, buf + 1);
142+
strbuf_addf(&outbuf, "%s%s", outbuf.len ? "\n" : "",
143+
DISPLAY_PREFIX);
144+
maybe_colorize_sideband(&outbuf, buf + 1, len);
145+
53146
retval = SIDEBAND_REMOTE_ERROR;
54147
break;
55148
case 2:
@@ -69,20 +162,22 @@ int recv_sideband(const char *me, int in_stream, int out)
69162
if (!outbuf.len)
70163
strbuf_addstr(&outbuf, DISPLAY_PREFIX);
71164
if (linelen > 0) {
72-
strbuf_addf(&outbuf, "%.*s%s%c",
73-
linelen, b, suffix, *brk);
74-
} else {
75-
strbuf_addch(&outbuf, *brk);
165+
maybe_colorize_sideband(&outbuf, b, linelen);
166+
strbuf_addstr(&outbuf, suffix);
76167
}
168+
169+
strbuf_addch(&outbuf, *brk);
77170
xwrite(2, outbuf.buf, outbuf.len);
78171
strbuf_reset(&outbuf);
79172

80173
b = brk + 1;
81174
}
82175

83-
if (*b)
84-
strbuf_addf(&outbuf, "%s%s", outbuf.len ?
85-
"" : DISPLAY_PREFIX, b);
176+
if (*b) {
177+
strbuf_addstr(&outbuf, outbuf.len ?
178+
"" : DISPLAY_PREFIX);
179+
maybe_colorize_sideband(&outbuf, b, strlen(b));
180+
}
86181
break;
87182
case 1:
88183
write_or_die(out, buf + 1, len);

t/t5409-colorize-remote-messages.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/sh
2+
3+
test_description='remote messages are colorized on the client'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
mkdir .git/hooks &&
9+
write_script .git/hooks/update <<-\EOF &&
10+
echo error: error
11+
echo hint: hint
12+
echo success: success
13+
echo warning: warning
14+
echo prefixerror: error
15+
exit 0
16+
EOF
17+
18+
echo 1 >file &&
19+
git add file &&
20+
git commit -m 1 &&
21+
git clone . child &&
22+
cd child &&
23+
echo 2 >file &&
24+
git commit -a -m 2
25+
'
26+
27+
test_expect_success 'push' '
28+
git -c color.remote=always \
29+
push -f origin HEAD:refs/heads/newbranch 2>output &&
30+
test_decode_color <output >decoded &&
31+
grep "<BOLD;RED>error<RESET>:" decoded &&
32+
grep "<YELLOW>hint<RESET>:" decoded &&
33+
grep "<BOLD;GREEN>success<RESET>:" decoded &&
34+
grep "<BOLD;YELLOW>warning<RESET>:" decoded &&
35+
grep "prefixerror: error" decoded
36+
'
37+
38+
test_expect_success 'push with customized color' '
39+
git -c color.remote=always -c color.remote.error=white \
40+
push -f origin HEAD:refs/heads/newbranch2 2>output &&
41+
test_decode_color <output >decoded &&
42+
grep "<WHITE>error<RESET>:" decoded &&
43+
grep "<YELLOW>hint<RESET>:" decoded &&
44+
grep "<BOLD;GREEN>success<RESET>:" decoded &&
45+
grep "<BOLD;YELLOW>warning<RESET>:" decoded
46+
'
47+
48+
test_done

0 commit comments

Comments
 (0)