When ignoring commits, the commit that is blamed might not be responsible for the change. Users might want to know when a particular line has a potentially inaccurate blame. This patch adds a config option to identify these lines by specifying blame.markIgnoredFiles. When this option is set, each blame line is marked with an '*'. For example: 278b6158d6fdb (Barret Rhoden 2016-04-11 13:57:54 -0400 26) appears as: *278b6158d6fd (Barret Rhoden 2016-04-11 13:57:54 -0400 26) where the '*' is placed before the commit, and the hash has one fewer characters. Signed-off-by: Barret Rhoden <brho@xxxxxxxxxx> --- Documentation/config/blame.txt | 4 ++++ blame.c | 4 ++++ blame.h | 1 + builtin/blame.c | 9 +++++++++ 4 files changed, 18 insertions(+) diff --git a/Documentation/config/blame.txt b/Documentation/config/blame.txt index 4da2788f306d..9f7f0fcf42c9 100644 --- a/Documentation/config/blame.txt +++ b/Documentation/config/blame.txt @@ -26,3 +26,7 @@ blame.ignoreRevsFile:: `#` are ignored. This option may be repeated multiple times. Empty file names will reset the list of ignored revisions. This option will be handled before the command line option `--ignore-revs-file`. + +blame.markIgnoredLines:: + Mark lines that were changed by an ignored revision with a '*' in the + output of linkgit:git-blame[1]. diff --git a/blame.c b/blame.c index 4427cde95dc5..34debdba1a7f 100644 --- a/blame.c +++ b/blame.c @@ -480,6 +480,7 @@ void blame_coalesce(struct blame_scoreboard *sb) for (ent = sb->ent; ent && (next = ent->next); ent = next) { if (ent->suspect == next->suspect && ent->s_lno + ent->num_lines == next->s_lno && + ent->ignored == next->ignored && ent->unblamable == next->unblamable) { ent->num_lines += next->num_lines; ent->next = next->next; @@ -732,6 +733,7 @@ static void split_overlap(struct blame_entry *split, int chunk_end_lno; memset(split, 0, sizeof(struct blame_entry [3])); + split[0].ignored = split[1].ignored = split[2].ignored = e->ignored; split[0].unblamable = e->unblamable; split[1].unblamable = e->unblamable; split[2].unblamable = e->unblamable; @@ -854,6 +856,7 @@ static struct blame_entry *split_blame_at(struct blame_entry *e, int len, struct blame_entry *n = xcalloc(1, sizeof(struct blame_entry)); n->suspect = new_suspect; + n->ignored = e->ignored; n->unblamable = e->unblamable; n->lno = e->lno + len; n->s_lno = e->s_lno + len; @@ -951,6 +954,7 @@ static void blame_chunk(struct blame_entry ***dstq, struct blame_entry ***srcq, blame_origin_decref(e->suspect); e->suspect = blame_origin_incref(parent); e->s_lno += offset; + e->ignored = 1; /* The top part of any ignored diff will not exist in * the parent, and we will never be able to accurately * blame it. We'll keep it on the blame list for the diff --git a/blame.h b/blame.h index 91664913d7c4..53df8b4c5b3f 100644 --- a/blame.h +++ b/blame.h @@ -92,6 +92,7 @@ struct blame_entry { * scanning the lines over and over. */ unsigned score; + int ignored; int unblamable; }; diff --git a/builtin/blame.c b/builtin/blame.c index 5f38e9dccddd..46d96905de75 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -53,6 +53,7 @@ static int show_progress; static char repeated_meta_color[COLOR_MAXLEN]; static int coloring_mode; static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP; +static int mark_ignored_lines; static struct date_mode blame_date_mode = { DATE_ISO8601 }; static size_t blame_date_width; @@ -482,6 +483,10 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int } } + if (mark_ignored_lines && ent->ignored) { + length--; + putchar('*'); + } if (ent->unblamable) memset(hex, '0', length); printf("%.*s", length, hex); @@ -710,6 +715,10 @@ static int git_blame_config(const char *var, const char *value, void *cb) string_list_insert(&ignore_revs_file_list, str); return 0; } + if (!strcmp(var, "blame.markignoredlines")) { + mark_ignored_lines = git_config_bool(var, value); + return 0; + } if (!strcmp(var, "color.blame.repeatedlines")) { if (color_parse_mem(value, strlen(value), repeated_meta_color)) warning(_("invalid color '%s' in color.blame.repeatedLines"), -- 2.21.0.rc0.258.g878e2cd30e-goog