Merge branch 'nd/log-graph-configurable-colors'

Some people feel the default set of colors used by "git log --graph"
rather limiting.  A mechanism to customize the set of colors has
been introduced.

* nd/log-graph-configurable-colors:
  document behavior of empty color name
  color_parse_mem: allow empty color spec
  log --graph: customize the graph lines with config log.graphColors
  color.c: trim leading spaces in color_parse_mem()
  color.c: fix color_parse_mem() with value_len == 0
This commit is contained in:
Junio C Hamano 2017-02-02 13:36:58 -08:00
commit 85279e8649
6 changed files with 97 additions and 5 deletions

View File

@ -170,6 +170,9 @@ The position of any attributes with respect to the colors
be turned off by prefixing them with `no` or `no-` (e.g., `noreverse`,
`no-ul`, etc).
+
An empty color string produces no color effect at all. This can be used
to avoid coloring specific elements without disabling color entirely.
+
For git's pre-defined color slots, the attributes are meant to be reset
at the beginning of each item in the colored output. So setting
`color.decorate.branch` to `black` will paint that branch name in a
@ -2036,6 +2039,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.

12
color.c
View File

@ -207,7 +207,17 @@ int color_parse_mem(const char *value, int value_len, char *dst)
struct color fg = { COLOR_UNSPECIFIED };
struct color bg = { COLOR_UNSPECIFIED };
if (!strncasecmp(value, "reset", len)) {
while (len > 0 && isspace(*ptr)) {
ptr++;
len--;
}
if (!len) {
dst[0] = '\0';
return 0;
}
if (!strncasecmp(ptr, "reset", len)) {
xsnprintf(dst, end - dst, GIT_COLOR_RESET);
return 0;
}

40
graph.c
View File

@ -3,6 +3,7 @@
#include "color.h"
#include "graph.h"
#include "revision.h"
#include "argv-array.h"
/* Internal API */
@ -79,6 +80,26 @@ static void graph_show_line_prefix(const struct diff_options *diffopt)
static const char **column_colors;
static unsigned short column_colors_max;
static void parse_graph_colors_config(struct argv_array *colors, const char *string)
{
const char *end, *start;
start = string;
end = string + strlen(string);
while (start < end) {
const char *comma = strchrnul(start, ',');
char color[COLOR_MAXLEN];
if (!color_parse_mem(start, comma - start, color))
argv_array_push(colors, color);
else
warning(_("ignore invalid color '%.*s' in log.graphColors"),
(int)(comma - start), start);
start = comma + 1;
}
argv_array_push(colors, GIT_COLOR_RESET);
}
void graph_set_column_colors(const char **colors, unsigned short colors_max)
{
column_colors = colors;
@ -238,9 +259,22 @@ 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);
if (!column_colors) {
char *string;
if (git_config_get_string("log.graphcolors", &string)) {
/* not configured -- use default */
graph_set_column_colors(column_colors_ansi,
column_colors_ansi_max);
} else {
static struct argv_array custom_colors = ARGV_ARRAY_INIT;
argv_array_clear(&custom_colors);
parse_graph_colors_config(&custom_colors, string);
free(string);
/* graph_set_column_colors takes a max-index, not a count */
graph_set_column_colors(custom_colors.argv,
custom_colors.argc - 1);
}
}
graph->commit = NULL;
graph->revs = opt;

View File

@ -380,4 +380,18 @@ test_expect_success 'patch mode ignores unmerged entries' '
test_cmp expected diff
'
test_expect_success 'diffs can be colorized' '
git reset --hard &&
# force color even though the test script has no terminal
test_config color.ui always &&
echo content >test &&
printf y | git add -p >output 2>&1 &&
# We do not want to depend on the exact coloring scheme
# git uses for diffs, so just check that we saw some kind of color.
grep "$(printf "\\033")" output
'
test_done

View File

@ -6,10 +6,11 @@
test_description='Test diff/status color escape codes'
. ./test-lib.sh
ESC=$(printf '\033')
color()
{
actual=$(git config --get-color no.such.slot "$1") &&
test "$actual" = "$2"
test "$actual" = "${2:+$ESC}$2"
}
invalid_color()
@ -21,6 +22,10 @@ test_expect_success 'reset' '
color "reset" "[m"
'
test_expect_success 'empty color is empty' '
color "" ""
'
test_expect_success 'attribute before color name' '
color "bold red" "[1;31m"
'

View File

@ -359,6 +359,28 @@ test_expect_success 'log --graph --line-prefix="| | | " 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,invalid-color, 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