Git development
 help / color / mirror / Atom feed
From: Laszlo Ersek <laszlo.ersek@posteo.net>
To: "René Scharfe" <l.s.r@web.de>, "Junio C Hamano" <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: Re: git-blame vs. abbrev
Date: Wed, 01 Jul 2026 08:45:33 +0000	[thread overview]
Message-ID: <7146f6a0-89aa-41bb-b187-4fc456b0c7da@posteo.net> (raw)
In-Reply-To: <f9761389-8c31-4928-babf-8218e9393376@web.de>

On 6/30/26 23:38, René Scharfe wrote:
> On 6/30/26 9:49 PM, Junio C Hamano wrote:
>> Laszlo Ersek <laszlo.ersek@posteo.net> writes:
>>
>>> Hi,
>>>
>>> when git-blame is passed the "-b" option ("Show blank SHA-1 for boundary
>>> commits"), shouldn't git-blame *stop* reserving a commit hash nibble for
>>> the caret that otherwise marks boundary commits?
>>>
>>> More directly, I find it inconvenient that git-blame shows commit hashes
>>> that are one nibble longer (13) than my "core.abbrev" (12) setting;
>>
>> Just for the sake of aesthetics, I agree that when we are not
>> showing the boundary mark, it would make sense not to reserve one
>> column that we know we will never use.
> Here's a patch to reserve a column only if marks are actually shown.
> 
> I strongly suspect that any line can only have a single mark, but I
> didn't bother checking and proving whether that's actually true; the
> new code should be able to handle multiple marks just fine.
> 
> Misses tests.
> 
> René
> 
> 
> ---
>   builtin/blame.c | 61 ++++++++++++++++++++++++++++++++++---------------
>   1 file changed, 42 insertions(+), 19 deletions(-)
> 
> diff --git a/builtin/blame.c b/builtin/blame.c
> index ffbd3ce5c5..0e747a43f2 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -453,6 +453,39 @@ static void determine_line_heat(struct commit_info *ci, const char **dest_color)
>   	*dest_color = colorfield[i].col;
>   }
>   
> +static size_t handle_marks(const struct blame_entry *ent, int opt, bool print)
> +{
> +	size_t len = 0;
> +
> +	if ((ent->suspect->commit->object.flags & UNINTERESTING) &&
> +	    !blank_boundary && !(opt & OUTPUT_ANNOTATE_COMPAT)) {
> +		if (print)
> +			putchar('^');
> +		len++;
> +	}
> +	if (mark_unblamable_lines && ent->unblamable) {
> +		if (print)
> +			putchar('*');
> +		len++;
> +	}
> +	if (mark_ignored_lines && ent->ignored) {
> +		if (print)
> +			putchar('?');
> +		len++;
> +	}
> +	return len;
> +}
> +
> +static size_t print_marks(const struct blame_entry *ent, int opt)
> +{
> +	return handle_marks(ent, opt, true);
> +}
> +
> +static size_t count_marks(const struct blame_entry *ent, int opt)
> +{
> +	return handle_marks(ent, opt, false);
> +}
> +
>   static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent,
>   		       int opt, struct blame_entry *prev_ent)
>   {
> @@ -499,23 +532,10 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent,
>   		if (color)
>   			fputs(color, stdout);
>   
> -		if (suspect->commit->object.flags & UNINTERESTING) {
> -			if (blank_boundary) {
> -				memset(hex, ' ', strlen(hex));
> -			} else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
> -				length--;
> -				putchar('^');
> -			}
> -		}
> -
> -		if (mark_unblamable_lines && ent->unblamable) {
> -			length--;
> -			putchar('*');
> -		}
> -		if (mark_ignored_lines && ent->ignored) {
> -			length--;
> -			putchar('?');
> -		}
> +		if ((suspect->commit->object.flags & UNINTERESTING) &&
> +		    blank_boundary)
> +			memset(hex, ' ', strlen(hex));
> +		length -= print_marks(ent, opt);
>   
>   		printf("%.*s", (int)(length < GIT_MAX_HEXSZ ? length : GIT_MAX_HEXSZ), hex);
>   		if (opt & OUTPUT_ANNOTATE_COMPAT) {
> @@ -647,11 +667,15 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)
>   	struct blame_entry *e;
>   	int compute_auto_abbrev = (abbrev < 0);
>   	int auto_abbrev = DEFAULT_ABBREV;
> +	size_t max_marks_count = 0;
>   
>   	for (e = sb->ent; e; e = e->next) {
>   		struct blame_origin *suspect = e->suspect;
>   		int num;
> +		size_t marks_count = count_marks(e, *option);
>   
> +		if (max_marks_count < marks_count)
> +			max_marks_count = marks_count;
>   		if (compute_auto_abbrev)
>   			auto_abbrev = update_auto_abbrev(auto_abbrev, suspect);
>   		if (strcmp(suspect->path, sb->path))
> @@ -685,8 +709,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)
>   	max_score_digits = decimal_width(largest_score);
>   
>   	if (compute_auto_abbrev)
> -		/* one more abbrev length is needed for the boundary commit */
> -		abbrev = auto_abbrev + 1;
> +		abbrev = auto_abbrev + max_marks_count;
>   }
>   
>   static void sanity_check_on_fail(struct blame_scoreboard *sb, int baa)

This way, I didn't even need to pass "-b". :)

I didn't try to test the patch exhaustively, but it definitely does what 
I'm after.

Tested-by: Laszlo Ersek <laszlo.ersek@posteo.net>

Thank you!
Laszlo

  reply	other threads:[~2026-07-01  8:45 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-30 11:15 git-blame vs. abbrev Laszlo Ersek
2026-06-30 19:49 ` Junio C Hamano
2026-06-30 20:32   ` Laszlo Ersek
2026-06-30 21:24     ` Junio C Hamano
2026-07-01  8:43       ` Laszlo Ersek
2026-06-30 21:38   ` René Scharfe
2026-07-01  8:45     ` Laszlo Ersek [this message]
2026-07-06  8:38 ` [PATCH] blame: reserve mark column only if necessary René Scharfe
2026-07-06 20:33   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7146f6a0-89aa-41bb-b187-4fc456b0c7da@posteo.net \
    --to=laszlo.ersek@posteo.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=l.s.r@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox