"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: got log -b path gets confused by merge commits
To:
James Cook <falsifian@falsifian.org>
Cc:
gameoftrees@openbsd.org
Date:
Mon, 29 Jan 2024 15:07:43 +0100

Download raw body.

Thread
On Sun, Jan 28, 2024 at 06:34:17PM +0000, James Cook wrote:
> I've managed to trigger the error
> 
> 	got: //d/g: no such entry found in tree
> 
> by running got log -b d/g or tog log -b d/g in a specially crafted repo.

Thanks! This is an edge case I had overlooked.
Below is a fix which I tested manually. Does it work for you?

The patch repeats an if-condition in a slightly awkward way because the
diff becomes easier to read, avoiding indentation of a lot of lines by
one more level. Essentially we need to guard the STAILQ_FOREACH loop
with if (merged_id != NULL).

> I have a script (at bottom) to reproduce and am happy to turn that into a
> patch for regress/cmdline.

Yes, please do turn it into a regression test if you have time.

-----------------------------------------------
 handle merge commits that are unrelated to requested changed path history
 
diff d4fbd6eb2ce77846055692cfe05c18e8fabe2dca e845bc35a6589b3076ef0ab0a37c85532a4c6fba
commit - d4fbd6eb2ce77846055692cfe05c18e8fabe2dca
commit + e845bc35a6589b3076ef0ab0a37c85532a4c6fba
blob - 60e80af88cd8b83c0792aa2a88a615267cd87994
blob + 7838410468b039613a6a79dd0f886d3a3f4d77c9
--- lib/commit_graph.c
+++ lib/commit_graph.c
@@ -254,6 +254,7 @@ advance_branch(struct got_commit_graph *graph, struct 
 {
 	const struct got_error *err;
 	struct got_object_qid *qid;
+	struct got_object_id *merged_id = NULL;
 
 	err = close_branch(graph, commit_id);
 	if (err)
@@ -289,13 +290,16 @@ advance_branch(struct got_commit_graph *graph, struct 
 	 * which do not contribute any content to this path.
 	 */
 	if (commit->nparents > 1 && !got_path_is_root_dir(graph->path)) {
-		struct got_object_id *merged_id, *prev_id = NULL;
+		err = got_object_id_by_path(&merged_id, repo, commit, graph->path);
+		if (err && err->code != GOT_ERR_NO_TREE_ENTRY)
+			return err;
+		/* The requested path does not exist in this merge commit. */
+	}
+	if (commit->nparents > 1 && !got_path_is_root_dir(graph->path) &&
+	    merged_id != NULL) {
+		struct got_object_id *prev_id = NULL;
 		int branches_differ = 0;
 
-		err = got_object_id_by_path(&merged_id, repo, commit,
-		    graph->path);
-		if (err)
-			return err;
 
 		STAILQ_FOREACH(qid, &commit->parent_ids, entry) {
 			struct got_object_id *id = NULL;