Skip to content

Commit cdc2d5f

Browse files
stefanbellergitster
authored andcommitted
builtin/blame: dim uninteresting metadata lines
When using git-blame lots of lines contain redundant information, for example in hunks that consist of multiple lines, the metadata (commit name, author, date) are repeated. A reader may not be interested in those, so offer an option to color the information that is repeated from the previous line differently. Traditionally, we use CYAN for lines that are less interesting than others (e.g. hunk header), so go with that. The command line option '--color-lines' will trigger the coloring of repeated lines, and the config option 'color.blame.colorLines' is provided to select the color. Setting the config option doesn't imply that repeated lines are colored. A later patch will introduce a config to enable this mode by default. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 75e5e9c commit cdc2d5f

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

Documentation/config.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,11 @@ color.status.<slot>::
12181218
status short-format), or
12191219
`unmerged` (files which have unmerged changes).
12201220

1221+
color.blame.repeatedLines::
1222+
Use the customized color for the part of git-blame output that
1223+
is repeated meta information per line (such as commit id,
1224+
author name, date and timezone). Defaults to cyan.
1225+
12211226
color.ui::
12221227
This variable determines the default value for variables such
12231228
as `color.diff` and `color.grep` that control the use of color

builtin/blame.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "cache.h"
99
#include "config.h"
10+
#include "color.h"
1011
#include "builtin.h"
1112
#include "commit.h"
1213
#include "diff.h"
@@ -46,6 +47,7 @@ static int xdl_opts;
4647
static int abbrev = -1;
4748
static int no_whole_file_rename;
4849
static int show_progress;
50+
static char repeated_meta_color[COLOR_MAXLEN];
4951

5052
static struct date_mode blame_date_mode = { DATE_ISO8601 };
5153
static size_t blame_date_width;
@@ -316,10 +318,11 @@ static const char *format_time(timestamp_t time, const char *tz_str,
316318
#define OUTPUT_PORCELAIN 010
317319
#define OUTPUT_SHOW_NAME 020
318320
#define OUTPUT_SHOW_NUMBER 040
319-
#define OUTPUT_SHOW_SCORE 0100
320-
#define OUTPUT_NO_AUTHOR 0200
321+
#define OUTPUT_SHOW_SCORE 0100
322+
#define OUTPUT_NO_AUTHOR 0200
321323
#define OUTPUT_SHOW_EMAIL 0400
322-
#define OUTPUT_LINE_PORCELAIN 01000
324+
#define OUTPUT_LINE_PORCELAIN 01000
325+
#define OUTPUT_COLOR_LINE 02000
323326

324327
static void emit_porcelain_details(struct blame_origin *suspect, int repeat)
325328
{
@@ -375,6 +378,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
375378
struct commit_info ci;
376379
char hex[GIT_MAX_HEXSZ + 1];
377380
int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
381+
const char *color = NULL, *reset = NULL;
378382

379383
get_commit_info(suspect->commit, &ci, 1);
380384
oid_to_hex_r(hex, &suspect->commit->object.oid);
@@ -384,6 +388,18 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
384388
char ch;
385389
int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ : abbrev;
386390

391+
if (opt & OUTPUT_COLOR_LINE) {
392+
if (cnt > 0) {
393+
color = repeated_meta_color;
394+
reset = GIT_COLOR_RESET;
395+
} else {
396+
color = NULL;
397+
reset = NULL;
398+
}
399+
}
400+
if (color)
401+
fputs(color, stdout);
402+
387403
if (suspect->commit->object.flags & UNINTERESTING) {
388404
if (blank_boundary)
389405
memset(hex, ' ', length);
@@ -433,6 +449,8 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
433449
printf(" %*d) ",
434450
max_digits, ent->lno + 1 + cnt);
435451
}
452+
if (reset)
453+
fputs(reset, stdout);
436454
do {
437455
ch = *cp++;
438456
putchar(ch);
@@ -607,6 +625,12 @@ static int git_blame_config(const char *var, const char *value, void *cb)
607625
parse_date_format(value, &blame_date_mode);
608626
return 0;
609627
}
628+
if (!strcmp(var, "color.blame.repeatedlines")) {
629+
if (color_parse_mem(value, strlen(value), repeated_meta_color))
630+
warning(_("invalid color '%s' in color.blame.repeatedLines"),
631+
value);
632+
return 0;
633+
}
610634

611635
if (git_diff_heuristic_config(var, value, cb) < 0)
612636
return -1;
@@ -681,6 +705,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
681705
OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
682706
OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
683707
OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
708+
OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),
684709

685710
/*
686711
* The following two options are parsed by parse_revision_opt()
@@ -940,8 +965,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
940965

941966
blame_coalesce(&sb);
942967

943-
if (!(output_option & OUTPUT_PORCELAIN))
968+
if (!(output_option & OUTPUT_PORCELAIN)) {
944969
find_alignment(&sb, &output_option);
970+
if (!*repeated_meta_color &&
971+
(output_option & OUTPUT_COLOR_LINE))
972+
strcpy(repeated_meta_color, GIT_COLOR_CYAN);
973+
}
974+
if (output_option & OUTPUT_ANNOTATE_COMPAT)
975+
output_option &= ~OUTPUT_COLOR_LINE;
945976

946977
output(&sb, output_option);
947978
free((void *)sb.final_buf);

t/t8012-blame-colors.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
3+
test_description='colored git blame'
4+
. ./test-lib.sh
5+
6+
PROG='git blame -c'
7+
. "$TEST_DIRECTORY"/annotate-tests.sh
8+
9+
test_expect_success 'colored blame colors contiguous lines' '
10+
git -c color.blame.repeatedLines=yellow blame --color-lines --abbrev=12 hello.c >actual.raw &&
11+
test_decode_color <actual.raw >actual &&
12+
grep "<YELLOW>" <actual >darkened &&
13+
grep "(F" darkened > F.expect &&
14+
grep "(H" darkened > H.expect &&
15+
test_line_count = 2 F.expect &&
16+
test_line_count = 3 H.expect
17+
'
18+
19+
test_done

0 commit comments

Comments
 (0)