Skip to content

Commit 15595ce

Browse files
committed
Merge branch 'jk/ref-filter-colors'
"%C(color name)" in the pretty print format always produced ANSI color escape codes, which was an early design mistake. They now honor the configuration (e.g. "color.ui = never") and also tty-ness of the output medium. * jk/ref-filter-colors: ref-filter: consult want_color() before emitting colors pretty: respect color settings for %C placeholders rev-list: pass diffopt->use_colors through to pretty-print for-each-ref: load config earlier color: check color.ui in git_default_config() ref-filter: pass ref_format struct to atom parsers ref-filter: factor out the parsing of sorting atoms ref-filter: make parse_ref_filter_atom a private function ref-filter: provide a function for parsing sort options ref-filter: move need_color_reset_at_eol into ref_format ref-filter: abstract ref format into its own struct ref-filter: simplify automatic color reset t: use test_decode_color rather than literal ANSI codes docs/for-each-ref: update pointer to color syntax check return value of verify_ref_format()
2 parents 076eeec + 11b087a commit 15595ce

22 files changed

+362
-220
lines changed

Documentation/git-for-each-ref.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ HEAD::
156156
otherwise.
157157

158158
color::
159-
Change output color. Followed by `:<colorname>`, where names
160-
are described in `color.branch.*`.
159+
Change output color. Followed by `:<colorname>`, where color
160+
names are described under Values in the "CONFIGURATION FILE"
161+
section of linkgit:git-config[1]. For example,
162+
`%(color:bold red)`.
161163

162164
align::
163165
Left-, middle-, or right-align the content between

Documentation/pretty-formats.txt

