Subject: Re: [PATCH] notes: remove trailing whitespace from editor template

From: Junio C Hamano <[email-masked]>
Date: Tue, 27 May 2025 15:22:53 -0700

Junio C Hamano <[email-masked]> writes:

> It probably should be a fairly isolated change, like the way how
> the expand_tabs_in_log bit is handled in pretty.c; give another
> bit and teach pp_handle_indent to return when that bit is set and
> the payload it was asked to show with indentation is empty, or
> something like that.

An unconditional change based on the above idea may look like the
attached patch.

No tests, no docs, no configuration, and I will not be working on
this in immediate future.  On top of what we can see here, probably
the following would need to happen before we can call it completed.

 - "git notes" should take a command line option to control which
   one of "--indent-empty-lines" or "--no-indent-empty-lines" is
   passed.  Optionally, we can introduce a new configuration
   variable notes.something to control the same.

 - "git log" and "git show", but not "git rev-list" plumbing, may
   want to start paying attention to a new configuration variable
   log.indentEmptyLines (which defaults to "yes" if not specified).

   I am not sure if we want to do this item; as there is no explicit
   end-user request to add such a feature, I am inclined to say no,
   at least not as a part of the "while editing notes with 'git
   notes add -e' the shortlog ends up with lines that are commented
   out with trailing whitespaces, which upsets some editors" topic.
   But it should be trivial to do.

 - documentation.

 - tests.

I've only compiled and then manually tested

    $ GIT_EXEC_PATH=$(pwd) ./git notes add -e

to see how the commented out "git show -s" output embedded in the
editor buffer looked like.

 builtin/log.c   | 1 +
 builtin/notes.c | 3 ++-
 log-tree.c      | 1 +
 pretty.c        | 8 +++++---
 pretty.h        | 1 +
 revision.c      | 4 ++++
 revision.h      | 2 ++
 7 files changed, 16 insertions(+), 4 deletions(-)

diff --git c/builtin/log.c w/builtin/log.c
index b450cd3bde..dc2d7d3a07 100644
--- c/builtin/log.c
+++ w/builtin/log.c
@@ -2148,6 +2148,7 @@ int cmd_format_patch(int argc,
 	rev.commit_format = CMIT_FMT_EMAIL;
 	rev.encode_email_headers = cfg.log.default_encode_email_headers;
 	rev.expand_tabs_in_log_default = 0;
+	rev.indent_empty_lines = 1;
 	rev.verbose_header = 1;
 	rev.diff = 1;
 	rev.max_parents = 1;
diff --git c/builtin/notes.c w/builtin/notes.c
index a3f433ca4c..b559b39cf0 100644
--- c/builtin/notes.c
+++ w/builtin/notes.c
@@ -167,7 +167,8 @@ static void write_commented_object(int fd, const struct object_id *object)
 	struct strbuf cbuf = STRBUF_INIT;
 
 	/* Invoke "git show --stat --no-notes $object" */
-	strvec_pushl(&show.args, "show", "--stat", "--no-notes",
+	strvec_pushl(&show.args, "show", "--stat",
+		     "--no-indent-empty-lines", "--no-notes",
 		     oid_to_hex(object), NULL);
 	show.no_stdin = 1;
 	show.out = -1;
diff --git c/log-tree.c w/log-tree.c
index 1d05dc1c70..e8ea2481ea 100644
--- c/log-tree.c
+++ w/log-tree.c
@@ -879,6 +879,7 @@ void show_log(struct rev_info *opt)
 	ctx.mailmap = opt->mailmap;
 	ctx.color = opt->diffopt.use_color;
 	ctx.expand_tabs_in_log = opt->expand_tabs_in_log;
+	ctx.indent_empty_lines = opt->indent_empty_lines;
 	ctx.output_encoding = get_log_output_encoding();
 	ctx.rev = opt;
 	if (opt->from_ident.mail_begin && opt->from_ident.name_begin)
diff --git c/pretty.c w/pretty.c
index 0bc8ad8a9a..4974af4d02 100644
--- c/pretty.c
+++ w/pretty.c
@@ -2247,13 +2247,14 @@ void pp_remainder(struct pretty_print_context *pp,
 
 	for (;;) {
 		const char *line = *msg_p;
+		int is_blank = 0;
 		int linelen = get_one_line(line);
 		*msg_p += linelen;
 
 		if (!linelen)
 			break;
-
-		if (is_blank_line(line, &linelen)) {
+		is_blank = is_blank_line(line, &linelen);
+		if (is_blank) {
 			if (first)
 				continue;
 			if (pp->fmt == CMIT_FMT_SHORT)
@@ -2262,7 +2263,8 @@ void pp_remainder(struct pretty_print_context *pp,
 		first = 0;
 
 		strbuf_grow(sb, linelen + indent + 20);
-		if (indent)
+
+		if (indent && (!is_blank || pp->indent_empty_lines))
 			pp_handle_indent(pp, sb, indent, line, linelen);
 		else if (pp->expand_tabs_in_log)
 			strbuf_add_tabexpand(sb, opt, pp->color,
diff --git c/pretty.h w/pretty.h
index df267afe4a..21e584e185 100644
--- c/pretty.h
+++ w/pretty.h
@@ -40,6 +40,7 @@ struct pretty_print_context {
 	struct date_mode date_mode;
 	unsigned date_mode_explicit:1;
 	int expand_tabs_in_log;
+	int indent_empty_lines;
 	int need_8bit_cte;
 	char *notes_message;
 	struct reflog_walk_info *reflog_info;
diff --git c/revision.c w/revision.c
index 2c36a9c179..ae6b98e701 100644
--- c/revision.c
+++ w/revision.c
@@ -2564,6 +2564,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
 		revs->verbose_header = 1;
 		revs->pretty_given = 1;
 		get_commit_format(optarg, revs);
+	} else if (!strcmp(arg, "--no-indent-empty-lines")) {
+		revs->indent_empty_lines = 0;
+	} else if (!strcmp(arg, "--indent-empty-lines")) {
+		revs->indent_empty_lines = 1;
 	} else if (!strcmp(arg, "--expand-tabs")) {
 		revs->expand_tabs_in_log = 8;
 	} else if (!strcmp(arg, "--no-expand-tabs")) {
diff --git c/revision.h w/revision.h
index 6d369cdad6..49b123387f 100644
--- c/revision.h
+++ w/revision.h
@@ -278,6 +278,7 @@ struct rev_info {
 	struct date_mode date_mode;
 	int		expand_tabs_in_log; /* unset if negative */
 	int		expand_tabs_in_log_default;
+	int		indent_empty_lines;
 
 	unsigned int	abbrev;
 	enum cmit_fmt	commit_format;
@@ -412,6 +413,7 @@ struct rev_info {
 	.expand_tabs_in_log = -1, \
 	.commit_format = CMIT_FMT_DEFAULT, \
 	.expand_tabs_in_log_default = 8, \
+	.indent_empty_lines = 1, \
 }
 
 /**