color: use GIT_COLOR_* instead of numeric constants

Long ago Git's decision to show color for a subsytem was stored in a
tri-state variable: it could be true (1), false (0), or unknown (-1).
But since daa0c3d971 (color: delay auto-color decision until point of
use, 2011-08-17) we want to carry around a new state, "auto", which
bases the decision on the tty-ness of stdout (rather than collapsing
that "auto" state to a true/false immediately).

That commit introduced a set of GIT_COLOR_* defines to represent each
state: UNKNOWN, ALWAYS, NEVER, and AUTO. But it only used the AUTO
value, and left alone code using bare 0/1/-1 values. And of course since
then we've grown many new spots that use those bare values.

Let's switch all of these to use the named constants. That should make
the code a bit easier to read, as it is more obvious that we're
representing a color decision.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King
2025-09-16 16:13:28 -04:00
committed by Junio C Hamano
parent e335ff31f7
commit 3c3e9b8303
21 changed files with 42 additions and 40 deletions

View File

@@ -42,7 +42,7 @@ static int check_color_config(struct repository *r, const char *var)
int ret; int ret;
if (repo_config_get_value(r, var, &value)) if (repo_config_get_value(r, var, &value))
ret = -1; ret = GIT_COLOR_UNKNOWN;
else else
ret = git_config_colorbool(var, value); ret = git_config_colorbool(var, value);
@@ -51,7 +51,8 @@ static int check_color_config(struct repository *r, const char *var)
* the value parsed by git_color_config(), which may not have been * the value parsed by git_color_config(), which may not have been
* called by the main command. * called by the main command.
*/ */
if (ret < 0 && !repo_config_get_value(r, "color.ui", &value)) if (ret == GIT_COLOR_UNKNOWN &&
!repo_config_get_value(r, "color.ui", &value))
ret = git_config_colorbool("color.ui", value); ret = git_config_colorbool("color.ui", value);
return want_color(ret); return want_color(ret);
@@ -130,8 +131,8 @@ void clear_add_i_state(struct add_i_state *s)
FREE_AND_NULL(s->interactive_diff_filter); FREE_AND_NULL(s->interactive_diff_filter);
FREE_AND_NULL(s->interactive_diff_algorithm); FREE_AND_NULL(s->interactive_diff_algorithm);
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->use_color_interactive = -1; s->use_color_interactive = GIT_COLOR_UNKNOWN;
s->use_color_diff = -1; s->use_color_diff = GIT_COLOR_UNKNOWN;
} }
/* /*

View File

@@ -7,7 +7,7 @@
#include "help.h" #include "help.h"
#include "string-list.h" #include "string-list.h"
static int advice_use_color = -1; static int advice_use_color = GIT_COLOR_UNKNOWN;
static char advice_colors[][COLOR_MAXLEN] = { static char advice_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET, GIT_COLOR_RESET,
GIT_COLOR_YELLOW, /* HINT */ GIT_COLOR_YELLOW, /* HINT */

View File

@@ -200,7 +200,7 @@ static int edit_patch(struct repository *repo,
argc = setup_revisions(argc, argv, &rev, NULL); argc = setup_revisions(argc, argv, &rev, NULL);
rev.diffopt.output_format = DIFF_FORMAT_PATCH; rev.diffopt.output_format = DIFF_FORMAT_PATCH;
rev.diffopt.use_color = 0; rev.diffopt.use_color = GIT_COLOR_NEVER;
rev.diffopt.flags.ignore_dirty_submodules = 1; rev.diffopt.flags.ignore_dirty_submodules = 1;
out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666); out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
rev.diffopt.file = xfdopen(out, "w"); rev.diffopt.file = xfdopen(out, "w");

View File

@@ -1408,7 +1408,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm
rev_info.no_commit_id = 1; rev_info.no_commit_id = 1;
rev_info.diffopt.flags.binary = 1; rev_info.diffopt.flags.binary = 1;
rev_info.diffopt.flags.full_index = 1; rev_info.diffopt.flags.full_index = 1;
rev_info.diffopt.use_color = 0; rev_info.diffopt.use_color = GIT_COLOR_NEVER;
rev_info.diffopt.file = fp; rev_info.diffopt.file = fp;
rev_info.diffopt.close_file = 1; rev_info.diffopt.close_file = 1;
add_pending_object(&rev_info, &commit->object, ""); add_pending_object(&rev_info, &commit->object, "");
@@ -1441,7 +1441,7 @@ static void write_index_patch(const struct am_state *state)
rev_info.disable_stdin = 1; rev_info.disable_stdin = 1;
rev_info.no_commit_id = 1; rev_info.no_commit_id = 1;
rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; rev_info.diffopt.output_format = DIFF_FORMAT_PATCH;
rev_info.diffopt.use_color = 0; rev_info.diffopt.use_color = GIT_COLOR_NEVER;
rev_info.diffopt.file = fp; rev_info.diffopt.file = fp;
rev_info.diffopt.close_file = 1; rev_info.diffopt.close_file = 1;
add_pending_object(&rev_info, &tree->object, ""); add_pending_object(&rev_info, &tree->object, "");

