From: "René Scharfe" <l.s.r@web.de>
To: Junio C Hamano <gitster@pobox.com>,
Laszlo Ersek <laszlo.ersek@posteo.net>
Cc: git@vger.kernel.org
Subject: Re: git-blame vs. abbrev
Date: Tue, 30 Jun 2026 23:38:43 +0200 [thread overview]
Message-ID: <f9761389-8c31-4928-babf-8218e9393376@web.de> (raw)
In-Reply-To: <xmqqy0fvreps.fsf@gitster.g>
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)
--
2.54.0
next prev parent reply other threads:[~2026-06-30 21:38 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 [this message]
2026-07-01 8:45 ` Laszlo Ersek
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=f9761389-8c31-4928-babf-8218e9393376@web.de \
--to=l.s.r@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=laszlo.ersek@posteo.net \
/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