git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/5] refs: trim newline from reflog message

From
Han-Wen Nienhuys via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 6, 2021, 16:52 UTC
Message-ID
<995d450da42f35b4cecdd699fa1b1a74518f481e.1630947142.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1067.v2.git.git.1630947142.gitgitgadget@gmail.com>
From: Han-Wen Nienhuys <hanwen@google.com>

Commit 523fa69c ("reflog: cleanse messages in the refs.c layer") standardizes how write entries into the reflog. This commit standardizes how we get messages out of the reflog. Before, the files backend implicitly added '\n' to the end of reflog message on reading, which creates a subtle incompatibility with alternate ref storage backends, such as reftable.

We address this by stripping LF from the message before we pass it to the user-provided callback.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
 builtin/show-branch.c          |  4 +++-
 reflog-walk.c                  |  6 ++----
 refs/files-backend.c           | 30 +++++++++++++++---------------
 t/t1405-main-ref-store.sh      |  5 ++---
 t/t1406-submodule-ref-store.sh |  4 ++--
 5 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index d77ce7aeb38..acf710313a0 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -888,7 +888,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
 				show_one_commit(rev[i], 1);
 			}
 			else
-				puts(reflog_msg[i]);
+				puts(reflog_msg[i]); /* XXX - this puts a
+							newline. Did we put two
+							newlines beforehand? */
 
 			if (is_head)
 				head_at = i;
diff --git a/reflog-walk.c b/reflog-walk.c
index e9cd3283694..944cce929c8 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -245,8 +245,6 @@ void get_reflog_message(struct strbuf *sb,
 
 	info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 	len = strlen(info->message);
-	if (len > 0)
-		len--; /* strip away trailing newline */
 	strbuf_add(sb, info->message, len);
 }
 
@@ -285,10 +283,10 @@ void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
 		info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
 		get_reflog_selector(&selector, reflog_info, dmode, force_date, 0);
 		if (oneline) {
-			printf("%s: %s", selector.buf, info->message);
+			printf("%s: %s\n", selector.buf, info->message);
 		}
 		else {
-			printf("Reflog: %s (%s)\nReflog message: %s",
+			printf("Reflog: %s (%s)\nReflog message: %s\n",
 			       selector.buf, info->email, info->message);
 		}
 
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 677b7e4cdd2..206c9f8b932 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1897,17 +1897,15 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
 	int tz;
 	const char *p = sb->buf;
 
-	/* old SP new SP name <email> SP time TAB msg LF */
-	if (!sb->len || sb->buf[sb->len - 1] != '\n' ||
-	    parse_oid_hex(p, &ooid, &p) || *p++ != ' ' ||
+	/* old SP new SP name <email> SP time TAB msg */
+	if (!sb->len || parse_oid_hex(p, &ooid, &p) || *p++ != ' ' ||
 	    parse_oid_hex(p, &noid, &p) || *p++ != ' ' ||
-	    !(email_end = strchr(p, '>')) ||
-	    email_end[1] != ' ' ||
+	    !(email_end = strchr(p, '>')) || email_end[1] != ' ' ||
 	    !(timestamp = parse_timestamp(email_end + 2, &message, 10)) ||
 	    !message || message[0] != ' ' ||
-	    (message[1] != '+' && message[1] != '-') ||
-	    !isdigit(message[2]) || !isdigit(message[3]) ||
-	    !isdigit(message[4]) || !isdigit(message[5]))
+	    (message[1] != '+' && message[1] != '-') || !isdigit(message[2]) ||
+	    !isdigit(message[3]) || !isdigit(message[4]) ||
+	    !isdigit(message[5]))
 		return 0; /* corrupt? */
 	email_end[1] = '\0';
 	tz = strtol(message + 1, NULL, 10);
@@ -1999,6 +1997,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
 				strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1));
 				scanp = bp;
 				endp = bp + 1;
+				strbuf_trim_trailing_newline(&sb);
 				ret = show_one_reflog_ent(&sb, fn, cb_data);
 				strbuf_reset(&sb);
 				if (ret)
@@ -2011,6 +2010,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
 				 * Process it, and we can end the loop.
 				 */
 				strbuf_splice(&sb, 0, 0, buf, endp - buf);
+				strbuf_trim_trailing_newline(&sb);
 				ret = show_one_reflog_ent(&sb, fn, cb_data);
 				strbuf_reset(&sb);
 				break;
@@ -2060,7 +2060,7 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store,
 	if (!logfp)
 		return -1;
 
-	while (!ret && !strbuf_getwholeline(&sb, logfp, '\n'))
+	while (!ret && !strbuf_getline(&sb, logfp))
 		ret = show_one_reflog_ent(&sb, fn, cb_data);
 	fclose(logfp);
 	strbuf_release(&sb);
@@ -3020,18 +3020,18 @@ static int expire_reflog_ent(struct object_id *ooid, struct object_id *noid,
 	if ((*cb->should_prune_fn)(ooid, noid, email, timestamp, tz,
 				   message, policy_cb)) {
 		if (!cb->newlog)
-			printf("would prune %s", message);
+			printf("would prune %s\n", message);
 		else if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
-			printf("prune %s", message);
+			printf("prune %s\n", message);
 	} else {
 		if (cb->newlog) {
-			fprintf(cb->newlog, "%s %s %s %"PRItime" %+05d\t%s",
-				oid_to_hex(ooid), oid_to_hex(noid),
-				email, timestamp, tz, message);
+			fprintf(cb->newlog, "%s %s %s %" PRItime " %+05d\t%s\n",
+				oid_to_hex(ooid), oid_to_hex(noid), email,
+				timestamp, tz, message);
 			oidcpy(&cb->last_kept_oid, noid);
 		}
 		if (cb->flags & EXPIRE_REFLOGS_VERBOSE)
-			printf("keep %s", message);
+			printf("keep %s\n", message);
 	}
 	return 0;
 }
diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh
index 49718b7ea7f..a600bedf2cd 100755
--- a/t/t1405-main-ref-store.sh
+++ b/t/t1405-main-ref-store.sh
@@ -89,13 +89,12 @@ test_expect_success 'for_each_reflog()' '
 test_expect_success 'for_each_reflog_ent()' '
 	$RUN for-each-reflog-ent HEAD >actual &&
 	head -n1 actual | grep one &&
-	tail -n2 actual | head -n1 | grep recreate-main
+	tail -n1 actual | grep recreate-main
 '
 
 test_expect_success 'for_each_reflog_ent_reverse()' '
 	$RUN for-each-reflog-ent-reverse HEAD >actual &&
-	head -n1 actual | grep recreate-main &&
-	tail -n2 actual | head -n1 | grep one
+	tail -n1 actual | grep one
 '
 
 test_expect_success 'reflog_exists(HEAD)' '
diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh
index 0a87058971e..b0365c1fee0 100755
--- a/t/t1406-submodule-ref-store.sh
+++ b/t/t1406-submodule-ref-store.sh
@@ -74,13 +74,13 @@ test_expect_success 'for_each_reflog()' '
 test_expect_success 'for_each_reflog_ent()' '
 	$RUN for-each-reflog-ent HEAD >actual &&
 	head -n1 actual | grep first &&
-	tail -n2 actual | head -n1 | grep main.to.new
+	tail -n1 actual | grep main.to.new
 '
 
 test_expect_success 'for_each_reflog_ent_reverse()' '
 	$RUN for-each-reflog-ent-reverse HEAD >actual &&
 	head -n1 actual | grep main.to.new &&
-	tail -n2 actual | head -n1 | grep first
+	tail -n1 actual | grep first
 '
 
 test_expect_success 'reflog_exists(HEAD)' '
-- 
gitgitgadget
Previous: Han-Wen Nienhuys via GitGitGadgetNext: Ævar Arnfjörð Bjarmason
Message 16 of 40 in “Gets rid of "if reflog exists, append to it regardless of config settings"”
  1. 0/4 Gets rid of "if reflog exists, append to it regardless of config settings"Han-Wen Nienhuys via GitGitGadget, Aug 30, 2021
  2. 1/4 test-ref-store: tweaks to for-each-reflog-ent formatHan-Wen Nienhuys via GitGitGadget, Aug 30, 2021
  3. Taylor BlauAug 30, 2021
  4. Taylor BlauAug 30, 2021
  5. Junio C HamanoAug 30, 2021
  6. Taylor BlauAug 30, 2021
  7. Junio C HamanoAug 30, 2021
  8. 2/4 t1400: use test-helper ref-store to inspect reflog contentsHan-Wen Nienhuys via GitGitGadget, Aug 30, 2021
  9. Junio C HamanoAug 30, 2021
  10. 3/4 refs: drop force_create argument of create_reflog APIHan-Wen Nienhuys via GitGitGadget, Aug 30, 2021
  11. Junio C HamanoAug 30, 2021
  12. 4/4 RFC: refs: reflog entries aren't written based on reflog existence.Han-Wen Nienhuys via GitGitGadget, Aug 30, 2021
  13. Taylor BlauAug 30, 2021
  14. Junio C HamanoAug 30, 2021
  15. 0/5 Gets rid of "if reflog exists, append to it regardless of config settings"Han-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  16. 1/5 refs: trim newline from reflog messageHan-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  17. Ævar Arnfjörð BjarmasonSep 6, 2021
  18. 2/5 test-ref-store: tweaks to for-each-reflog-ent formatHan-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  19. Ævar Arnfjörð BjarmasonSep 6, 2021
  20. Han-Wen NienhuysSep 7, 2021
  21. Ævar Arnfjörð BjarmasonSep 7, 2021
  22. 3/5 t1400: use test-helper ref-store to inspect reflog contentsHan-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  23. 4/5 refs: drop force_create argument of create_reflog APIHan-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  24. Ævar Arnfjörð BjarmasonSep 6, 2021
  25. 5/5 RFC: refs: reflog entries aren't written based on reflog existence.Han-Wen Nienhuys via GitGitGadget, Sep 6, 2021
  26. Ævar Arnfjörð BjarmasonSep 6, 2021
  27. 0/7 Gets rid of "if reflog exists, append to it regardless of config settings"Han-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  28. 1/7 show-branch: show reflog messageHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  29. 5/7 refs: drop force_create argument of create_reflog APIHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  30. 2/7 refs: trim newline from reflog messageHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  31. 3/7 test-ref-store: tweaks to for-each-reflog-ent formatHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  32. 6/7 RFC: refs: reflog entries aren't written based on reflog existence.Han-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  33. 4/7 t1400: use test-helper ref-store to inspect reflog contentsHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  34. 7/7 refs: change log_ref_setup calling conventionHan-Wen Nienhuys via GitGitGadget, Sep 7, 2021
  35. Han-Wen NienhuysOct 5, 2021
  36. Junio C HamanoOct 6, 2021
  37. Junio C HamanoOct 6, 2021
  38. Junio C HamanoOct 7, 2021
  39. Han-Wen NienhuysNov 11, 2021
  40. Ævar Arnfjörð BjarmasonNov 11, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.