+11-7
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,17 @@ endif::git-rev-list[]
173173
- '%Cblue': switch color to blue
174174
- '%Creset': reset color
175175
- '%C(...)': color specification, as described under Values in the
176-
"CONFIGURATION FILE" section of linkgit:git-config[1];
177-
adding `auto,` at the beginning (e.g. `%C(auto,red)`) will emit
178-
color only when colors are enabled for log output (by `color.diff`,
179-
`color.ui`, or `--color`, and respecting the `auto` settings of the
180-
former if we are going to a terminal). `auto` alone (i.e.
181-
`%C(auto)`) will turn on auto coloring on the next placeholders
182-
until the color is switched again.
176+
"CONFIGURATION FILE" section of linkgit:git-config[1].
177+
By default, colors are shown only when enabled for log output (by
178+
`color.diff`, `color.ui`, or `--color`, and respecting the `auto`
179+
settings of the former if we are going to a terminal). `%C(auto,...)`
180+
is accepted as a historical synonym for the default (e.g.,
181+
`%C(auto,red)`). Specifying `%C(always,...) will show the colors
182+
even when color is not otherwise enabled (though consider
183+
just using `--color=always` to enable color for the whole output,
184+
including this format and anything else git might color). `auto`
185+
alone (i.e. `%C(auto)`) will turn on auto coloring on the next
186+
placeholders until the color is switched again.
183187
- '%m': left (`<`), right (`>`) or boundary (`-`) mark
184188
- '%n': newline
185189
- '%%': a raw '%'

builtin/branch.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static int git_branch_config(const char *var, const char *value, void *cb)
9292
return config_error_nonbool(var);
9393
return color_parse(value, branch_colors[slot]);
9494
}
95-
return git_color_default_config(var, value, cb);
95+
return git_default_config(var, value, cb);
9696
}
9797

9898
static const char *branch_get_color(enum color_branch ix)
@@ -383,7 +383,7 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
383383
return strbuf_detach(&fmt, NULL);
384384
}
385385

386-
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
386+
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format)
387387
{
388388
int i;
389389
struct ref_array array;
@@ -407,14 +407,17 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
407407
if (filter->verbose)
408408
maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
409409

410-
if (!format)
411-
format = to_free = build_format(filter, maxwidth, remote_prefix);
412-
verify_ref_format(format);
410+
if (!format->format)
411+
format->format = to_free = build_format(filter, maxwidth, remote_prefix);
412+
format->use_color = branch_use_color;
413+
414+
if (verify_ref_format(format))
415+
die(_("unable to parse format string"));
413416

414417
ref_array_sort(sorting, &array);
415418

416419
for (i = 0; i < array.nr; i++) {
417-
format_ref_array_item(array.items[i], format, 0, &out);
420+
format_ref_array_item(array.items[i], format, &out);
418421
if (column_active(colopts)) {
419422
assert(!filter->verbose && "--column and --verbose are incompatible");
420423
/* format to a string_list to let print_columns() do its job */
@@ -549,7 +552,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
549552
struct ref_filter filter;
550553
int icase = 0;
551554
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
552-
const char *format = NULL;
555+
struct ref_format format = REF_FORMAT_INIT;
553556

554557
struct option options[] = {
555558
OPT_GROUP(N_("Generic options")),
@@ -593,7 +596,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
593596
N_("print only branches of the object"), 0, parse_opt_object_name
594597
},
595598
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
596-
OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
599+
OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")),
597600
OPT_END(),
598601
};
599602

@@ -667,7 +670,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
667670
if (!sorting)
668671
sorting = ref_default_sorting();
669672
sorting->ignore_case = icase;
670-
print_ref_list(&filter, sorting, format);
673+
print_ref_list(&filter, sorting, &format);
671674
print_columns(&output, colopts, NULL);
672675
string_list_clear(&output, 0);
673676
return 0;

builtin/clean.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ static int git_clean_config(const char *var, const char *value, void *cb)
125125
return 0;
126126
}
127127

128-
/* inspect the color.ui config variable and others */
129-
return git_color_default_config(var, value, cb);
128+
return git_default_config(var, value, cb);
130129
}
131130

132131
static const char *clean_get_color(enum color_clean ix)

builtin/for-each-ref.c

+14-13
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ static char const * const for_each_ref_usage[] = {
1717
int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
1818
{
1919
int i;
20-
const char *format = "%(objectname) %(objecttype)\t%(refname)";
2120
struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
22-
int maxcount = 0, quote_style = 0, icase = 0;
21+
int maxcount = 0, icase = 0;
2322
struct ref_array array;
2423
struct ref_filter filter;
24+
struct ref_format format = REF_FORMAT_INIT;
2525

2626
struct option opts[] = {
27-
OPT_BIT('s', "shell", &quote_style,
27+
OPT_BIT('s', "shell", &format.quote_style,
2828
N_("quote placeholders suitably for shells"), QUOTE_SHELL),
29-
OPT_BIT('p', "perl", &quote_style,
29+
OPT_BIT('p', "perl", &format.quote_style,
3030
N_("quote placeholders suitably for perl"), QUOTE_PERL),
31-
OPT_BIT(0 , "python", &quote_style,
31+
OPT_BIT(0 , "python", &format.quote_style,
3232
N_("quote placeholders suitably for python"), QUOTE_PYTHON),
33-
OPT_BIT(0 , "tcl", &quote_style,
33+
OPT_BIT(0 , "tcl", &format.quote_style,
3434
N_("quote placeholders suitably for Tcl"), QUOTE_TCL),
3535

3636
OPT_GROUP(""),
3737
OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
38-
OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
38+
OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")),
3939
OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
4040
N_("field name to sort on"), &parse_opt_ref_sorting),
4141
OPT_CALLBACK(0, "points-at", &filter.points_at,
@@ -52,26 +52,27 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
5252
memset(&array, 0, sizeof(array));
5353
memset(&filter, 0, sizeof(filter));
5454

55+
format.format = "%(objectname) %(objecttype)\t%(refname)";
56+
57+
git_config(git_default_config, NULL);
58+
5559
parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);
5660
if (maxcount < 0) {
5761
error("invalid --count argument: `%d'", maxcount);
5862
usage_with_options(for_each_ref_usage, opts);
5963
}
60-
if (HAS_MULTI_BITS(quote_style)) {
64+
if (HAS_MULTI_BITS(format.quote_style)) {
6165
error("more than one quoting style?");
6266
usage_with_options(for_each_ref_usage, opts);
6367
}
64-
if (verify_ref_format(format))
68+
if (verify_ref_format(&format))
6569
usage_with_options(for_each_ref_usage, opts);
6670

6771
if (!sorting)
6872
sorting = ref_default_sorting();
6973
sorting->ignore_case = icase;
7074
filter.ignore_case = icase;
7175

72-
/* for warn_ambiguous_refs */
73-
git_config(git_default_config, NULL);
74-
7576
filter.name_patterns = argv;
7677
filter.match_as_path = 1;
7778
filter_refs(&array, &filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN);
@@ -80,7 +81,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
8081
if (!maxcount || array.nr < maxcount)
8182
maxcount = array.nr;
8283
for (i = 0; i < maxcount; i++)
83-
show_ref_array_item(array.items[i], format, quote_style);
84+
show_ref_array_item(array.items[i], &format);
8485
ref_array_clear(&array);
8586
return 0;
8687
}

