If you have a 256 colors terminal (or one with true color support), then the predefined 12 colors seem limited. On the other hand, you don't want to draw graph lines with every single color in this mode because the two colors could look extremely similar. This option allows you to hand pick the colors you want. Even with standard terminal, if your background color is neither black or white, then the graph line may match your background and become hidden. You can exclude your background color (or simply the colors you hate) with this. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Compared to v2: * set_column_colors_by_config() is renamed to set_column_colors() * no memory leak if the function is called the second time * proper space trimming since color_parse_mem expects so * fixed the warning message, giving some context * at least one test to exercise the code * I'm not going with the cumulative behavior because I think that's just harder to manage colors, and we would need a way to remove colors from the config too. Documentation/config.txt | 4 ++++ graph.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- t/t4202-log.sh | 22 ++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 0bcb679..33a007b 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2003,6 +2003,10 @@ log.follow:: i.e. it cannot be used to follow multiple files and does not work well on non-linear history. +log.graphColors:: + A list of colors, separated by commas, that can be used to draw + history lines in `git log --graph`. + log.showRoot:: If true, the initial commit will be shown as a big creation event. This is equivalent to a diff against an empty tree. diff --git a/graph.c b/graph.c index dd17201..048f5cb 100644 --- a/graph.c +++ b/graph.c @@ -62,6 +62,49 @@ enum graph_state { static const char **column_colors; static unsigned short column_colors_max; +static void set_column_colors(void) +{ + static char **colors; + static int colors_max, colors_alloc; + char *string = NULL; + const char *end, *start; + int i; + + for (i = 0; i < colors_max; i++) + free(colors[i]); + if (colors) + free(colors[colors_max]); + colors_max = 0; + + if (git_config_get_string("log.graphcolors", &string)) { + graph_set_column_colors(column_colors_ansi, + column_colors_ansi_max); + return; + } + + start = string; + end = string + strlen(string); + while (start < end) { + const char *comma = strchrnul(start, ','); + char color[COLOR_MAXLEN]; + + while (start < comma && isspace(*start)) + start++; + + if (!color_parse_mem(start, comma - start, color)) { + ALLOC_GROW(colors, colors_max + 1, colors_alloc); + colors[colors_max++] = xstrdup(color); + } else + warning(_("ignore invalid color '%.*s' in log.graphColors"), + (int)(comma - start), start); + start = comma + 1; + } + free(string); + ALLOC_GROW(colors, colors_max + 1, colors_alloc); + colors[colors_max] = xstrdup(GIT_COLOR_RESET); + graph_set_column_colors((const char **)colors, colors_max); +} + void graph_set_column_colors(const char **colors, unsigned short colors_max) { column_colors = colors; @@ -208,8 +251,7 @@ struct git_graph *graph_init(struct rev_info *opt) struct git_graph *graph = xmalloc(sizeof(struct git_graph)); if (!column_colors) - graph_set_column_colors(column_colors_ansi, - column_colors_ansi_max); + set_column_colors(); graph->commit = NULL; graph->revs = opt; diff --git a/t/t4202-log.sh b/t/t4202-log.sh index e2db47c..afe0715 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -313,6 +313,28 @@ test_expect_success 'log --graph with merge' ' test_cmp expect actual ' +cat > expect.colors <<\EOF +* Merge branch 'side' +<BLUE>|<RESET><CYAN>\<RESET> +<BLUE>|<RESET> * side-2 +<BLUE>|<RESET> * side-1 +* <CYAN>|<RESET> Second +* <CYAN>|<RESET> sixth +* <CYAN>|<RESET> fifth +* <CYAN>|<RESET> fourth +<CYAN>|<RESET><CYAN>/<RESET> +* third +* second +* initial +EOF + +test_expect_success 'log --graph with merge with log.graphColors' ' + test_config log.graphColors " blue , cyan , red " && + git log --color=always --graph --date-order --pretty=tformat:%s | + test_decode_color | sed "s/ *\$//" >actual && + test_cmp expect.colors actual +' + test_expect_success 'log --raw --graph -m with merge' ' git log --raw --graph --oneline -m master | head -n 500 >actual && grep "initial" actual -- 2.8.2.524.g6ff3d78