Git fork

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

+114 -109
+13 -12
add-interactive.c
··· 20 #include "prompt.h" 21 #include "tree.h" 22 23 - static void init_color(struct repository *r, int use_color, 24 const char *section_and_slot, char *dst, 25 const char *default_color) 26 { 27 char *key = xstrfmt("color.%s", section_and_slot); 28 const char *value; 29 30 - if (!use_color) 31 dst[0] = '\0'; 32 else if (repo_config_get_value(r, key, &value) || 33 color_parse(value, dst)) ··· 36 free(key); 37 } 38 39 - static int check_color_config(struct repository *r, const char *var) 40 { 41 const char *value; 42 - int ret; 43 44 if (repo_config_get_value(r, var, &value)) 45 - ret = -1; 46 else 47 ret = git_config_colorbool(var, value); 48 ··· 51 * the value parsed by git_color_config(), which may not have been 52 * called by the main command. 53 */ 54 - if (ret < 0 && !repo_config_get_value(r, "color.ui", &value)) 55 ret = git_config_colorbool("color.ui", value); 56 57 - return want_color(ret); 58 } 59 60 void init_add_i_state(struct add_i_state *s, struct repository *r, ··· 75 init_color(r, s->use_color_interactive, "interactive.error", 76 s->error_color, GIT_COLOR_BOLD_RED); 77 strlcpy(s->reset_color_interactive, 78 - s->use_color_interactive ? GIT_COLOR_RESET : "", COLOR_MAXLEN); 79 80 s->use_color_diff = check_color_config(r, "color.diff"); 81 ··· 92 init_color(r, s->use_color_diff, "diff.new", s->file_new_color, 93 diff_get_color(s->use_color_diff, DIFF_FILE_NEW)); 94 strlcpy(s->reset_color_diff, 95 - s->use_color_diff ? GIT_COLOR_RESET : "", COLOR_MAXLEN); 96 97 FREE_AND_NULL(s->interactive_diff_filter); 98 repo_config_get_string(r, "interactive.difffilter", ··· 130 FREE_AND_NULL(s->interactive_diff_filter); 131 FREE_AND_NULL(s->interactive_diff_algorithm); 132 memset(s, 0, sizeof(*s)); 133 - s->use_color_interactive = -1; 134 - s->use_color_diff = -1; 135 } 136 137 /* ··· 1210 * When color was asked for, use the prompt color for 1211 * highlighting, otherwise use square brackets. 1212 */ 1213 - if (s.use_color_interactive) { 1214 data.color = s.prompt_color; 1215 data.reset = s.reset_color_interactive; 1216 }
··· 20 #include "prompt.h" 21 #include "tree.h" 22 23 + static void init_color(struct repository *r, enum git_colorbool use_color, 24 const char *section_and_slot, char *dst, 25 const char *default_color) 26 { 27 char *key = xstrfmt("color.%s", section_and_slot); 28 const char *value; 29 30 + if (!want_color(use_color)) 31 dst[0] = '\0'; 32 else if (repo_config_get_value(r, key, &value) || 33 color_parse(value, dst)) ··· 36 free(key); 37 } 38 39 + static enum git_colorbool check_color_config(struct repository *r, const char *var) 40 { 41 const char *value; 42 + enum git_colorbool ret; 43 44 if (repo_config_get_value(r, var, &value)) 45 + ret = GIT_COLOR_UNKNOWN; 46 else 47 ret = git_config_colorbool(var, value); 48 ··· 51 * the value parsed by git_color_config(), which may not have been 52 * called by the main command. 53 */ 54 + if (ret == GIT_COLOR_UNKNOWN && 55 + !repo_config_get_value(r, "color.ui", &value)) 56 ret = git_config_colorbool("color.ui", value); 57 58 + return ret; 59 } 60 61 void init_add_i_state(struct add_i_state *s, struct repository *r, ··· 76 init_color(r, s->use_color_interactive, "interactive.error", 77 s->error_color, GIT_COLOR_BOLD_RED); 78 strlcpy(s->reset_color_interactive, 79 + want_color(s->use_color_interactive) ? GIT_COLOR_RESET : "", COLOR_MAXLEN); 80 81 s->use_color_diff = check_color_config(r, "color.diff"); 82 ··· 93 init_color(r, s->use_color_diff, "diff.new", s->file_new_color, 94 diff_get_color(s->use_color_diff, DIFF_FILE_NEW)); 95 strlcpy(s->reset_color_diff, 96 + want_color(s->use_color_diff) ? GIT_COLOR_RESET : "", COLOR_MAXLEN); 97 98 FREE_AND_NULL(s->interactive_diff_filter); 99 repo_config_get_string(r, "interactive.difffilter", ··· 131 FREE_AND_NULL(s->interactive_diff_filter); 132 FREE_AND_NULL(s->interactive_diff_algorithm); 133 memset(s, 0, sizeof(*s)); 134 + s->use_color_interactive = GIT_COLOR_UNKNOWN; 135 + s->use_color_diff = GIT_COLOR_UNKNOWN; 136 } 137 138 /* ··· 1211 * When color was asked for, use the prompt color for 1212 * highlighting, otherwise use square brackets. 1213 */ 1214 + if (want_color(s.use_color_interactive)) { 1215 data.color = s.prompt_color; 1216 data.reset = s.reset_color_interactive; 1217 }
+2 -2
add-interactive.h
··· 12 13 struct add_i_state { 14 struct repository *r; 15 - int use_color_interactive; 16 - int use_color_diff; 17 char header_color[COLOR_MAXLEN]; 18 char help_color[COLOR_MAXLEN]; 19 char prompt_color[COLOR_MAXLEN];
··· 12 13 struct add_i_state { 14 struct repository *r; 15 + enum git_colorbool use_color_interactive; 16 + enum git_colorbool use_color_diff; 17 char header_color[COLOR_MAXLEN]; 18 char help_color[COLOR_MAXLEN]; 19 char prompt_color[COLOR_MAXLEN];
+1 -1
advice.c
··· 7 #include "help.h" 8 #include "string-list.h" 9 10 - static int advice_use_color = -1; 11 static char advice_colors[][COLOR_MAXLEN] = { 12 GIT_COLOR_RESET, 13 GIT_COLOR_YELLOW, /* HINT */
··· 7 #include "help.h" 8 #include "string-list.h" 9 10 + static enum git_colorbool advice_use_color = GIT_COLOR_UNKNOWN; 11 static char advice_colors[][COLOR_MAXLEN] = { 12 GIT_COLOR_RESET, 13 GIT_COLOR_YELLOW, /* HINT */
+1 -1
builtin/add.c
··· 200 201 argc = setup_revisions(argc, argv, &rev, NULL); 202 rev.diffopt.output_format = DIFF_FORMAT_PATCH; 203 - rev.diffopt.use_color = 0; 204 rev.diffopt.flags.ignore_dirty_submodules = 1; 205 out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666); 206 rev.diffopt.file = xfdopen(out, "w");
··· 200 201 argc = setup_revisions(argc, argv, &rev, NULL); 202 rev.diffopt.output_format = DIFF_FORMAT_PATCH; 203 + rev.diffopt.use_color = GIT_COLOR_NEVER; 204 rev.diffopt.flags.ignore_dirty_submodules = 1; 205 out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666); 206 rev.diffopt.file = xfdopen(out, "w");
+2 -2
builtin/am.c
··· 1408 rev_info.no_commit_id = 1; 1409 rev_info.diffopt.flags.binary = 1; 1410 rev_info.diffopt.flags.full_index = 1; 1411 - rev_info.diffopt.use_color = 0; 1412 rev_info.diffopt.file = fp; 1413 rev_info.diffopt.close_file = 1; 1414 add_pending_object(&rev_info, &commit->object, ""); ··· 1441 rev_info.disable_stdin = 1; 1442 rev_info.no_commit_id = 1; 1443 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; 1444 - rev_info.diffopt.use_color = 0; 1445 rev_info.diffopt.file = fp; 1446 rev_info.diffopt.close_file = 1; 1447 add_pending_object(&rev_info, &tree->object, "");
··· 1408 rev_info.no_commit_id = 1; 1409 rev_info.diffopt.flags.binary = 1; 1410 rev_info.diffopt.flags.full_index = 1; 1411 + rev_info.diffopt.use_color = GIT_COLOR_NEVER; 1412 rev_info.diffopt.file = fp; 1413 rev_info.diffopt.close_file = 1; 1414 add_pending_object(&rev_info, &commit->object, ""); ··· 1441 rev_info.disable_stdin = 1; 1442 rev_info.no_commit_id = 1; 1443 rev_info.diffopt.output_format = DIFF_FORMAT_PATCH; 1444 + rev_info.diffopt.use_color = GIT_COLOR_NEVER; 1445 rev_info.diffopt.file = fp; 1446 rev_info.diffopt.close_file = 1; 1447 add_pending_object(&rev_info, &tree->object, "");
+1 -1
builtin/branch.c
··· 46 static int recurse_submodules = 0; 47 static int submodule_propagate_branches = 0; 48 49 - static int branch_use_color = -1; 50 static char branch_colors[][COLOR_MAXLEN] = { 51 GIT_COLOR_RESET, 52 GIT_COLOR_NORMAL, /* PLAIN */
··· 46 static int recurse_submodules = 0; 47 static int submodule_propagate_branches = 0; 48 49 + static enum git_colorbool branch_use_color = GIT_COLOR_UNKNOWN; 50 static char branch_colors[][COLOR_MAXLEN] = { 51 GIT_COLOR_RESET, 52 GIT_COLOR_NORMAL, /* PLAIN */
+1 -1
builtin/clean.c
··· 64 [CLEAN_COLOR_RESET] = "reset", 65 }; 66 67 - static int clean_use_color = -1; 68 static char clean_colors[][COLOR_MAXLEN] = { 69 [CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED, 70 [CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,
··· 64 [CLEAN_COLOR_RESET] = "reset", 65 }; 66 67 + static enum git_colorbool clean_use_color = GIT_COLOR_UNKNOWN; 68 static char clean_colors[][COLOR_MAXLEN] = { 69 [CLEAN_COLOR_ERROR] = GIT_COLOR_BOLD_RED, 70 [CLEAN_COLOR_HEADER] = GIT_COLOR_BOLD,
+2 -2
builtin/commit.c
··· 940 strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT)); 941 if (use_editor && include_status) { 942 int ident_shown = 0; 943 - int saved_color_setting; 944 struct ident_split ci, ai; 945 const char *hint_cleanup_all = allow_empty_message ? 946 _("Please enter the commit message for your changes." ··· 1020 status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); /* Add new line for clarity */ 1021 1022 saved_color_setting = s->use_color; 1023 - s->use_color = 0; 1024 committable = run_status(s->fp, index_file, prefix, 1, s); 1025 s->use_color = saved_color_setting; 1026 string_list_clear_func(&s->change, change_data_free);
··· 940 strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT)); 941 if (use_editor && include_status) { 942 int ident_shown = 0; 943 + enum git_colorbool saved_color_setting; 944 struct ident_split ci, ai; 945 const char *hint_cleanup_all = allow_empty_message ? 946 _("Please enter the commit message for your changes." ··· 1020 status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); /* Add new line for clarity */ 1021 1022 saved_color_setting = s->use_color; 1023 + s->use_color = GIT_COLOR_NEVER; 1024 committable = run_status(s->fp, index_file, prefix, 1, s); 1025 s->use_color = saved_color_setting; 1026 string_list_clear_func(&s->change, change_data_free);
+13 -12
builtin/config.c
··· 568 } 569 570 struct get_colorbool_config_data { 571 - int get_colorbool_found; 572 - int get_diff_color_found; 573 - int get_color_ui_found; 574 const char *get_colorbool_slot; 575 }; 576 ··· 594 { 595 struct get_colorbool_config_data data = { 596 .get_colorbool_slot = var, 597 - .get_colorbool_found = -1, 598 - .get_diff_color_found = -1, 599 - .get_color_ui_found = -1, 600 }; 601 602 config_with_options(git_get_colorbool_config, &data, 603 &opts->source, the_repository, 604 &opts->options); 605 606 - if (data.get_colorbool_found < 0) { 607 if (!strcmp(data.get_colorbool_slot, "color.diff")) 608 data.get_colorbool_found = data.get_diff_color_found; 609 - if (data.get_colorbool_found < 0) 610 data.get_colorbool_found = data.get_color_ui_found; 611 } 612 613 - if (data.get_colorbool_found < 0) 614 /* default value if none found in config */ 615 data.get_colorbool_found = GIT_COLOR_AUTO; 616 617 - data.get_colorbool_found = want_color(data.get_colorbool_found); 618 619 if (print) { 620 - printf("%s\n", data.get_colorbool_found ? "true" : "false"); 621 return 0; 622 } else 623 - return data.get_colorbool_found ? 0 : 1; 624 } 625 626 static void check_write(const struct git_config_source *source)
··· 568 } 569 570 struct get_colorbool_config_data { 571 + enum git_colorbool get_colorbool_found; 572 + enum git_colorbool get_diff_color_found; 573 + enum git_colorbool get_color_ui_found; 574 const char *get_colorbool_slot; 575 }; 576 ··· 594 { 595 struct get_colorbool_config_data data = { 596 .get_colorbool_slot = var, 597 + .get_colorbool_found = GIT_COLOR_UNKNOWN, 598 + .get_diff_color_found = GIT_COLOR_UNKNOWN, 599 + .get_color_ui_found = GIT_COLOR_UNKNOWN, 600 }; 601 + bool result; 602 603 config_with_options(git_get_colorbool_config, &data, 604 &opts->source, the_repository, 605 &opts->options); 606 607 + if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) { 608 if (!strcmp(data.get_colorbool_slot, "color.diff")) 609 data.get_colorbool_found = data.get_diff_color_found; 610 + if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) 611 data.get_colorbool_found = data.get_color_ui_found; 612 } 613 614 + if (data.get_colorbool_found == GIT_COLOR_UNKNOWN) 615 /* default value if none found in config */ 616 data.get_colorbool_found = GIT_COLOR_AUTO; 617 618 + result = want_color(data.get_colorbool_found); 619 620 if (print) { 621 + printf("%s\n", result ? "true" : "false"); 622 return 0; 623 } else 624 + return result ? 0 : 1; 625 } 626 627 static void check_write(const struct git_config_source *source)
+1 -1
builtin/grep.c
··· 1091 if (show_in_pager == default_pager) 1092 show_in_pager = git_pager(the_repository, 1); 1093 if (show_in_pager) { 1094 - opt.color = 0; 1095 opt.name_only = 1; 1096 opt.null_following_name = 1; 1097 opt.output_priv = &path_list;
··· 1091 if (show_in_pager == default_pager) 1092 show_in_pager = git_pager(the_repository, 1); 1093 if (show_in_pager) { 1094 + opt.color = GIT_COLOR_NEVER; 1095 opt.name_only = 1; 1096 opt.null_following_name = 1; 1097 opt.output_priv = &path_list;
+1 -1
builtin/push.c
··· 27 NULL, 28 }; 29 30 - static int push_use_color = -1; 31 static char push_colors[][COLOR_MAXLEN] = { 32 GIT_COLOR_RESET, 33 GIT_COLOR_RED, /* ERROR */
··· 27 NULL, 28 }; 29 30 + static enum git_colorbool push_use_color = GIT_COLOR_UNKNOWN; 31 static char push_colors[][COLOR_MAXLEN] = { 32 GIT_COLOR_RESET, 33 GIT_COLOR_RED, /* ERROR */
+2 -1
builtin/range-diff.c
··· 7 #include "range-diff.h" 8 #include "config.h" 9 #include "parse.h" 10 11 12 static const char * const builtin_range_diff_usage[] = { ··· 87 88 /* force color when --dual-color was used */ 89 if (!simple_color) 90 - diffopt.use_color = 1; 91 92 /* If `--diff-merges` was specified, imply `--merges` */ 93 if (diff_merges_arg.nr) {
··· 7 #include "range-diff.h" 8 #include "config.h" 9 #include "parse.h" 10 + #include "color.h" 11 12 13 static const char * const builtin_range_diff_usage[] = { ··· 88 89 /* force color when --dual-color was used */ 90 if (!simple_color) 91 + diffopt.use_color = GIT_COLOR_ALWAYS; 92 93 /* If `--diff-merges` was specified, imply `--merges` */ 94 if (diff_merges_arg.nr) {
+1 -1
builtin/show-branch.c
··· 29 NULL 30 }; 31 32 - static int showbranch_use_color = -1; 33 34 static struct strvec default_args = STRVEC_INIT; 35
··· 29 NULL 30 }; 31 32 + static enum git_colorbool showbranch_use_color = GIT_COLOR_UNKNOWN; 33 34 static struct strvec default_args = STRVEC_INIT; 35
+12 -12
color.c
··· 9 #include "pager.h" 10 #include "strbuf.h" 11 12 - static int git_use_color_default = GIT_COLOR_AUTO; 13 int color_stdout_is_tty = -1; 14 15 /* ··· 369 #undef OUT 370 } 371 372 - int git_config_colorbool(const char *var, const char *value) 373 { 374 if (value) { 375 if (!strcasecmp(value, "never")) 376 - return 0; 377 if (!strcasecmp(value, "always")) 378 - return 1; 379 if (!strcasecmp(value, "auto")) 380 return GIT_COLOR_AUTO; 381 } 382 383 if (!var) 384 - return -1; 385 386 /* Missing or explicit false to turn off colorization */ 387 if (!git_config_bool(var, value)) 388 - return 0; 389 390 /* any normal truth value defaults to 'auto' */ 391 return GIT_COLOR_AUTO; 392 } 393 394 - static int check_auto_color(int fd) 395 { 396 static int color_stderr_is_tty = -1; 397 int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty; ··· 399 *is_tty_p = isatty(fd); 400 if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) { 401 if (!is_terminal_dumb()) 402 - return 1; 403 } 404 - return 0; 405 } 406 407 - int want_color_fd(int fd, int var) 408 { 409 /* 410 * NEEDSWORK: This function is sometimes used from multiple threads, and ··· 418 if (fd < 1 || fd >= ARRAY_SIZE(want_auto)) 419 BUG("file descriptor out of range: %d", fd); 420 421 - if (var < 0) 422 var = git_use_color_default; 423 424 if (var == GIT_COLOR_AUTO) { ··· 426 want_auto[fd] = check_auto_color(fd); 427 return want_auto[fd]; 428 } 429 - return var; 430 } 431 432 int git_color_config(const char *var, const char *value, void *cb UNUSED)
··· 9 #include "pager.h" 10 #include "strbuf.h" 11 12 + static enum git_colorbool git_use_color_default = GIT_COLOR_AUTO; 13 int color_stdout_is_tty = -1; 14 15 /* ··· 369 #undef OUT 370 } 371 372 + enum git_colorbool git_config_colorbool(const char *var, const char *value) 373 { 374 if (value) { 375 if (!strcasecmp(value, "never")) 376 + return GIT_COLOR_NEVER; 377 if (!strcasecmp(value, "always")) 378 + return GIT_COLOR_ALWAYS; 379 if (!strcasecmp(value, "auto")) 380 return GIT_COLOR_AUTO; 381 } 382 383 if (!var) 384 + return GIT_COLOR_UNKNOWN; 385 386 /* Missing or explicit false to turn off colorization */ 387 if (!git_config_bool(var, value)) 388 + return GIT_COLOR_NEVER; 389 390 /* any normal truth value defaults to 'auto' */ 391 return GIT_COLOR_AUTO; 392 } 393 394 + static bool check_auto_color(int fd) 395 { 396 static int color_stderr_is_tty = -1; 397 int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty; ··· 399 *is_tty_p = isatty(fd); 400 if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) { 401 if (!is_terminal_dumb()) 402 + return true; 403 } 404 + return false; 405 } 406 407 + bool want_color_fd(int fd, enum git_colorbool var) 408 { 409 /* 410 * NEEDSWORK: This function is sometimes used from multiple threads, and ··· 418 if (fd < 1 || fd >= ARRAY_SIZE(want_auto)) 419 BUG("file descriptor out of range: %d", fd); 420 421 + if (var == GIT_COLOR_UNKNOWN) 422 var = git_use_color_default; 423 424 if (var == GIT_COLOR_AUTO) { ··· 426 want_auto[fd] = check_auto_color(fd); 427 return want_auto[fd]; 428 } 429 + return var == GIT_COLOR_ALWAYS; 430 } 431 432 int git_color_config(const char *var, const char *value, void *cb UNUSED)
+8 -6
color.h
··· 73 * returned from git_config_colorbool. The "auto" value can be returned from 74 * config_colorbool, and will be converted by want_color() into either 0 or 1. 75 */ 76 - #define GIT_COLOR_UNKNOWN -1 77 - #define GIT_COLOR_NEVER 0 78 - #define GIT_COLOR_ALWAYS 1 79 - #define GIT_COLOR_AUTO 2 80 81 /* A default list of colors to use for commit graphs and show-branch output */ 82 extern const char *column_colors_ansi[]; ··· 98 * GIT_COLOR_ALWAYS for "always" or a positive boolean, 99 * and GIT_COLOR_AUTO for "auto". 100 */ 101 - int git_config_colorbool(const char *var, const char *value); 102 103 /* 104 * Return a boolean whether to use color, where the argument 'var' is 105 * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO. 106 */ 107 - int want_color_fd(int fd, int var); 108 #define want_color(colorbool) want_color_fd(1, (colorbool)) 109 #define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) 110
··· 73 * returned from git_config_colorbool. The "auto" value can be returned from 74 * config_colorbool, and will be converted by want_color() into either 0 or 1. 75 */ 76 + enum git_colorbool { 77 + GIT_COLOR_UNKNOWN = -1, 78 + GIT_COLOR_NEVER = 0, 79 + GIT_COLOR_ALWAYS = 1, 80 + GIT_COLOR_AUTO = 2, 81 + }; 82 83 /* A default list of colors to use for commit graphs and show-branch output */ 84 extern const char *column_colors_ansi[]; ··· 100 * GIT_COLOR_ALWAYS for "always" or a positive boolean, 101 * and GIT_COLOR_AUTO for "auto". 102 */ 103 + enum git_colorbool git_config_colorbool(const char *var, const char *value); 104 105 /* 106 * Return a boolean whether to use color, where the argument 'var' is 107 * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO. 108 */ 109 + bool want_color_fd(int fd, enum git_colorbool var); 110 #define want_color(colorbool) want_color_fd(1, (colorbool)) 111 #define want_color_stderr(colorbool) want_color_fd(2, (colorbool)) 112
+1 -1
combine-diff.c
··· 749 750 static void dump_sline(struct sline *sline, const char *line_prefix, 751 unsigned long cnt, int num_parent, 752 - int use_color, int result_deleted) 753 { 754 unsigned long mark = (1UL<<num_parent); 755 unsigned long no_pre_delete = (2UL<<num_parent);
··· 749 750 static void dump_sline(struct sline *sline, const char *line_prefix, 751 unsigned long cnt, int num_parent, 752 + enum git_colorbool use_color, int result_deleted) 753 { 754 unsigned long mark = (1UL<<num_parent); 755 unsigned long no_pre_delete = (2UL<<num_parent);
+20 -24
diff.c
··· 57 static int diff_indent_heuristic = 1; 58 static int diff_rename_limit_default = 1000; 59 static int diff_suppress_blank_empty; 60 - static int diff_use_color_default = -1; 61 static int diff_color_moved_default; 62 static int diff_color_moved_ws_default; 63 static int diff_context_default = 3; ··· 1672 const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO); 1673 const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO); 1674 const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET); 1675 - const char *reverse = ecbdata->color_diff ? GIT_COLOR_REVERSE : ""; 1676 static const char atat[2] = { '@', '@' }; 1677 const char *cp, *ep; 1678 struct strbuf msgbuf = STRBUF_INIT; ··· 1826 size_two = fill_textconv(o->repo, textconv_two, two, &data_two); 1827 1828 memset(&ecbdata, 0, sizeof(ecbdata)); 1829 - ecbdata.color_diff = want_color(o->use_color); 1830 ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); 1831 ecbdata.opt = o; 1832 if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { ··· 2303 } 2304 } 2305 2306 - const char *diff_get_color(int diff_use_color, enum color_diff ix) 2307 { 2308 if (want_color(diff_use_color)) 2309 return diff_colors[ix]; ··· 3732 if (o->flags.suppress_diff_headers) 3733 lbl[0] = NULL; 3734 ecbdata.label_path = lbl; 3735 - ecbdata.color_diff = want_color(o->use_color); 3736 ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); 3737 if (ecbdata.ws_rule & WS_BLANK_AT_EOF) 3738 check_blank_at_eof(&mf1, &mf2, &ecbdata); ··· 4497 struct diff_options *o, 4498 struct diff_filepair *p, 4499 int *must_show_header, 4500 - int use_color) 4501 { 4502 const char *set = diff_get_color(use_color, DIFF_METAINFO); 4503 const char *reset = diff_get_color(use_color, DIFF_RESET); ··· 4596 */ 4597 fill_metainfo(msg, name, other, one, two, o, p, 4598 &must_show_header, 4599 - want_color(o->use_color) && !pgm); 4600 xfrm_msg = msg->len ? msg->buf : NULL; 4601 } 4602 ··· 4995 if (options->flags.follow_renames) 4996 diff_check_follow_pathspec(&options->pathspec, 1); 4997 4998 - if (!options->use_color || 4999 - (options->flags.allow_external && external_diff())) 5000 options->color_moved = 0; 5001 5002 if (options->filter_not) { ··· 5278 struct diff_options *options = opt->value; 5279 5280 BUG_ON_OPT_NEG(unset); 5281 - options->use_color = 1; 5282 options->word_diff = DIFF_WORDS_COLOR; 5283 options->word_regex = arg; 5284 return 0; ··· 5600 if (!strcmp(arg, "plain")) 5601 options->word_diff = DIFF_WORDS_PLAIN; 5602 else if (!strcmp(arg, "color")) { 5603 - options->use_color = 1; 5604 options->word_diff = DIFF_WORDS_COLOR; 5605 } 5606 else if (!strcmp(arg, "porcelain")) ··· 6733 if (WSEH_NEW & WS_RULE_MASK) 6734 BUG("WS rules bit mask overlaps with diff symbol flags"); 6735 6736 - if (o->color_moved) 6737 o->emitted_symbols = &esm; 6738 6739 if (o->additional_path_headers) ··· 6746 } 6747 6748 if (o->emitted_symbols) { 6749 - if (o->color_moved) { 6750 - struct mem_pool entry_pool; 6751 - struct moved_entry_list *entry_list; 6752 6753 - mem_pool_init(&entry_pool, 1024 * 1024); 6754 - entry_list = add_lines_to_move_detection(o, 6755 - &entry_pool); 6756 - mark_color_as_moved(o, entry_list); 6757 - if (o->color_moved == COLOR_MOVED_ZEBRA_DIM) 6758 - dim_moved_lines(o); 6759 6760 - mem_pool_discard(&entry_pool, 0); 6761 - free(entry_list); 6762 - } 6763 6764 for (i = 0; i < esm.nr; i++) 6765 emit_diff_symbol_from_struct(o, &esm.buf[i]);
··· 57 static int diff_indent_heuristic = 1; 58 static int diff_rename_limit_default = 1000; 59 static int diff_suppress_blank_empty; 60 + static enum git_colorbool diff_use_color_default = GIT_COLOR_UNKNOWN; 61 static int diff_color_moved_default; 62 static int diff_color_moved_ws_default; 63 static int diff_context_default = 3; ··· 1672 const char *frag = diff_get_color(ecbdata->color_diff, DIFF_FRAGINFO); 1673 const char *func = diff_get_color(ecbdata->color_diff, DIFF_FUNCINFO); 1674 const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET); 1675 + const char *reverse = want_color(ecbdata->color_diff) ? GIT_COLOR_REVERSE : ""; 1676 static const char atat[2] = { '@', '@' }; 1677 const char *cp, *ep; 1678 struct strbuf msgbuf = STRBUF_INIT; ··· 1826 size_two = fill_textconv(o->repo, textconv_two, two, &data_two); 1827 1828 memset(&ecbdata, 0, sizeof(ecbdata)); 1829 + ecbdata.color_diff = o->use_color; 1830 ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); 1831 ecbdata.opt = o; 1832 if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { ··· 2303 } 2304 } 2305 2306 + const char *diff_get_color(enum git_colorbool diff_use_color, enum color_diff ix) 2307 { 2308 if (want_color(diff_use_color)) 2309 return diff_colors[ix]; ··· 3732 if (o->flags.suppress_diff_headers) 3733 lbl[0] = NULL; 3734 ecbdata.label_path = lbl; 3735 + ecbdata.color_diff = o->use_color; 3736 ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b); 3737 if (ecbdata.ws_rule & WS_BLANK_AT_EOF) 3738 check_blank_at_eof(&mf1, &mf2, &ecbdata); ··· 4497 struct diff_options *o, 4498 struct diff_filepair *p, 4499 int *must_show_header, 4500 + enum git_colorbool use_color) 4501 { 4502 const char *set = diff_get_color(use_color, DIFF_METAINFO); 4503 const char *reset = diff_get_color(use_color, DIFF_RESET); ··· 4596 */ 4597 fill_metainfo(msg, name, other, one, two, o, p, 4598 &must_show_header, 4599 + pgm ? GIT_COLOR_NEVER : o->use_color); 4600 xfrm_msg = msg->len ? msg->buf : NULL; 4601 } 4602 ··· 4995 if (options->flags.follow_renames) 4996 diff_check_follow_pathspec(&options->pathspec, 1); 4997 4998 + if (options->flags.allow_external && external_diff()) 4999 options->color_moved = 0; 5000 5001 if (options->filter_not) { ··· 5277 struct diff_options *options = opt->value; 5278 5279 BUG_ON_OPT_NEG(unset); 5280 + options->use_color = GIT_COLOR_ALWAYS; 5281 options->word_diff = DIFF_WORDS_COLOR; 5282 options->word_regex = arg; 5283 return 0; ··· 5599 if (!strcmp(arg, "plain")) 5600 options->word_diff = DIFF_WORDS_PLAIN; 5601 else if (!strcmp(arg, "color")) { 5602 + options->use_color = GIT_COLOR_ALWAYS; 5603 options->word_diff = DIFF_WORDS_COLOR; 5604 } 5605 else if (!strcmp(arg, "porcelain")) ··· 6732 if (WSEH_NEW & WS_RULE_MASK) 6733 BUG("WS rules bit mask overlaps with diff symbol flags"); 6734 6735 + if (o->color_moved && want_color(o->use_color)) 6736 o->emitted_symbols = &esm; 6737 6738 if (o->additional_path_headers) ··· 6745 } 6746 6747 if (o->emitted_symbols) { 6748 + struct mem_pool entry_pool; 6749 + struct moved_entry_list *entry_list; 6750 6751 + mem_pool_init(&entry_pool, 1024 * 1024); 6752 + entry_list = add_lines_to_move_detection(o, &entry_pool); 6753 + mark_color_as_moved(o, entry_list); 6754 + if (o->color_moved == COLOR_MOVED_ZEBRA_DIM) 6755 + dim_moved_lines(o); 6756 6757 + mem_pool_discard(&entry_pool, 0); 6758 + free(entry_list); 6759 6760 for (i = 0; i < esm.nr; i++) 6761 emit_diff_symbol_from_struct(o, &esm.buf[i]);
+3 -2
diff.h
··· 7 #include "hash.h" 8 #include "pathspec.h" 9 #include "strbuf.h" 10 11 struct oidset; 12 ··· 283 /* diff-filter bits */ 284 unsigned int filter, filter_not; 285 286 - int use_color; 287 288 /* Number of context lines to generate in patch output. */ 289 int context; ··· 469 DIFF_FILE_NEW_BOLD = 22, 470 }; 471 472 - const char *diff_get_color(int diff_use_color, enum color_diff ix); 473 #define diff_get_color_opt(o, ix) \ 474 diff_get_color((o)->use_color, ix) 475
··· 7 #include "hash.h" 8 #include "pathspec.h" 9 #include "strbuf.h" 10 + #include "color.h" 11 12 struct oidset; 13 ··· 284 /* diff-filter bits */ 285 unsigned int filter, filter_not; 286 287 + enum git_colorbool use_color; 288 289 /* Number of context lines to generate in patch output. */ 290 int context; ··· 470 DIFF_FILE_NEW_BOLD = 22, 471 }; 472 473 + const char *diff_get_color(enum git_colorbool diff_use_color, enum color_diff ix); 474 #define diff_get_color_opt(o, ix) \ 475 diff_get_color((o)->use_color, ix) 476
+2 -2
grep.c
··· 1263 */ 1264 show_line_header(opt, name, lno, cno, sign); 1265 } 1266 - if (opt->color || opt->only_matching) { 1267 regmatch_t match; 1268 enum grep_context ctx = GREP_CONTEXT_BODY; 1269 int eflags = 0; 1270 1271 - if (opt->color) { 1272 if (sign == ':') 1273 match_color = opt->colors[GREP_COLOR_MATCH_SELECTED]; 1274 else
··· 1263 */ 1264 show_line_header(opt, name, lno, cno, sign); 1265 } 1266 + if (want_color(opt->color) || opt->only_matching) { 1267 regmatch_t match; 1268 enum grep_context ctx = GREP_CONTEXT_BODY; 1269 int eflags = 0; 1270 1271 + if (want_color(opt->color)) { 1272 if (sign == ':') 1273 match_color = opt->colors[GREP_COLOR_MATCH_SELECTED]; 1274 else
+2 -2
grep.h
··· 159 int pathname; 160 int null_following_name; 161 int only_matching; 162 - int color; 163 int max_depth; 164 int funcname; 165 int funcbody; ··· 198 [GREP_COLOR_SEP] = GIT_COLOR_CYAN, \ 199 }, \ 200 .only_matching = 0, \ 201 - .color = -1, \ 202 .output = std_output, \ 203 } 204
··· 159 int pathname; 160 int null_following_name; 161 int only_matching; 162 + enum git_colorbool color; 163 int max_depth; 164 int funcname; 165 int funcbody; ··· 198 [GREP_COLOR_SEP] = GIT_COLOR_CYAN, \ 199 }, \ 200 .only_matching = 0, \ 201 + .color = GIT_COLOR_UNKNOWN, \ 202 .output = std_output, \ 203 } 204
+2 -2
log-tree.c
··· 57 [DECORATION_GRAFTED] = "grafted", 58 }; 59 60 - static const char *decorate_get_color(int decorate_use_color, enum decoration_type ix) 61 { 62 if (want_color(decorate_use_color)) 63 return decoration_colors[ix]; ··· 341 */ 342 void format_decorations(struct strbuf *sb, 343 const struct commit *commit, 344 - int use_color, 345 const struct decoration_options *opts) 346 { 347 const struct name_decoration *decoration;
··· 57 [DECORATION_GRAFTED] = "grafted", 58 }; 59 60 + static const char *decorate_get_color(enum git_colorbool decorate_use_color, enum decoration_type ix) 61 { 62 if (want_color(decorate_use_color)) 63 return decoration_colors[ix]; ··· 341 */ 342 void format_decorations(struct strbuf *sb, 343 const struct commit *commit, 344 + enum git_colorbool use_color, 345 const struct decoration_options *opts) 346 { 347 const struct name_decoration *decoration;
+3 -1
log-tree.h
··· 1 #ifndef LOG_TREE_H 2 #define LOG_TREE_H 3 4 struct rev_info; 5 6 struct log_info { ··· 26 int log_tree_commit(struct rev_info *, struct commit *); 27 void show_log(struct rev_info *opt); 28 void format_decorations(struct strbuf *sb, const struct commit *commit, 29 - int use_color, const struct decoration_options *opts); 30 void show_decorations(struct rev_info *opt, struct commit *commit); 31 void log_write_email_headers(struct rev_info *opt, struct commit *commit, 32 char **extra_headers_p,
··· 1 #ifndef LOG_TREE_H 2 #define LOG_TREE_H 3 4 + #include "color.h" 5 + 6 struct rev_info; 7 8 struct log_info { ··· 28 int log_tree_commit(struct rev_info *, struct commit *); 29 void show_log(struct rev_info *opt); 30 void format_decorations(struct strbuf *sb, const struct commit *commit, 31 + enum git_colorbool use_color, const struct decoration_options *opts); 32 void show_decorations(struct rev_info *opt, struct commit *commit); 33 void log_write_email_headers(struct rev_info *opt, struct commit *commit, 34 char **extra_headers_p,
+2 -2
parse-options-cb.c
··· 50 int parse_opt_color_flag_cb(const struct option *opt, const char *arg, 51 int unset) 52 { 53 - int value; 54 55 if (!arg) 56 arg = unset ? "never" : (const char *)opt->defval; 57 value = git_config_colorbool(NULL, arg); 58 - if (value < 0) 59 return error(_("option `%s' expects \"always\", \"auto\", or \"never\""), 60 opt->long_name); 61 *(int *)opt->value = value;
··· 50 int parse_opt_color_flag_cb(const struct option *opt, const char *arg, 51 int unset) 52 { 53 + enum git_colorbool value; 54 55 if (!arg) 56 arg = unset ? "never" : (const char *)opt->defval; 57 value = git_config_colorbool(NULL, arg); 58 + if (value == GIT_COLOR_UNKNOWN) 59 return error(_("option `%s' expects \"always\", \"auto\", or \"never\""), 60 opt->long_name); 61 *(int *)opt->value = value;
+6 -6
pretty.c
··· 470 471 static void append_line_with_color(struct strbuf *sb, struct grep_opt *opt, 472 const char *line, size_t linelen, 473 - int color, enum grep_context ctx, 474 enum grep_header_field field) 475 { 476 const char *buf, *eol, *line_color, *match_color; ··· 899 const char *message; 900 char *commit_encoding; 901 size_t width, indent1, indent2; 902 - int auto_color; 903 int padding; 904 905 /* These offsets are relative to the start of the commit message. */ ··· 1455 switch (placeholder[0]) { 1456 case 'C': 1457 if (starts_with(placeholder + 1, "(auto)")) { 1458 - c->auto_color = want_color(c->pretty_ctx->color); 1459 - if (c->auto_color && sb->len) 1460 strbuf_addstr(sb, GIT_COLOR_RESET); 1461 return 7; /* consumed 7 bytes, "C(auto)" */ 1462 } else { 1463 int ret = parse_color(sb, placeholder, c); 1464 if (ret) 1465 - c->auto_color = 0; 1466 /* 1467 * Otherwise, we decided to treat %C<unknown> 1468 * as a literal string, and the previous ··· 2167 } 2168 2169 static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt, 2170 - int color, int tabwidth, const char *line, 2171 int linelen) 2172 { 2173 const char *tab;
··· 470 471 static void append_line_with_color(struct strbuf *sb, struct grep_opt *opt, 472 const char *line, size_t linelen, 473 + enum git_colorbool color, enum grep_context ctx, 474 enum grep_header_field field) 475 { 476 const char *buf, *eol, *line_color, *match_color; ··· 899 const char *message; 900 char *commit_encoding; 901 size_t width, indent1, indent2; 902 + enum git_colorbool auto_color; 903 int padding; 904 905 /* These offsets are relative to the start of the commit message. */ ··· 1455 switch (placeholder[0]) { 1456 case 'C': 1457 if (starts_with(placeholder + 1, "(auto)")) { 1458 + c->auto_color = c->pretty_ctx->color; 1459 + if (want_color(c->auto_color) && sb->len) 1460 strbuf_addstr(sb, GIT_COLOR_RESET); 1461 return 7; /* consumed 7 bytes, "C(auto)" */ 1462 } else { 1463 int ret = parse_color(sb, placeholder, c); 1464 if (ret) 1465 + c->auto_color = GIT_COLOR_NEVER; 1466 /* 1467 * Otherwise, we decided to treat %C<unknown> 1468 * as a literal string, and the previous ··· 2167 } 2168 2169 static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt, 2170 + enum git_colorbool color, int tabwidth, const char *line, 2171 int linelen) 2172 { 2173 const char *tab;
+2 -1
pretty.h
··· 3 4 #include "date.h" 5 #include "string-list.h" 6 7 struct commit; 8 struct repository; ··· 46 struct rev_info *rev; 47 const char *output_encoding; 48 struct string_list *mailmap; 49 - int color; 50 struct ident_split *from_ident; 51 unsigned encode_email_headers:1; 52 struct pretty_print_describe_status *describe_status;
··· 3 4 #include "date.h" 5 #include "string-list.h" 6 + #include "color.h" 7 8 struct commit; 9 struct repository; ··· 47 struct rev_info *rev; 48 const char *output_encoding; 49 struct string_list *mailmap; 50 + enum git_colorbool color; 51 struct ident_split *from_ident; 52 unsigned encode_email_headers:1; 53 struct pretty_print_describe_status *describe_status;
+2 -2
ref-filter.h
··· 95 const char *format; 96 const char *rest; 97 int quote_style; 98 - int use_color; 99 100 /* Internal state to ref-filter */ 101 int need_color_reset_at_eol; ··· 111 .exclude = STRVEC_INIT, \ 112 } 113 #define REF_FORMAT_INIT { \ 114 - .use_color = -1, \ 115 } 116 117 /* Macros for checking --merged and --no-merged options */
··· 95 const char *format; 96 const char *rest; 97 int quote_style; 98 + enum git_colorbool use_color; 99 100 /* Internal state to ref-filter */ 101 int need_color_reset_at_eol; ··· 111 .exclude = STRVEC_INIT, \ 112 } 113 #define REF_FORMAT_INIT { \ 114 + .use_color = GIT_COLOR_UNKNOWN, \ 115 } 116 117 /* Macros for checking --merged and --no-merged options */
+3 -3
sideband.c
··· 27 }; 28 29 /* Returns a color setting (GIT_COLOR_NEVER, etc). */ 30 - static int use_sideband_colors(void) 31 { 32 - static int use_sideband_colors_cached = -1; 33 34 const char *key = "color.remote"; 35 struct strbuf sb = STRBUF_INIT; 36 const char *value; 37 int i; 38 39 - if (use_sideband_colors_cached >= 0) 40 return use_sideband_colors_cached; 41 42 if (!repo_config_get_string_tmp(the_repository, key, &value))
··· 27 }; 28 29 /* Returns a color setting (GIT_COLOR_NEVER, etc). */ 30 + static enum git_colorbool use_sideband_colors(void) 31 { 32 + static enum git_colorbool use_sideband_colors_cached = GIT_COLOR_UNKNOWN; 33 34 const char *key = "color.remote"; 35 struct strbuf sb = STRBUF_INIT; 36 const char *value; 37 int i; 38 39 + if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN) 40 return use_sideband_colors_cached; 41 42 if (!repo_config_get_string_tmp(the_repository, key, &value))
+1 -1
transport.c
··· 30 #include "color.h" 31 #include "bundle-uri.h" 32 33 - static int transport_use_color = -1; 34 static char transport_colors[][COLOR_MAXLEN] = { 35 GIT_COLOR_RESET, 36 GIT_COLOR_RED /* REJECTED */
··· 30 #include "color.h" 31 #include "bundle-uri.h" 32 33 + static enum git_colorbool transport_use_color = GIT_COLOR_UNKNOWN; 34 static char transport_colors[][COLOR_MAXLEN] = { 35 GIT_COLOR_RESET, 36 GIT_COLOR_RED /* REJECTED */
+3 -3
wt-status.c
··· 148 memcpy(s->color_palette, default_wt_status_colors, 149 sizeof(default_wt_status_colors)); 150 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; 151 - s->use_color = -1; 152 s->relative_paths = 1; 153 s->branch = refs_resolve_refdup(get_main_ref_store(the_repository), 154 "HEAD", 0, NULL, NULL); ··· 1165 * before. 1166 */ 1167 if (s->fp != stdout) { 1168 - rev.diffopt.use_color = 0; 1169 wt_status_add_cut_line(s); 1170 } 1171 if (s->verbose > 1 && s->committable) { ··· 2155 2156 static void wt_porcelain_print(struct wt_status *s) 2157 { 2158 - s->use_color = 0; 2159 s->relative_paths = 0; 2160 s->prefix = NULL; 2161 s->no_gettext = 1;
··· 148 memcpy(s->color_palette, default_wt_status_colors, 149 sizeof(default_wt_status_colors)); 150 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; 151 + s->use_color = GIT_COLOR_UNKNOWN; 152 s->relative_paths = 1; 153 s->branch = refs_resolve_refdup(get_main_ref_store(the_repository), 154 "HEAD", 0, NULL, NULL); ··· 1165 * before. 1166 */ 1167 if (s->fp != stdout) { 1168 + rev.diffopt.use_color = GIT_COLOR_NEVER; 1169 wt_status_add_cut_line(s); 1170 } 1171 if (s->verbose > 1 && s->committable) { ··· 2155 2156 static void wt_porcelain_print(struct wt_status *s) 2157 { 2158 + s->use_color = GIT_COLOR_NEVER; 2159 s->relative_paths = 0; 2160 s->prefix = NULL; 2161 s->no_gettext = 1;
+1 -1
wt-status.h
··· 111 int amend; 112 enum commit_whence whence; 113 int nowarn; 114 - int use_color; 115 int no_gettext; 116 int display_comment_prefix; 117 int relative_paths;
··· 111 int amend; 112 enum commit_whence whence; 113 int nowarn; 114 + enum git_colorbool use_color; 115 int no_gettext; 116 int display_comment_prefix; 117 int relative_paths;