Skip to content

Commit 11b087a

Browse files
peffgitster
authored andcommitted
ref-filter: consult want_color() before emitting colors
When color placeholders like %(color:red) are used in a ref-filter format, we unconditionally output the colors, even if the user has asked us for no colors. This usually isn't a problem when the user is constructing a --format on the command line, but it means we may do the wrong thing when the format is fed from a script or alias. For example: $ git config alias.b 'branch --format=%(color:green)%(refname)' $ git b --no-color should probably omit the green color. Likewise, running: $ git b >branches should probably also omit the color, just as we would for all baked-in coloring (and as we recently started to do for user-specified colors in --pretty formats). This commit makes both of those cases work by teaching the ref-filter code to consult want_color() before outputting any color. The color flag in ref_format defaults to "-1", which means we'll consult color.ui, which in turn defaults to the usual isatty() check on stdout. However, callers like git-branch which support their own color config (and command-line options) can override that. The new tests independently cover all three of the callers of ref-filter (for-each-ref, tag, and branch). Even though these seem redundant, it confirms that we've correctly plumbed through all of the necessary config to make colors work by default. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 18fb7ff commit 11b087a

File tree

6 files changed

+93
-12
lines changed

6 files changed

+93
-12
lines changed

builtin/branch.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
409409

410410
if (!format->format)
411411
format->format = to_free = build_format(filter, maxwidth, remote_prefix);
412+
format->use_color = branch_use_color;
412413

413414
if (verify_ref_format(format))
414415
die(_("unable to parse format string"));

ref-filter.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ static void color_atom_parser(const struct ref_format *format, struct used_atom
104104
die(_("expected format: %%(color:<color>)"));
105105
if (color_parse(color_value, atom->u.color) < 0)
106106
die(_("unrecognized color: %%(color:%s)"), color_value);
107+
/*
108+
* We check this after we've parsed the color, which lets us complain
109+
* about syntactically bogus color names even if they won't be used.
110+
*/
111+
if (!want_color(format->use_color))
112+
color_parse("", atom->u.color);
107113
}
108114

109115
static void refname_atom_parser_internal(struct refname_atom *atom,
@@ -675,6 +681,8 @@ int verify_ref_format(struct ref_format *format)
675681
if (skip_prefix(used_atom[at].name, "color:", &color))
676682
format->need_color_reset_at_eol = !!strcmp(color, "reset");
677683
}
684+
if (format->need_color_reset_at_eol && !want_color(format->use_color))
685+
format->need_color_reset_at_eol = 0;
678686
return 0;
679687
}
680688

ref-filter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,13 @@ struct ref_format {
7979
*/
8080
const char *format;
8181
int quote_style;
82+
int use_color;
8283

8384
/* Internal state to ref-filter */
8485
int need_color_reset_at_eol;
8586
};
8687

87-
#define REF_FORMAT_INIT { NULL, 0 }
88+
#define REF_FORMAT_INIT { NULL, 0, -1 }
8889

8990
/* Macros for checking --merged and --no-merged options */
9091
#define _OPT_MERGED_NO_MERGED(option, filter, h) \

t/t3203-branch-output.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
test_description='git branch display tests'
44
. ./test-lib.sh
5+
. "$TEST_DIRECTORY"/lib-terminal.sh
56

67
test_expect_success 'make commits' '
78
echo content >file &&
@@ -239,4 +240,34 @@ test_expect_success 'git branch --format option' '
239240
test_i18ncmp expect actual
240241
'
241242

243+
test_expect_success "set up color tests" '
244+
echo "<RED>master<RESET>" >expect.color &&
245+
echo "master" >expect.bare &&
246+
color_args="--format=%(color:red)%(refname:short) --list master"
247+
'
248+
249+
test_expect_success '%(color) omitted without tty' '
250+
TERM=vt100 git branch $color_args >actual.raw &&
251+
test_decode_color <actual.raw >actual &&
252+
test_cmp expect.bare actual
253+
'
254+
255+
test_expect_success TTY '%(color) present with tty' '
256+
test_terminal env TERM=vt100 git branch $color_args >actual.raw &&
257+
test_decode_color <actual.raw >actual &&
258+
test_cmp expect.color actual
259+
'
260+
261+
test_expect_success 'color.branch=always overrides auto-color' '
262+
git -c color.branch=always branch $color_args >actual.raw &&
263+
test_decode_color <actual.raw >actual &&
264+
test_cmp expect.color actual
265+
'
266+
267+
test_expect_success '--color overrides auto-color' '
268+
git branch --color $color_args >actual.raw &&
269+
test_decode_color <actual.raw >actual &&
270+
test_cmp expect.color actual
271+
'
272+
242273
test_done

