This lets you use something like this in your $GIT_DIR/config file. [diff] color = auto [diff.color] new = blue old = yellow frag = reverse When diff.color is set to "auto", colored diff is enabled when the standard output is the terminal. Other choices are "always", and "never". Usual boolean true/false can also be used. The colormap entries can specify colors for the following slots: plain - lines that appear in both old and new file (context) meta - diff --git header and extended git diff headers frag - @@ -n,m +l,k @@ lines (hunk header) old - lines deleted from old file new - lines added to new file The following color names can be used: normal, bold, dim, l, blink, reverse, reset, black, red, green, yellow, blue, magenta, cyan, white Signed-off-by: Junio C Hamano <junkio@xxxxxxx> --- Linus Torvalds <torvalds@xxxxxxxx> writes: > Which just means that we should have some way to let people set their own > colors. At the source level it is easy to specify color and attribute combinations (e.g. "bold|red") by having the preprocessor concatenate string literals, but I was too lazy to allow that from the configuration level. People might want to have that, though. BTW, while doing this, I noticed that the patch does not do the color output for combined diffs. Care to look into it after Timo's output format series settles? cache.h | 1 - diff.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/cache.h b/cache.h index efeafea..3502fee 100644 --- a/cache.h +++ b/cache.h @@ -181,7 +181,6 @@ extern int assume_unchanged; extern int prefer_symlink_refs; extern int log_all_ref_updates; extern int warn_ambiguous_refs; -extern int diff_rename_limit_default; extern int shared_repository; extern const char *apply_default_whitespace; diff --git a/diff.c b/diff.c index 1db0285..33c8c57 100644 --- a/diff.c +++ b/diff.c @@ -13,17 +13,8 @@ #include "xdiff-interface.h" static int use_size_cache; -int diff_rename_limit_default = -1; - -int git_diff_config(const char *var, const char *value) -{ - if (!strcmp(var, "diff.renamelimit")) { - diff_rename_limit_default = git_config_int(var, value); - return 0; - } - - return git_default_config(var, value); -} +static int diff_rename_limit_default = -1; +static int diff_use_color_default = 0; enum color_diff { DIFF_RESET = 0, @@ -51,9 +42,6 @@ #define COLOR_MAGENTA "\033[35m" #define COLOR_CYAN "\033[36m" #define COLOR_WHITE "\033[37m" -#define COLOR_CYANBG "\033[46m" -#define COLOR_GRAYBG "\033[47m" // Good for xterm - static const char *diff_colors[] = { [DIFF_RESET] = COLOR_RESET, [DIFF_PLAIN] = COLOR_NORMAL, @@ -63,6 +51,83 @@ static const char *diff_colors[] = { [DIFF_FILE_NEW] = COLOR_GREEN, }; +static int parse_diff_color_slot(const char *var, int ofs) +{ + if (!strcasecmp(var+ofs, "plain")) + return DIFF_PLAIN; + if (!strcasecmp(var+ofs, "meta")) + return DIFF_METAINFO; + if (!strcasecmp(var+ofs, "frag")) + return DIFF_FRAGINFO; + if (!strcasecmp(var+ofs, "old")) + return DIFF_FILE_OLD; + if (!strcasecmp(var+ofs, "new")) + return DIFF_FILE_NEW; + die("bad config variable '%s'", var); +} + +static const char *parse_diff_color_value(const char *value, const char *var) +{ + if (!strcasecmp(value, "normal")) + return COLOR_NORMAL; + if (!strcasecmp(value, "bold")) + return COLOR_BOLD; + if (!strcasecmp(value, "dim")) + return COLOR_DIM; + if (!strcasecmp(value, "ul")) + return COLOR_UL; + if (!strcasecmp(value, "blink")) + return COLOR_BLINK; + if (!strcasecmp(value, "reverse")) + return COLOR_REVERSE; + if (!strcasecmp(value, "reset")) + return COLOR_RESET; + if (!strcasecmp(value, "black")) + return COLOR_BLACK; + if (!strcasecmp(value, "red")) + return COLOR_RED; + if (!strcasecmp(value, "green")) + return COLOR_GREEN; + if (!strcasecmp(value, "yellow")) + return COLOR_YELLOW; + if (!strcasecmp(value, "blue")) + return COLOR_BLUE; + if (!strcasecmp(value, "magenta")) + return COLOR_MAGENTA; + if (!strcasecmp(value, "cyan")) + return COLOR_CYAN; + if (!strcasecmp(value, "white")) + return COLOR_WHITE; + die("bad config value '%s' for variable '%s'", value, var); +} + +int git_diff_config(const char *var, const char *value) +{ + if (!strcmp(var, "diff.renamelimit")) { + diff_rename_limit_default = git_config_int(var, value); + return 0; + } + if (!strcmp(var, "diff.color")) { + if (!value) + diff_use_color_default = 1; /* bool */ + else if (!strcasecmp(value, "auto")) + diff_use_color_default = isatty(1); + else if (!strcasecmp(value, "never")) + diff_use_color_default = 0; + else if (!strcasecmp(value, "always")) + diff_use_color_default = 1; + else + diff_use_color_default = git_config_bool(var, value); + return 0; + } + if (!strncmp(var, "diff.color.", 11)) { + int slot = parse_diff_color_slot(var, 11); + diff_colors[slot] = parse_diff_color_value(value, var); + return 0; + } + return git_default_config(var, value); +} + static char *quote_one(const char *str) { int needlen; @@ -1362,6 +1427,7 @@ void diff_setup(struct diff_options *opt options->change = diff_change; options->add_remove = diff_addremove; + options->color_diff = diff_use_color_default; } int diff_setup_done(struct diff_options *options) -- 1.4.1.rc1.ga77b7 - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html