1

Is it possible to easily trim the newline when displaying a note with %N with git log?

I would like to include metadata about a commit by adding it with git-notes and viewing it with something like:

git log --format=format:'%h [%N] %an %s %D'

This seems much cleaner than creating commit messages with meta-data prefixed as is common practice these days, but it seems that there is always a trailing newline on the note.

Any suggestions on how to easily remove it without filtering through external tools?

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Sigh. "We will end the annotation by a newline anyway" https://github.com/git/git/blob/2807bd2c10606e590886543afe4e4f208dddd489/notes.c#L1288-L1309 Looks like there is no convenient way to do this at the present time. – William Pursell Apr 27 '23 at 16:39
  • 1
    This could be accomplished if the metadata was in a trailer (in the commit message) instead of a note. – Guildenstern Apr 29 '23 at 00:01
  • @Guildenstern Brilliant! Using a trailer is definitely cleaner. – William Pursell Apr 29 '23 at 03:29

2 Answers2

2

Use %N%-C().

%N you know. The - in %-C() means "strip immediately-preceding newlines if this is empty", and the empty color spec C() is empty.

From comments:

OP was using %<(20,trunc)%N, and notes by default have an explicitly-encoded trailing newline that the formatter does not strip—so a ten-byte note will have a newline eleventh byte and then the fixed-width will pad that out to 20 bytes with spaces . . . and %-C() will see the immediately-preceding space and do nothing.

One workaround for this OP found: use %>(20,trunc) instead, short notes will be right-aligned so the trailing newline will always appear there.

Another was suggested by @Guildenstern in a comment on the question: use a trailer instead, whose value doesn't notionally include the embedded trailing newline.

git notes will supply any "missing" trailing newline to an added note, even from a file; to create a no-trailing-newline note yourself you have to create the blob manually and create it with the premade object, but even then git log's formatter will add it back. So it looks like rj is pretty much the only option if you want to format the data in a fixed-width field and keep the flexibility advantage notes offer over trailers.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • This works well with just `%N`, but behaves a bit strangely with `%<(20,trunc)%N%-C()`. If the note does not fit in the width but gets truncated, the newline is stripped. But if the notes fits completely, the newline is not stripped. – William Pursell Apr 29 '23 at 03:05
  • The same issue happens when truncating with a trailer using `[%<(10,trunc)%(trailers:key=meta,valueonly)%-C()]`. Perhaps I'm using `trunc` incorrectly. – William Pursell Apr 29 '23 at 03:31
  • Some testing says the newline is part of the notes text, not added by `git log`, so it looks like the fixed-width processing is adding spaces *after* the newline, making it no longer a trailing newline. You could postprocess for it, `%<(20,trunc)%N%xff | sed -Ez 's,(\n *)?\xff,,g',` yes? – jthill Apr 29 '23 at 04:16
  • Adding filters is doable, but is an extra layer of complexity I'm hoping to avoid. I'm trying to find a simple solution to encourage people to stop doing this: https://www.conventionalcommits.org/en/v1.0.0-beta.2/ Something like `%-*C()` would be nice (strip all preceding trailing whitespace), but does not seem to exist yet. – William Pursell Apr 29 '23 at 04:32
  • It does seem to me metadata that could usefully fit in such a short fixed field is a better match for trailer tags, as [@Guildenstern suggests](https://stackoverflow.com/questions/76120184/remove-trailing-newline-from-n-format-specifier-in-git-log/76133983?noredirect=1#comment134266179_76120184). – jthill Apr 29 '23 at 04:57
  • Yes, trailers certainly seems more appropriate. And `%>()` instead of `trunc` works well with `%-C()` Thanks! – William Pursell Apr 29 '23 at 05:07
  • @WilliamPursell “I'm trying to find a simple solution to encourage people to stop doing this:”—I’m glad to hear it. :·) I don’t like how that standard front-loads the metadata so much (and the metadata itself is of limited value outside of automatic version bumps). I hope you’re able to convince people. :·) – Guildenstern Apr 29 '23 at 20:39
1

It looks like current git does not support this, but the following patch seems to work:

diff --git a/notes.c b/notes.c
index 02f1aa39ae..21001b2261 100644
--- a/notes.c
+++ b/notes.c
@@ -1306,7 +1306,9 @@ static void format_note(struct notes_tree *t, const struct object_id *object_oid
                if (!raw)
                        strbuf_addstr(sb, "    ");
                strbuf_add(sb, msg_p, linelen);
-               strbuf_addch(sb, '\n');
+               if (!raw) {
+                       strbuf_addch(sb, '\n');
+               }
        }
 
        free(msg);
William Pursell
  • 204,365
  • 48
  • 270
  • 300