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

[PATCH] reflog: continue walking the reflog past root commits

From
SZEDER Gábor <szeder@ira.uka.de>
Date
Jun 3, 2016, 20:42 UTC
Message-ID
<20160603204235.7994-1-szeder@ira.uka.de>
In-Reply-To
<f51f9df7-d6d7-3a45-736f-ca2e2c9eb2cb@textalk.se>

If a repository contains more than one root commit, then its HEAD reflog may contain multiple "creation events", i.e. entries whose "from" value is the null sha1. Listing such a reflog currently stops prematurely at the first such entry, even when the reflog still contains older entries. This can scare users into thinking that their reflog got truncated after 'git checkout --orphan'.

Continue walking the reflog past such creation evens based on the preceeding reflog entry's "new" value.

The test 'symbolic-ref writes reflog entry' in t1401-symbolic-ref implicitly relies on the current behavior of the reflog walker to stop at a root commit and thus to list only the reflog entries that are relevant for that test. Adjust the test to explicitly specify the number of relevant reflog entries to be listed.

Reported-by: Patrik Gustafsson <pvn@textalk.se>
Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
---
 reflog-walk.c           |  6 ++++++
 t/t1401-symbolic-ref.sh |  2 +-
 t/t1410-reflog.sh       | 22 ++++++++++++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/reflog-walk.c b/reflog-walk.c
index 0ebd1da5ceb8..a246af27678a 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -241,6 +241,12 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 		logobj = parse_object(reflog->osha1);
 	} while (commit_reflog->recno && (logobj && logobj->type != OBJ_COMMIT));
 
+	if (!logobj && commit_reflog->recno >= 0 && is_null_sha1(reflog->osha1)) {
+		/* a root commit, but there are still more entries to show */
+		reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
+		logobj = parse_object(reflog->nsha1);
+	}
+
 	if (!logobj || logobj->type != OBJ_COMMIT) {
 		commit_info->commit = NULL;
 		commit->parents = NULL;
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index 417eecc3af2a..ca3fa406c34f 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -110,7 +110,7 @@ test_expect_success 'symbolic-ref writes reflog entry' '
 	update
 	create
 	EOF
-	git log --format=%gs -g >actual &&
+	git log --format=%gs -g -2 >actual &&
 	test_cmp expect actual
 '
 
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 9cf91dc6d217..dd2be049ecf6 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -348,4 +348,26 @@ test_expect_success 'reflog expire operates on symref not referrent' '
 	git reflog expire --expire=all the_symref
 '
 
+test_expect_success 'continue walking past root commits' '
+	git init orphanage &&
+	(
+		cd orphanage &&
+		cat >expect <<-\EOF &&
+		HEAD@{0} commit (initial): orphan2-1
+		HEAD@{1} commit: orphan1-2
+		HEAD@{2} commit (initial): orphan1-1
+		HEAD@{3} commit (initial): initial
+		EOF
+		test_commit initial &&
+		git reflog &&
+		git checkout --orphan orphan1 &&
+		test_commit orphan1-1 &&
+		test_commit orphan1-2 &&
+		git checkout --orphan orphan2 &&
+		test_commit orphan2-1 &&
+		git log -g --format="%gd %gs" >actual &&
+		test_cmp expect actual
+	)
+'
+
 test_done
-- 
2.9.0.rc1.66.ge2c3978
Previous: SZEDER GáborNext: Eric Sunshine
Message 3 of 4 in “--orphan erases HEAD reflog”
  1. Patrik GustafssonJun 3, 2016
  2. SZEDER GáborJun 3, 2016
  3. reflog: continue walking the reflog past root commitsSZEDER Gábor, Jun 3, 2016
  4. Eric SunshineJun 4, 2016

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.