Merge branch 'jk/color-variable-fixes'

Some places in the code confused a variable that is *not* a boolean
to enable color but is an enum that records what the user requested
to do about color.  A couple of bugs of this sort have been fixed,
while the code has been cleaned up to prevent similar bugs in the
future.

* jk/color-variable-fixes:
  config: store want_color() result in a separate bool
  add-interactive: retain colorbool values longer
  color: return bool from want_color()
  color: use git_colorbool enum type to store colorbools
  pretty: use format_commit_context.auto_color as colorbool
  diff: stop passing ecbdata->use_color as boolean
  diff: pass o->use_color directly to fill_metainfo()
  diff: don't use diff_options.use_color as a strict bool
  diff: simplify color_moved check when flushing
  grep: don't treat grep_opt.color as a strict bool
  color: return enum from git_config_colorbool()
  color: use GIT_COLOR_* instead of numeric constants
main
Junio C Hamano 2025-09-29 11:40:35 -07:00
commit a89fa2fff2
30 changed files with 114 additions and 109 deletions

View File

@ -20,14 +20,14 @@
#include "prompt.h"
#include "tree.h"

static void init_color(struct repository *r, int use_color,
static void init_color(struct repository *r, enum git_colorbool use_color,
const char *section_and_slot, char *dst,
const char *default_color)
{
char *key = xstrfmt("color.%s", section_and_slot);
const char *value;

if (!use_color)
if (!want_color(use_color))
dst[0] = '\0';
else if (repo_config_get_value(r, key, &value) ||
color_parse(value, dst))
@ -36,13 +36,13 @@ static void init_color(struct repository *r, int use_color,
free(key);
}

static int check_color_config(struct repository *r, const char *var)
static enum git_colorbool check_color_config(struct repository *r, const char *var)
{
const char *value;
int ret;
enum git_colorbool ret;

if (repo_config_get_value(r, var, &value))
ret = -1;
ret = GIT_COLOR_UNKNOWN;
else
ret = git_config_colorbool(var, value);

@ -51,10 +51,11 @@ static int check_color_config(struct repository *r, const char *var)
* the value parsed by git_color_config(), which may not have been
* 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);

return want_color(ret);
return ret;
}

void init_add_i_state(struct add_i_state *s, struct repository *r,
@ -75,7 +76,7 @@ void init_add_i_state(struct add_i_state *s, struct repository *r,
init_color(r, s->use_color_interactive, "interactive.error",
s->error_color, GIT_COLOR_BOLD_RED);
strlcpy(s->reset_color_interactive,
s->use_color_interactive ? GIT_COLOR_RESET : "", COLOR_MAXLEN);
want_color(s->use_color_interactive) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);

s->use_color_diff = check_color_config(r, "color.diff");

@ -92,7 +93,7 @@ void init_add_i_state(struct add_i_state *s, struct repository *r,
init_color(r, s->use_color_diff, "diff.new", s->file_new_color,
diff_get_color(s->use_color_diff, DIFF_FILE_NEW));
strlcpy(s->reset_color_diff,
s->use_color_diff ? GIT_COLOR_RESET : "", COLOR_MAXLEN);
want_color(s->use_color_diff) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);

FREE_AND_NULL(s->interactive_diff_filter);
repo_config_get_string(r, "interactive.difffilter",
@ -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_algorithm);
memset(s, 0, sizeof(*s));
s->use_color_interactive = -1;
s->use_color_diff = -1;
s->use_color_interactive = GIT_COLOR_UNKNOWN;
s->use_color_diff = GIT_COLOR_UNKNOWN;
}

/*
@ -1210,7 +1211,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps,
* When color was asked for, use the prompt color for
* highlighting, otherwise use square brackets.
*/
if (s.use_color_interactive) {
if (want_color(s.use_color_interactive)) {
data.color = s.prompt_color;
data.reset = s.reset_color_interactive;
}

View File

@ -12,8 +12,8 @@ struct add_p_opt {

struct add_i_state {
struct repository *r;
int use_color_interactive;
int use_color_diff;
enum git_colorbool use_color_interactive;
enum git_colorbool use_color_diff;
char header_color[COLOR_MAXLEN];
char help_color[COLOR_MAXLEN];
char prompt_color[COLOR_MAXLEN];

View File

@ -7,7 +7,7 @@
#include "help.h"
#include "string-list.h"

static int advice_use_color = -1;
static enum git_colorbool advice_use_color = GIT_COLOR_UNKNOWN;
static char advice_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
GIT_COLOR_YELLOW, /* HINT */

View File

@ -200,7 +200,7 @@ static int edit_patch(struct repository *repo,

argc = setup_revisions(argc, argv, &rev, NULL);
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;
out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
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.diffopt.flags.binary = 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.close_file = 1;
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.no_commit_id = 1;
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.close_file = 1;
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 submodule_propagate_branches = 0;

static int branch_use_color = -1;
static enum git_colorbool branch_use_color = GIT_COLOR_UNKNOWN;
static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
GIT_COLOR_NORMAL, /* PLAIN */

View File

@ -64,7 +64,7 @@ static const char *color_interactive_slots[] = {
[CLEAN_COLOR_RESET] = "reset",
};

static int clean_use_color = -1;
static enum git_colorbool clean_use_color = GIT_COLOR_UNKNOWN;
static char clean_colors[][COLOR_MAXLEN] = {
[CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED,
[CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,

View File

@ -940,7 +940,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT));
if (use_editor && include_status) {
int ident_shown = 0;
int saved_color_setting;
enum git_colorbool saved_color_setting;
struct ident_split ci, ai;
const char *hint_cleanup_all = allow_empty_message ?
_("Please enter the commit message for your changes."
@ -1020,7 +1020,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 */

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);
s->use_color = saved_color_setting;
string_list_clear_func(&s->change, change_data_free);

View File

@ -568,9 +568,9 @@ static void get_color(const struct config_location_options *opts,
}

struct get_colorbool_config_data {
int get_colorbool_found;
int get_diff_color_found;
int get_color_ui_found;
enum git_colorbool get_colorbool_found;
enum git_colorbool get_diff_color_found;
enum git_colorbool get_color_ui_found;
const char *get_colorbool_slot;
};

@ -594,33 +594,34 @@ static int get_colorbool(const struct config_location_options *opts,
{
struct get_colorbool_config_data data = {
.get_colorbool_slot = var,
.get_colorbool_found = -1,
.get_diff_color_found = -1,
.get_color_ui_found = -1,
.get_colorbool_found = GIT_COLOR_UNKNOWN,
.get_diff_color_found = GIT_COLOR_UNKNOWN,
.get_color_ui_found = GIT_COLOR_UNKNOWN,
};
bool result;

config_with_options(git_get_colorbool_config, &data,
&opts->source, the_repository,
&opts->options);

if (data.get_colorbool_found < 0) {
if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) {
if (!strcmp(data.get_colorbool_slot, "color.diff"))
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;
}

if (data.get_colorbool_found < 0)
if (data.get_colorbool_found == GIT_COLOR_UNKNOWN)
/* default value if none found in config */
data.get_colorbool_found = GIT_COLOR_AUTO;

data.get_colorbool_found = want_color(data.get_colorbool_found);
result = want_color(data.get_colorbool_found);

if (print) {
printf("%s\n", data.get_colorbool_found ? "true" : "false");
printf("%s\n", result ? "true" : "false");
return 0;
} else
return data.get_colorbool_found ? 0 : 1;
return result ? 0 : 1;
}

static void check_write(const struct git_config_source *source)

View File

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

View File

@ -27,7 +27,7 @@ static const char * const push_usage[] = {
NULL,
};

static int push_use_color = -1;
static enum git_colorbool push_use_color = GIT_COLOR_UNKNOWN;
static char push_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
GIT_COLOR_RED, /* ERROR */

View File

@ -7,6 +7,7 @@
#include "range-diff.h"
#include "config.h"
#include "parse.h"
#include "color.h"


static const char * const builtin_range_diff_usage[] = {
@ -87,7 +88,7 @@ int cmd_range_diff(int argc,

/* force color when --dual-color was used */
if (!simple_color)
diffopt.use_color = 1;
diffopt.use_color = GIT_COLOR_ALWAYS;

/* If `--diff-merges` was specified, imply `--merges` */
if (diff_merges_arg.nr) {

View File

@ -29,7 +29,7 @@ static const char*const show_branch_usage[] = {
NULL
};

static int showbranch_use_color = -1;
static enum git_colorbool showbranch_use_color = GIT_COLOR_UNKNOWN;

static struct strvec default_args = STRVEC_INIT;


24
color.c
View File

@ -9,7 +9,7 @@
#include "pager.h"
#include "strbuf.h"

static int git_use_color_default = GIT_COLOR_AUTO;
static enum git_colorbool git_use_color_default = GIT_COLOR_AUTO;
int color_stdout_is_tty = -1;

/*
@ -369,29 +369,29 @@ bad:
#undef OUT
}

int git_config_colorbool(const char *var, const char *value)
enum git_colorbool git_config_colorbool(const char *var, const char *value)
{
if (value) {
if (!strcasecmp(value, "never"))
return 0;
return GIT_COLOR_NEVER;
if (!strcasecmp(value, "always"))
return 1;
return GIT_COLOR_ALWAYS;
if (!strcasecmp(value, "auto"))
return GIT_COLOR_AUTO;
}

if (!var)
return -1;
return GIT_COLOR_UNKNOWN;

/* Missing or explicit false to turn off colorization */
if (!git_config_bool(var, value))
return 0;
return GIT_COLOR_NEVER;

/* any normal truth value defaults to 'auto' */
return GIT_COLOR_AUTO;
}

static int check_auto_color(int fd)
static bool check_auto_color(int fd)
{
static int color_stderr_is_tty = -1;
int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;
@ -399,12 +399,12 @@ static int check_auto_color(int fd)
*is_tty_p = isatty(fd);
if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {
if (!is_terminal_dumb())
return 1;
return true;
}
return 0;
return false;
}

int want_color_fd(int fd, int var)
bool want_color_fd(int fd, enum git_colorbool var)
{
/*
* NEEDSWORK: This function is sometimes used from multiple threads, and
@ -418,7 +418,7 @@ int want_color_fd(int fd, int var)
if (fd < 1 || fd >= ARRAY_SIZE(want_auto))
BUG("file descriptor out of range: %d", fd);

if (var < 0)
if (var == GIT_COLOR_UNKNOWN)
var = git_use_color_default;

if (var == GIT_COLOR_AUTO) {
@ -426,7 +426,7 @@ int want_color_fd(int fd, int var)
want_auto[fd] = check_auto_color(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)

14
color.h
View File

@ -73,10 +73,12 @@ struct strbuf;
* returned from git_config_colorbool. The "auto" value can be returned from
* config_colorbool, and will be converted by want_color() into either 0 or 1.
*/
#define GIT_COLOR_UNKNOWN -1
#define GIT_COLOR_NEVER 0
#define GIT_COLOR_ALWAYS 1
#define GIT_COLOR_AUTO 2
enum git_colorbool {
GIT_COLOR_UNKNOWN = -1,
GIT_COLOR_NEVER = 0,
GIT_COLOR_ALWAYS = 1,
GIT_COLOR_AUTO = 2,
};

/* A default list of colors to use for commit graphs and show-branch output */
extern const char *column_colors_ansi[];
@ -98,13 +100,13 @@ int git_color_config(const char *var, const char *value, void *cb);
* GIT_COLOR_ALWAYS for "always" or a positive boolean,
* and GIT_COLOR_AUTO for "auto".
*/
int git_config_colorbool(const char *var, const char *value);
enum git_colorbool git_config_colorbool(const char *var, const char *value);

/*
* Return a boolean whether to use color, where the argument 'var' is
* one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO.
*/
int want_color_fd(int fd, int var);
bool want_color_fd(int fd, enum git_colorbool var);
#define want_color(colorbool) want_color_fd(1, (colorbool))
#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))


View File

@ -749,7 +749,7 @@ static void show_line_to_eol(const char *line, int len, const char *reset)

static void dump_sline(struct sline *sline, const char *line_prefix,
unsigned long cnt, int num_parent,
int use_color, int result_deleted)
enum git_colorbool use_color, int result_deleted)
{
unsigned long mark = (1UL<<num_parent);
unsigned long no_pre_delete = (2UL<<num_parent);

28
diff.c
View File

@ -57,7 +57,7 @@ static int diff_detect_rename_default;
static int diff_indent_heuristic = 1;
static int diff_rename_limit_default = 1000;
static int diff_suppress_blank_empty;
static int diff_use_color_default = -1;
static enum git_colorbool diff_use_color_default = GIT_COLOR_UNKNOWN;
static int diff_color_moved_default;
static int diff_color_moved_ws_default;
static int diff_context_default = 3;
@ -1672,7 +1672,7 @@ static void emit_hunk_header(struct emit_callback *ecbdata,
const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO);
const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO);
const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET);
const char *reverse = ecbdata->color_diff ? GIT_COLOR_REVERSE : "";
const char *reverse = want_color(ecbdata->color_diff) ? GIT_COLOR_REVERSE : "";
static const char atat[2] = { '@', '@' };
const char *cp, *ep;
struct strbuf msgbuf = STRBUF_INIT;
@ -1826,7 +1826,7 @@ static void emit_rewrite_diff(const char *name_a,
size_two = fill_textconv(o->repo, textconv_two, two, &data_two);

memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.color_diff = want_color(o->use_color);
ecbdata.color_diff = o->use_color;
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
@ -2303,7 +2303,7 @@ static void free_diff_words_data(struct emit_callback *ecbdata)
}
}

const char *diff_get_color(int diff_use_color, enum color_diff ix)
const char *diff_get_color(enum git_colorbool diff_use_color, enum color_diff ix)
{
if (want_color(diff_use_color))
return diff_colors[ix];
@ -3732,7 +3732,7 @@ static void builtin_diff(const char *name_a,
if (o->flags.suppress_diff_headers)
lbl[0] = NULL;
ecbdata.label_path = lbl;
ecbdata.color_diff = want_color(o->use_color);
ecbdata.color_diff = o->use_color;
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
check_blank_at_eof(&mf1, &mf2, &ecbdata);
@ -4497,7 +4497,7 @@ static void fill_metainfo(struct strbuf *msg,
struct diff_options *o,
struct diff_filepair *p,
int *must_show_header,
int use_color)
enum git_colorbool use_color)
{
const char *set = diff_get_color(use_color, DIFF_METAINFO);
const char *reset = diff_get_color(use_color, DIFF_RESET);
@ -4596,7 +4596,7 @@ static void run_diff_cmd(const struct external_diff *pgm,
*/
fill_metainfo(msg, name, other, one, two, o, p,
&must_show_header,
want_color(o->use_color) && !pgm);
pgm ? GIT_COLOR_NEVER : o->use_color);
xfrm_msg = msg->len ? msg->buf : NULL;
}

@ -4995,8 +4995,7 @@ void diff_setup_done(struct diff_options *options)
if (options->flags.follow_renames)
diff_check_follow_pathspec(&options->pathspec, 1);

if (!options->use_color ||
(options->flags.allow_external && external_diff()))
if (options->flags.allow_external && external_diff())
options->color_moved = 0;

if (options->filter_not) {
@ -5278,7 +5277,7 @@ static int diff_opt_color_words(const struct option *opt,
struct diff_options *options = opt->value;

BUG_ON_OPT_NEG(unset);
options->use_color = 1;
options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR;
options->word_regex = arg;
return 0;
@ -5600,7 +5599,7 @@ static int diff_opt_word_diff(const struct option *opt,
if (!strcmp(arg, "plain"))
options->word_diff = DIFF_WORDS_PLAIN;
else if (!strcmp(arg, "color")) {
options->use_color = 1;
options->use_color = GIT_COLOR_ALWAYS;
options->word_diff = DIFF_WORDS_COLOR;
}
else if (!strcmp(arg, "porcelain"))
@ -6733,7 +6732,7 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
if (WSEH_NEW & WS_RULE_MASK)
BUG("WS rules bit mask overlaps with diff symbol flags");

if (o->color_moved)
if (o->color_moved && want_color(o->use_color))
o->emitted_symbols = &esm;

if (o->additional_path_headers)
@ -6746,20 +6745,17 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
}

if (o->emitted_symbols) {
if (o->color_moved) {
struct mem_pool entry_pool;
struct moved_entry_list *entry_list;

mem_pool_init(&entry_pool, 1024 * 1024);
entry_list = add_lines_to_move_detection(o,
&entry_pool);
entry_list = add_lines_to_move_detection(o, &entry_pool);
mark_color_as_moved(o, entry_list);
if (o->color_moved == COLOR_MOVED_ZEBRA_DIM)
dim_moved_lines(o);

mem_pool_discard(&entry_pool, 0);
free(entry_list);
}

for (i = 0; i < esm.nr; i++)
emit_diff_symbol_from_struct(o, &esm.buf[i]);

5
diff.h
View File

@ -7,6 +7,7 @@
#include "hash.h"
#include "pathspec.h"
#include "strbuf.h"
#include "color.h"

struct oidset;

@ -283,7 +284,7 @@ struct diff_options {
/* diff-filter bits */
unsigned int filter, filter_not;

int use_color;
enum git_colorbool use_color;

/* Number of context lines to generate in patch output. */
int context;
@ -469,7 +470,7 @@ enum color_diff {
DIFF_FILE_NEW_BOLD = 22,
};

const char *diff_get_color(int diff_use_color, enum color_diff ix);
const char *diff_get_color(enum git_colorbool diff_use_color, enum color_diff ix);
#define diff_get_color_opt(o, ix) \
diff_get_color((o)->use_color, ix)


4
grep.c
View File

@ -1263,12 +1263,12 @@ static void show_line(struct grep_opt *opt,
*/
show_line_header(opt, name, lno, cno, sign);
}
if (opt->color || opt->only_matching) {
if (want_color(opt->color) || opt->only_matching) {
regmatch_t match;
enum grep_context ctx = GREP_CONTEXT_BODY;
int eflags = 0;

if (opt->color) {
if (want_color(opt->color)) {
if (sign == ':')
match_color = opt->colors[GREP_COLOR_MATCH_SELECTED];
else

4
grep.h
View File

@ -159,7 +159,7 @@ struct grep_opt {
int pathname;
int null_following_name;
int only_matching;
int color;
enum git_colorbool color;
int max_depth;
int funcname;
int funcbody;
@ -198,7 +198,7 @@ struct grep_opt {
[GREP_COLOR_SEP] = GIT_COLOR_CYAN, \
}, \
.only_matching = 0, \
.color = -1, \
.color = GIT_COLOR_UNKNOWN, \
.output = std_output, \
}


View File

@ -57,7 +57,7 @@ static const char *color_decorate_slots[] = {
[DECORATION_GRAFTED] = "grafted",
};

static const char *decorate_get_color(int decorate_use_color, enum decoration_type ix)
static const char *decorate_get_color(enum git_colorbool decorate_use_color, enum decoration_type ix)
{
if (want_color(decorate_use_color))
return decoration_colors[ix];
@ -341,7 +341,7 @@ static void show_name(struct strbuf *sb, const struct name_decoration *decoratio
*/
void format_decorations(struct strbuf *sb,
const struct commit *commit,
int use_color,
enum git_colorbool use_color,
const struct decoration_options *opts)
{
const struct name_decoration *decoration;

View File

@ -1,6 +1,8 @@
#ifndef LOG_TREE_H
#define LOG_TREE_H

#include "color.h"

struct rev_info;

struct log_info {
@ -26,7 +28,7 @@ int log_tree_diff_flush(struct rev_info *);
int log_tree_commit(struct rev_info *, struct commit *);
void show_log(struct rev_info *opt);
void format_decorations(struct strbuf *sb, const struct commit *commit,
int use_color, const struct decoration_options *opts);
enum git_colorbool use_color, const struct decoration_options *opts);
void show_decorations(struct rev_info *opt, struct commit *commit);
void log_write_email_headers(struct rev_info *opt, struct commit *commit,
char **extra_headers_p,

View File

@ -50,12 +50,12 @@ int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
int unset)
{
int value;
enum git_colorbool value;

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

View File

@ -470,7 +470,7 @@ static inline void strbuf_add_with_color(struct strbuf *sb, const char *color,

static void append_line_with_color(struct strbuf *sb, struct grep_opt *opt,
const char *line, size_t linelen,
int color, enum grep_context ctx,
enum git_colorbool color, enum grep_context ctx,
enum grep_header_field field)
{
const char *buf, *eol, *line_color, *match_color;
@ -899,7 +899,7 @@ struct format_commit_context {
const char *message;
char *commit_encoding;
size_t width, indent1, indent2;
int auto_color;
enum git_colorbool auto_color;
int padding;

/* These offsets are relative to the start of the commit message. */
@ -1455,14 +1455,14 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
switch (placeholder[0]) {
case 'C':
if (starts_with(placeholder + 1, "(auto)")) {
c->auto_color = want_color(c->pretty_ctx->color);
if (c->auto_color && sb->len)
c->auto_color = c->pretty_ctx->color;
if (want_color(c->auto_color) && sb->len)
strbuf_addstr(sb, GIT_COLOR_RESET);
return 7; /* consumed 7 bytes, "C(auto)" */
} else {
int ret = parse_color(sb, placeholder, c);
if (ret)
c->auto_color = 0;
c->auto_color = GIT_COLOR_NEVER;
/*
* Otherwise, we decided to treat %C<unknown>
* as a literal string, and the previous
@ -2167,7 +2167,7 @@ static int pp_utf8_width(const char *start, const char *end)
}

static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt,
int color, int tabwidth, const char *line,
enum git_colorbool color, int tabwidth, const char *line,
int linelen)
{
const char *tab;

View File

@ -3,6 +3,7 @@

#include "date.h"
#include "string-list.h"
#include "color.h"

struct commit;
struct repository;
@ -46,7 +47,7 @@ struct pretty_print_context {
struct rev_info *rev;
const char *output_encoding;
struct string_list *mailmap;
int color;
enum git_colorbool color;
struct ident_split *from_ident;
unsigned encode_email_headers:1;
struct pretty_print_describe_status *describe_status;

View File

@ -95,7 +95,7 @@ struct ref_format {
const char *format;
const char *rest;
int quote_style;
int use_color;
enum git_colorbool use_color;

/* Internal state to ref-filter */
int need_color_reset_at_eol;
@ -111,7 +111,7 @@ struct ref_format {
.exclude = STRVEC_INIT, \
}
#define REF_FORMAT_INIT { \
.use_color = -1, \
.use_color = GIT_COLOR_UNKNOWN, \
}

/* Macros for checking --merged and --no-merged options */

View File

@ -27,16 +27,16 @@ static struct keyword_entry keywords[] = {
};

/* Returns a color setting (GIT_COLOR_NEVER, etc). */
static int use_sideband_colors(void)
static enum git_colorbool use_sideband_colors(void)
{
static int use_sideband_colors_cached = -1;
static enum git_colorbool use_sideband_colors_cached = GIT_COLOR_UNKNOWN;

const char *key = "color.remote";
struct strbuf sb = STRBUF_INIT;
const char *value;
int i;

if (use_sideband_colors_cached >= 0)
if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN)
return use_sideband_colors_cached;

if (!repo_config_get_string_tmp(the_repository, key, &value))

View File

@ -30,7 +30,7 @@
#include "color.h"
#include "bundle-uri.h"

static int transport_use_color = -1;
static enum git_colorbool transport_use_color = GIT_COLOR_UNKNOWN;
static char transport_colors[][COLOR_MAXLEN] = {
GIT_COLOR_RESET,
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,
sizeof(default_wt_status_colors));
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = -1;
s->use_color = GIT_COLOR_UNKNOWN;
s->relative_paths = 1;
s->branch = refs_resolve_refdup(get_main_ref_store(the_repository),
"HEAD", 0, NULL, NULL);
@ -1165,7 +1165,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
* before.
*/
if (s->fp != stdout) {
rev.diffopt.use_color = 0;
rev.diffopt.use_color = GIT_COLOR_NEVER;
wt_status_add_cut_line(s);
}
if (s->verbose > 1 && s->committable) {
@ -2155,7 +2155,7 @@ static void wt_shortstatus_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->prefix = NULL;
s->no_gettext = 1;

View File

@ -111,7 +111,7 @@ struct wt_status {
int amend;
enum commit_whence whence;
int nowarn;
int use_color;
enum git_colorbool use_color;
int no_gettext;
int display_comment_prefix;
int relative_paths;