builtin/grep.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ static int wait_all(void)
284284
static int grep_cmd_config(const char *var, const char *value, void *cb)
285285
{
286286
int st = grep_config(var, value, cb);
287-
if (git_color_default_config(var, value, cb) < 0)
287+
if (git_default_config(var, value, cb) < 0)
288288
st = -1;
289289

290290
if (!strcmp(var, "grep.threads")) {

builtin/rev-list.c

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ static void show_commit(struct commit *commit, void *data)
122122
ctx.date_mode_explicit = revs->date_mode_explicit;
123123
ctx.fmt = revs->commit_format;
124124
ctx.output_encoding = get_log_output_encoding();
125+
ctx.color = revs->diffopt.use_color;
125126
pretty_print_commit(&ctx, commit, &buf);
126127
if (buf.len) {
127128
if (revs->commit_format != CMIT_FMT_ONELINE)

builtin/show-branch.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ static int git_show_branch_config(const char *var, const char *value, void *cb)
554554
return 0;
555555
}
556556

557-
return git_color_default_config(var, value, cb);
557+
return git_default_config(var, value, cb);
558558
}
559559

560560
static int omit_in_dense(struct commit *commit, struct commit **rev, int n)

builtin/tag.c

+20-41
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ static const char * const git_tag_usage[] = {
3232
static unsigned int colopts;
3333
static int force_sign_annotate;
3434

35-
static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
35+
static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
36+
struct ref_format *format)
3637
{
3738
struct ref_array array;
3839
char *to_free = NULL;
@@ -43,23 +44,24 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
4344
if (filter->lines == -1)
4445
filter->lines = 0;
4546

46-
if (!format) {
47+
if (!format->format) {
4748
if (filter->lines) {
4849
to_free = xstrfmt("%s %%(contents:lines=%d)",
4950
"%(align:15)%(refname:lstrip=2)%(end)",
5051
filter->lines);
51-
format = to_free;
52+
format->format = to_free;
5253
} else
53-
format = "%(refname:lstrip=2)";
54+
format->format = "%(refname:lstrip=2)";
5455
}
5556

56-
verify_ref_format(format);
57+
if (verify_ref_format(format))
58+
die(_("unable to parse format string"));
5759
filter->with_commit_tag_algo = 1;
5860
filter_refs(&array, filter, FILTER_REFS_TAGS);
5961
ref_array_sort(sorting, &array);
6062

6163
for (i = 0; i < array.nr; i++)
62-
show_ref_array_item(array.items[i], format, 0);
64+
show_ref_array_item(array.items[i], format);
6365
ref_array_clear(&array);
6466
free(to_free);
6567

@@ -105,17 +107,17 @@ static int verify_tag(const char *name, const char *ref,
105107
const struct object_id *oid, const void *cb_data)
106108
{
107109
int flags;
108-
const char *fmt_pretty = cb_data;
110+
const struct ref_format *format = cb_data;
109111
flags = GPG_VERIFY_VERBOSE;
110112

111-
if (fmt_pretty)
113+
if (format->format)
112114
flags = GPG_VERIFY_OMIT_STATUS;
113115

114116
if (gpg_verify_tag(oid, name, flags))
115117
return -1;
116118

117-
if (fmt_pretty)
118-
pretty_print_ref(name, oid->hash, fmt_pretty);
119+
if (format->format)
120+
pretty_print_ref(name, oid->hash, format);
119121

120122
return 0;
121123
}
@@ -134,30 +136,6 @@ static const char tag_template_nocleanup[] =
134136
"Lines starting with '%c' will be kept; you may remove them"
135137
" yourself if you want to.\n");
136138

137-
/* Parse arg given and add it the ref_sorting array */
138-
static int parse_sorting_string(const char *arg, struct ref_sorting **sorting_tail)
139-
{
140-
struct ref_sorting *s;
141-
int len;
142-
143-
s = xcalloc(1, sizeof(*s));
144-
s->next = *sorting_tail;
145-
*sorting_tail = s;
146-
147-
if (*arg == '-') {
148-
s->reverse = 1;
149-
arg++;
150-
}
151-
if (skip_prefix(arg, "version:", &arg) ||
152-
skip_prefix(arg, "v:", &arg))
153-
s->version = 1;
154-
155-
len = strlen(arg);
156-
s->atom = parse_ref_filter_atom(arg, arg+len);
157-
158-
return 0;
159-
}
160-
161139
static int git_tag_config(const char *var, const char *value, void *cb)
162140
{
163141
int status;
@@ -166,7 +144,7 @@ static int git_tag_config(const char *var, const char *value, void *cb)
166144
if (!strcmp(var, "tag.sort")) {
167145
if (!value)
168146
return config_error_nonbool(var);
169-
parse_sorting_string(value, sorting_tail);
147+
parse_ref_sorting(sorting_tail, value);
170148
return 0;
171149
}
172150

@@ -392,7 +370,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
392370
struct strbuf err = STRBUF_INIT;
393371
struct ref_filter filter;
394372
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
395-
const char *format = NULL;
373+
struct ref_format format = REF_FORMAT_INIT;
396374
int icase = 0;
397375
struct option options[] = {
398376
OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
@@ -431,7 +409,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
431409
N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT,
432410
parse_opt_object_name, (intptr_t) "HEAD"
433411
},
434-
OPT_STRING( 0 , "format", &format, N_("format"), N_("format to use for the output")),
412+
OPT_STRING( 0 , "format", &format.format, N_("format"),
413+
N_("format to use for the output")),
435414
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
436415
OPT_END()
437416
};
@@ -483,7 +462,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
483462
run_column_filter(colopts, &copts);
484463
}
485464
filter.name_patterns = argv;
486-
ret = list_tags(&filter, sorting, format);
465+
ret = list_tags(&filter, sorting, &format);
487466
if (column_active(colopts))
488467
stop_column_filter();
489468
return ret;
@@ -501,9 +480,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
501480
if (cmdmode == 'd')
502481
return for_each_tag_name(argv, delete_tag, NULL);
503482
if (cmdmode == 'v') {
504-
if (format)
505-
verify_ref_format(format);
506-
return for_each_tag_name(argv, verify_tag, format);
483+
if (format.format && verify_ref_format(&format))
484+
usage_with_options(git_tag_usage, options);
485+
return for_each_tag_name(argv, verify_tag, &format);
507486
}
508487

509488
if (msg.given || msgfile) {

builtin/verify-tag.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
3232
{
3333
int i = 1, verbose = 0, had_error = 0;
3434
unsigned flags = 0;
35-
char *fmt_pretty = NULL;
35+
struct ref_format format = REF_FORMAT_INIT;
3636
const struct option verify_tag_options[] = {
3737
OPT__VERBOSE(&verbose, N_("print tag contents")),
3838
OPT_BIT(0, "raw", &flags, N_("print raw gpg status output"), GPG_VERIFY_RAW),
39-
OPT_STRING( 0 , "format", &fmt_pretty, N_("format"), N_("format to use for the output")),
39+
OPT_STRING(0, "format", &format.format, N_("format"), N_("format to use for the output")),
4040
OPT_END()
4141
};
4242

@@ -50,8 +50,10 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
5050
if (verbose)
5151
flags |= GPG_VERIFY_VERBOSE;
5252

53-
if (fmt_pretty) {
54-
verify_ref_format(fmt_pretty);
53+
if (format.format) {
54+
if (verify_ref_format(&format))
55+
usage_with_options(verify_tag_usage,
56+
verify_tag_options);
5557
flags |= GPG_VERIFY_OMIT_STATUS;
5658
}
5759

@@ -69,8 +71,8 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
6971
continue;
7072
}
7173

72-
if (fmt_pretty)
73-
pretty_print_ref(name, oid.hash, fmt_pretty);
74+
if (format.format)
75+
pretty_print_ref(name, oid.hash, &format);
7476
}
7577
return had_error;
7678
}

0 commit comments

Comments
 (0)