View File

@@ -46,7 +46,7 @@ static struct object_id head_oid;
static int recurse_submodules = 0; static int recurse_submodules = 0;
static int submodule_propagate_branches = 0; static int submodule_propagate_branches = 0;
static int branch_use_color = -1; static int branch_use_color = GIT_COLOR_UNKNOWN;
static char branch_colors[][COLOR_MAXLEN] = { static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET, GIT_COLOR_RESET,
GIT_COLOR_NORMAL, /* PLAIN */ GIT_COLOR_NORMAL, /* PLAIN */

View File

@@ -64,7 +64,7 @@ static const char *color_interactive_slots[] = {
[CLEAN_COLOR_RESET] = "reset", [CLEAN_COLOR_RESET] = "reset",
}; };
static int clean_use_color = -1; static int clean_use_color = GIT_COLOR_UNKNOWN;
static char clean_colors[][COLOR_MAXLEN] = { static char clean_colors[][COLOR_MAXLEN] = {
[CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED, [CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED,
[CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD, [CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,

View File

@@ -1016,7 +1016,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); /* Add new line for clarity */ status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); /* Add new line for clarity */
saved_color_setting = s->use_color; saved_color_setting = s->use_color;
s->use_color = 0; s->use_color = GIT_COLOR_NEVER;
committable = run_status(s->fp, index_file, prefix, 1, s); committable = run_status(s->fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting; s->use_color = saved_color_setting;
string_list_clear_func(&s->change, change_data_free); string_list_clear_func(&s->change, change_data_free);

View File

@@ -594,23 +594,23 @@ static int get_colorbool(const struct config_location_options *opts,
{ {
struct get_colorbool_config_data data = { struct get_colorbool_config_data data = {
.get_colorbool_slot = var, .get_colorbool_slot = var,
.get_colorbool_found = -1, .get_colorbool_found = GIT_COLOR_UNKNOWN,
.get_diff_color_found = -1, .get_diff_color_found = GIT_COLOR_UNKNOWN,
.get_color_ui_found = -1, .get_color_ui_found = GIT_COLOR_UNKNOWN,
}; };
config_with_options(git_get_colorbool_config, &data, config_with_options(git_get_colorbool_config, &data,
&opts->source, the_repository, &opts->source, the_repository,
&opts->options); &opts->options);
if (data.get_colorbool_found < 0) { if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) {
if (!strcmp(data.get_colorbool_slot, "color.diff")) if (!strcmp(data.get_colorbool_slot, "color.diff"))
data.get_colorbool_found = data.get_diff_color_found; data.get_colorbool_found = data.get_diff_color_found;
if (data.get_colorbool_found < 0) if (data.get_colorbool_found == GIT_COLOR_UNKNOWN)
data.get_colorbool_found = data.get_color_ui_found; data.get_colorbool_found = data.get_color_ui_found;
} }
if (data.get_colorbool_found < 0) if (data.get_colorbool_found == GIT_COLOR_UNKNOWN)
/* default value if none found in config */ /* default value if none found in config */
data.get_colorbool_found = GIT_COLOR_AUTO; data.get_colorbool_found = GIT_COLOR_AUTO;

View File

@@ -1091,7 +1091,7 @@ int cmd_grep(int argc,
if (show_in_pager == default_pager) if (show_in_pager == default_pager)
show_in_pager = git_pager(the_repository, 1); show_in_pager = git_pager(the_repository, 1);
if (show_in_pager) { if (show_in_pager) {
opt.color = 0; opt.color = GIT_COLOR_NEVER;
opt.name_only = 1; opt.name_only = 1;
opt.null_following_name = 1; opt.null_following_name = 1;
opt.output_priv = &path_list; opt.output_priv = &path_list;

View File

@@ -27,7 +27,7 @@ static const char * const push_usage[] = {
NULL, NULL,
}; };
static int push_use_color = -1; static int push_use_color = GIT_COLOR_UNKNOWN;
static char push_colors[][COLOR_MAXLEN] = { static char push_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET, GIT_COLOR_RESET,
GIT_COLOR_RED, /* ERROR */ GIT_COLOR_RED, /* ERROR */

View File

@@ -6,6 +6,7 @@
#include "parse-options.h" #include "parse-options.h"
#include "range-diff.h" #include "range-diff.h"
#include "config.h" #include "config.h"
#include "color.h"
static const char * const builtin_range_diff_usage[] = { static const char * const builtin_range_diff_usage[] = {
@@ -66,7 +67,7 @@ int cmd_range_diff(int argc,
/* force color when --dual-color was used */ /* force color when --dual-color was used */
if (!simple_color) if (!simple_color)
diffopt.use_color = 1; diffopt.use_color = GIT_COLOR_ALWAYS;
/* If `--diff-merges` was specified, imply `--merges` */ /* If `--diff-merges` was specified, imply `--merges` */
if (diff_merges_arg.nr) { if (diff_merges_arg.nr) {

View File

@@ -29,7 +29,7 @@ static const char*const show_branch_usage[] = {
NULL NULL
}; };
static int showbranch_use_color = -1; static int showbranch_use_color = GIT_COLOR_UNKNOWN;
static struct strvec default_args = STRVEC_INIT; static struct strvec default_args = STRVEC_INIT;

12
color.c
View File

@@ -373,19 +373,19 @@ int git_config_colorbool(const char *var, const char *value)
{ {
if (value) { if (value) {
if (!strcasecmp(value, "never")) if (!strcasecmp(value, "never"))
return 0; return GIT_COLOR_NEVER;
if (!strcasecmp(value, "always")) if (!strcasecmp(value, "always"))
return 1; return GIT_COLOR_ALWAYS;
if (!strcasecmp(value, "auto")) if (!strcasecmp(value, "auto"))
return GIT_COLOR_AUTO; return GIT_COLOR_AUTO;
} }
if (!var) if (!var)
return -1; return GIT_COLOR_UNKNOWN;
/* Missing or explicit false to turn off colorization */ /* Missing or explicit false to turn off colorization */
if (!git_config_bool(var, value)) if (!git_config_bool(var, value))
return 0; return GIT_COLOR_NEVER;
/* any normal truth value defaults to 'auto' */ /* any normal truth value defaults to 'auto' */
return GIT_COLOR_AUTO; return GIT_COLOR_AUTO;
@@ -418,7 +418,7 @@ int want_color_fd(int fd, int var)
if (fd < 1 || fd >= ARRAY_SIZE(want_auto)) if (fd < 1 || fd >= ARRAY_SIZE(want_auto))
BUG("file descriptor out of range: %d", fd); BUG("file descriptor out of range: %d", fd);
if (var < 0) if (var == GIT_COLOR_UNKNOWN)
var = git_use_color_default; var = git_use_color_default;
if (var == GIT_COLOR_AUTO) { if (var == GIT_COLOR_AUTO) {
@@ -426,7 +426,7 @@ int want_color_fd(int fd, int var)
want_auto[fd] = check_auto_color(fd); want_auto[fd] = check_auto_color(fd);
return want_auto[fd]; return want_auto[fd];
} }
return var; return var == GIT_COLOR_ALWAYS;
} }
int git_color_config(const char *var, const char *value, void *cb UNUSED) int git_color_config(const char *var, const char *value, void *cb UNUSED)

6
diff.c
View File

@@ -57,7 +57,7 @@ static int diff_detect_rename_default;
static int diff_indent_heuristic = 1; static int diff_indent_heuristic = 1;
static int diff_rename_limit_default = 1000; static int diff_rename_limit_default = 1000;
static int diff_suppress_blank_empty; static int diff_suppress_blank_empty;
static int diff_use_color_default = -1; static int diff_use_color_default = GIT_COLOR_UNKNOWN;
static int diff_color_moved_default; static int diff_color_moved_default;
static int diff_color_moved_ws_default; static int diff_color_moved_ws_default;
static int diff_context_default = 3; static int diff_context_default = 3;
@@ -5259,7 +5259,7 @@ static int diff_opt_color_words(const struct option *opt,
struct diff_options *options = opt->value; struct diff_options *options = opt->value;
BUG_ON_OPT_NEG(unset); BUG_ON_OPT_NEG(unset);
options->use_color = 1; options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR; options->word_diff = DIFF_WORDS_COLOR;
options->word_regex = arg; options->word_regex = arg;
return 0; return 0;
@@ -5581,7 +5581,7 @@ static int diff_opt_word_diff(const struct option *opt,
if (!strcmp(arg, "plain")) if (!strcmp(arg, "plain"))
options->word_diff = DIFF_WORDS_PLAIN; options->word_diff = DIFF_WORDS_PLAIN;
else if (!strcmp(arg, "color")) { else if (!strcmp(arg, "color")) {
options->use_color = 1; options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR; options->word_diff = DIFF_WORDS_COLOR;
} }
else if (!strcmp(arg, "porcelain")) else if (!strcmp(arg, "porcelain"))

2
grep.h
View File

@@ -198,7 +198,7 @@ struct grep_opt {
[GREP_COLOR_SEP] = GIT_COLOR_CYAN, \ [GREP_COLOR_SEP] = GIT_COLOR_CYAN, \
}, \ }, \
.only_matching = 0, \ .only_matching = 0, \
.color = -1, \ .color = GIT_COLOR_UNKNOWN, \
.output = std_output, \ .output = std_output, \
} }

View File

@@ -55,7 +55,7 @@ int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
if (!arg) if (!arg)
arg = unset ? "never" : (const char *)opt->defval; arg = unset ? "never" : (const char *)opt->defval;
value = git_config_colorbool(NULL, arg); value = git_config_colorbool(NULL, arg);
if (value < 0) if (value == GIT_COLOR_UNKNOWN)
return error(_("option `%s' expects \"always\", \"auto\", or \"never\""), return error(_("option `%s' expects \"always\", \"auto\", or \"never\""),
opt->long_name); opt->long_name);
*(int *)opt->value = value; *(int *)opt->value = value;

View File

@@ -1462,7 +1462,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
} else { } else {
int ret = parse_color(sb, placeholder, c); int ret = parse_color(sb, placeholder, c);
if (ret) if (ret)
c->auto_color = 0; c->auto_color = GIT_COLOR_NEVER;
/* /*
* Otherwise, we decided to treat %C<unknown> * Otherwise, we decided to treat %C<unknown>
* as a literal string, and the previous * as a literal string, and the previous

View File

@@ -111,7 +111,7 @@ struct ref_format {
.exclude = STRVEC_INIT, \ .exclude = STRVEC_INIT, \
} }
#define REF_FORMAT_INIT { \ #define REF_FORMAT_INIT { \
.use_color = -1, \ .use_color = GIT_COLOR_UNKNOWN, \
} }
/* Macros for checking --merged and --no-merged options */ /* Macros for checking --merged and --no-merged options */

View File

@@ -29,14 +29,14 @@ static struct keyword_entry keywords[] = {
/* Returns a color setting (GIT_COLOR_NEVER, etc). */ /* Returns a color setting (GIT_COLOR_NEVER, etc). */
static int use_sideband_colors(void) static int use_sideband_colors(void)
{ {
static int use_sideband_colors_cached = -1; static int use_sideband_colors_cached = GIT_COLOR_UNKNOWN;
const char *key = "color.remote"; const char *key = "color.remote";
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
const char *value; const char *value;
int i; int i;
if (use_sideband_colors_cached >= 0) if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN)
return use_sideband_colors_cached; return use_sideband_colors_cached;
if (!repo_config_get_string_tmp(the_repository, key, &value)) if (!repo_config_get_string_tmp(the_repository, key, &value))

View File

@@ -30,7 +30,7 @@
#include "color.h" #include "color.h"
#include "bundle-uri.h" #include "bundle-uri.h"
static int transport_use_color = -1; static int transport_use_color = GIT_COLOR_UNKNOWN;
static char transport_colors[][COLOR_MAXLEN] = { static char transport_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET, GIT_COLOR_RESET,
GIT_COLOR_RED /* REJECTED */ GIT_COLOR_RED /* REJECTED */

View File

@@ -148,7 +148,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
memcpy(s->color_palette, default_wt_status_colors, memcpy(s->color_palette, default_wt_status_colors,
sizeof(default_wt_status_colors)); sizeof(default_wt_status_colors));
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = -1; s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1; s->relative_paths = 1;
s->branch = refs_resolve_refdup(get_main_ref_store(the_repository), s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
"HEAD", 0, NULL, NULL); "HEAD", 0, NULL, NULL);
@@ -1164,7 +1164,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
* before. * before.
*/ */
if (s->fp != stdout) { if (s->fp != stdout) {
rev.diffopt.use_color = 0; rev.diffopt.use_color = GIT_COLOR_NEVER;
wt_status_add_cut_line(s); wt_status_add_cut_line(s);
} }
if (s->verbose > 1 && s->committable) { if (s->verbose > 1 && s->committable) {
@@ -2164,7 +2164,7 @@ static void wt_shortstatus_print(struct wt_status *s)
static void wt_porcelain_print(struct wt_status *s) static void wt_porcelain_print(struct wt_status *s)
{ {
s->use_color = 0; s->use_color = GIT_COLOR_NEVER;
s->relative_paths = 0; s->relative_paths = 0;
s->prefix = NULL; s->prefix = NULL;
s->no_gettext = 1; s->no_gettext = 1;