t/t6300-for-each-ref.sh

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ test_description='for-each-ref test'
77

88
. ./test-lib.sh
99
. "$TEST_DIRECTORY"/lib-gpg.sh
10+
. "$TEST_DIRECTORY"/lib-terminal.sh
1011

1112
# Mon Jul 3 23:18:43 2006 +0000
1213
datestamp=1151968723
@@ -412,19 +413,33 @@ test_expect_success 'Check for invalid refname format' '
412413
test_must_fail git for-each-ref --format="%(refname:INVALID)"
413414
'
414415

415-
cat >expected <<EOF
416-
$(git rev-parse --short refs/heads/master) <GREEN>master<RESET>
417-
$(git rev-parse --short refs/remotes/origin/master) <GREEN>origin/master<RESET>
418-
$(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET>
419-
$(git rev-parse --short refs/tags/two) <GREEN>two<RESET>
420-
EOF
416+
test_expect_success 'set up color tests' '
417+
cat >expected.color <<-EOF &&
418+
$(git rev-parse --short refs/heads/master) <GREEN>master<RESET>
419+
$(git rev-parse --short refs/remotes/origin/master) <GREEN>origin/master<RESET>
420+
$(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET>
421+
$(git rev-parse --short refs/tags/two) <GREEN>two<RESET>
422+
EOF
423+
sed "s/<[^>]*>//g" <expected.color >expected.bare &&
424+
color_format="%(objectname:short) %(color:green)%(refname:short)"
425+
'
421426

422-
test_expect_success 'Check %(color:...) ' '
423-
git for-each-ref \
424-
--format="%(objectname:short) %(color:green)%(refname:short)" \
425-
>actual.raw &&
427+
test_expect_success TTY '%(color) shows color with a tty' '
428+
test_terminal env TERM=vt100 \
429+
git for-each-ref --format="$color_format" >actual.raw &&
426430
test_decode_color <actual.raw >actual &&
427-
test_cmp expected actual
431+
test_cmp expected.color actual
432+
'
433+
434+
test_expect_success '%(color) does not show color without tty' '
435+
TERM=vt100 git for-each-ref --format="$color_format" >actual &&
436+
test_cmp expected.bare actual
437+
'
438+
439+
test_expect_success 'color.ui=always can override tty check' '
440+
git -c color.ui=always for-each-ref --format="$color_format" >actual.raw &&
441+
test_decode_color <actual.raw >actual &&
442+
test_cmp expected.color actual
428443
'
429444

430445
cat >expected <<\EOF

t/t7004-tag.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Tests for operations with tags.'
99

1010
. ./test-lib.sh
1111
. "$TEST_DIRECTORY"/lib-gpg.sh
12+
. "$TEST_DIRECTORY"/lib-terminal.sh
1213

1314
# creating and listing lightweight tags:
1415

@@ -1900,6 +1901,30 @@ test_expect_success '--format should list tags as per format given' '
19001901
test_cmp expect actual
19011902
'
19021903

1904+
test_expect_success "set up color tests" '
1905+
echo "<RED>v1.0<RESET>" >expect.color &&
1906+
echo "v1.0" >expect.bare &&
1907+
color_args="--format=%(color:red)%(refname:short) --list v1.0"
1908+
'
1909+
1910+
test_expect_success '%(color) omitted without tty' '
1911+
TERM=vt100 git tag $color_args >actual.raw &&
1912+
test_decode_color <actual.raw >actual &&
1913+
test_cmp expect.bare actual
1914+
'
1915+
1916+
test_expect_success TTY '%(color) present with tty' '
1917+
test_terminal env TERM=vt100 git tag $color_args >actual.raw &&
1918+
test_decode_color <actual.raw >actual &&
1919+
test_cmp expect.color actual
1920+
'
1921+
1922+
test_expect_success 'color.ui=always overrides auto-color' '
1923+
git -c color.ui=always tag $color_args >actual.raw &&
1924+
test_decode_color <actual.raw >actual &&
1925+
test_cmp expect.color actual
1926+
'
1927+
19031928
test_expect_success 'setup --merged test tags' '
19041929
git tag mergetest-1 HEAD~2 &&
19051930
git tag mergetest-2 HEAD~1 &&

0 commit comments

Comments
 (0)