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

[PATCH v3 02/11] Prepare `repo_in_merge_bases_many()` to optionally expect missing commits

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Feb 27, 2024, 13:28 UTC
Message-ID
<f68d77c612398368f860592a756b95c4d64d3b53.1709040499.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1657.v3.git.1709040497.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>

Currently this function treats unrelated commit histories the same way as commit histories with missing commit objects.

Typically, missing commit objects constitute a corrupt repository, though, and should be reported as such. The next commits will make it so, but there is one exception: In `git fetch --update-shallow` we _expect_ commit objects to be missing, and we do want to treat the now-incomplete commit histories as unrelated.

To allow for that, let's introduce an additional parameter that is passed to `repo_in_merge_bases_many()` to trigger this behavior, and use it in the two callers in `shallow.c`.

This commit changes behavior slightly: unless called from the `shallow.c` functions that set the `ignore_missing_commits` bit, any non-existing tip commit that is passed to `repo_in_merge_bases_many()` will now result in an error.

Note: When encountering missing commits while traversing the commit
history in search for merge bases, with this commit there won't be a
change in behavior just yet, their children will still be interpreted as
root commits. This bug will get fixed by follow-up commits.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 commit-reach.c        | 9 +++++----
 commit-reach.h        | 3 ++-
 remote.c              | 2 +-
 shallow.c             | 5 +++--
 t/helper/test-reach.c | 2 +-
 5 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/commit-reach.c b/commit-reach.c
index 7ea916f9ebd..5c1b5256598 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -467,7 +467,7 @@ int repo_is_descendant_of(struct repository *r,
 
 			other = with_commit->item;
 			with_commit = with_commit->next;
-			if (repo_in_merge_bases_many(r, other, 1, &commit))
+			if (repo_in_merge_bases_many(r, other, 1, &commit, 0))
 				return 1;
 		}
 		return 0;
@@ -478,17 +478,18 @@ int repo_is_descendant_of(struct repository *r,
  * Is "commit" an ancestor of one of the "references"?
  */
 int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
-			     int nr_reference, struct commit **reference)
+			     int nr_reference, struct commit **reference,
+			     int ignore_missing_commits)
 {
 	struct commit_list *bases;
 	int ret = 0, i;
 	timestamp_t generation, max_generation = GENERATION_NUMBER_ZERO;
 
 	if (repo_parse_commit(r, commit))
-		return ret;
+		return ignore_missing_commits ? 0 : -1;
 	for (i = 0; i < nr_reference; i++) {
 		if (repo_parse_commit(r, reference[i]))
-			return ret;
+			return ignore_missing_commits ? 0 : -1;
 
 		generation = commit_graph_generation(reference[i]);
 		if (generation > max_generation)
diff --git a/commit-reach.h b/commit-reach.h
index 35c4da49481..68f81549a44 100644
--- a/commit-reach.h
+++ b/commit-reach.h
@@ -30,7 +30,8 @@ int repo_in_merge_bases(struct repository *r,
 			struct commit *reference);
 int repo_in_merge_bases_many(struct repository *r,
 			     struct commit *commit,
-			     int nr_reference, struct commit **reference);
+			     int nr_reference, struct commit **reference,
+			     int ignore_missing_commits);
 
 /*
  * Takes a list of commits and returns a new list where those
diff --git a/remote.c b/remote.c
index abb24822beb..763c80f4a7d 100644
--- a/remote.c
+++ b/remote.c
@@ -2675,7 +2675,7 @@ static int is_reachable_in_reflog(const char *local, const struct ref *remote)
 		if (MERGE_BASES_BATCH_SIZE < size)
 			size = MERGE_BASES_BATCH_SIZE;
 
-		if ((ret = repo_in_merge_bases_many(the_repository, commit, size, chunk)))
+		if ((ret = repo_in_merge_bases_many(the_repository, commit, size, chunk, 0)))
 			break;
 	}
 
diff --git a/shallow.c b/shallow.c
index ac728cdd778..dfcc1f86a7f 100644
--- a/shallow.c
+++ b/shallow.c
@@ -797,7 +797,7 @@ static void post_assign_shallow(struct shallow_info *info,
 		for (j = 0; j < bitmap_nr; j++)
 			if (bitmap[0][j] &&
 			    /* Step 7, reachability test at commit level */
-			    !repo_in_merge_bases_many(the_repository, c, ca.nr, ca.commits)) {
+			    !repo_in_merge_bases_many(the_repository, c, ca.nr, ca.commits, 1)) {
 				update_refstatus(ref_status, info->ref->nr, *bitmap);
 				dst++;
 				break;
@@ -828,7 +828,8 @@ int delayed_reachability_test(struct shallow_info *si, int c)
 		si->reachable[c] = repo_in_merge_bases_many(the_repository,
 							    commit,
 							    si->nr_commits,
-							    si->commits);
+							    si->commits,
+							    1);
 		si->need_reachability_test[c] = 0;
 	}
 	return si->reachable[c];
diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c
index 3e173399a00..aa816e168ea 100644
--- a/t/helper/test-reach.c
+++ b/t/helper/test-reach.c
@@ -113,7 +113,7 @@ int cmd__reach(int ac, const char **av)
 		       repo_in_merge_bases(the_repository, A, B));
 	else if (!strcmp(av[1], "in_merge_bases_many"))
 		printf("%s(A,X):%d\n", av[1],
-		       repo_in_merge_bases_many(the_repository, A, X_nr, X_array));
+		       repo_in_merge_bases_many(the_repository, A, X_nr, X_array, 0));
 	else if (!strcmp(av[1], "is_descendant_of"))
 		printf("%s(A,X):%d\n", av[1], repo_is_descendant_of(r, A, X));
 	else if (!strcmp(av[1], "get_merge_bases_many")) {
-- 
gitgitgadget
Previous: Johannes Schindelin via GitGitGadgetNext: Johannes Schindelin via GitGitGadget
Message 34 of 70 in “The merge-base logic vs missing commit objects”
  1. 00/12 The merge-base logic vs missing commit objectsJohannes Schindelin via GitGitGadget, Feb 13, 2024
  2. 01/12 paint_down_to_common: plug a memory leakJohannes Schindelin via GitGitGadget, Feb 13, 2024
  3. 02/12 Let `repo_in_merge_bases()` report missing commitsJohannes Schindelin via GitGitGadget, Feb 13, 2024
  4. Patrick SteinhardtFeb 15, 2024
  5. 03/12 Prepare `repo_in_merge_bases_many()` to optionally expect missing commitsJohannes Schindelin via GitGitGadget, Feb 13, 2024
  6. 04/12 Prepare `paint_down_to_common()` for handling shallow commitsJohannes Schindelin via GitGitGadget, Feb 13, 2024
  7. 05/12 commit-reach: start reporting errors in `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  8. 06/12 merge_bases_many(): pass on errors from `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  9. 07/12 get_merge_bases_many_0(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  10. 08/12 repo_get_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  11. 09/12 get_octopus_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  12. 10/12 repo_get_merge_bases_many(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  13. 11/12 repo_get_merge_bases_many_dirty(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 13, 2024
  14. 12/12 paint_down_to_common(): special-case shallow/partial clonesJohannes Schindelin via GitGitGadget, Feb 13, 2024
  15. Junio C HamanoFeb 13, 2024
  16. 00/11 The merge-base logic vs missing commit objectsJohannes Schindelin via GitGitGadget, Feb 22, 2024
  17. 01/11 paint_down_to_common: plug two memory leaksJohannes Schindelin via GitGitGadget, Feb 22, 2024
  18. 02/11 Prepare `repo_in_merge_bases_many()` to optionally expect missing commitsJohannes Schindelin via GitGitGadget, Feb 22, 2024
  19. 03/11 Start reporting missing commits in `repo_in_merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  20. Junio C HamanoFeb 24, 2024
  21. Johannes SchindelinFeb 26, 2024
  22. Junio C HamanoFeb 26, 2024
  23. Jeff KingMar 1, 2024
  24. 04/11 Prepare `paint_down_to_common()` for handling shallow commitsJohannes Schindelin via GitGitGadget, Feb 22, 2024
  25. 05/11 commit-reach: start reporting errors in `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  26. 06/11 merge_bases_many(): pass on errors from `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  27. 07/11 get_merge_bases_many_0(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  28. 08/11 repo_get_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  29. 10/11 repo_get_merge_bases_many(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  30. 09/11 get_octopus_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  31. 11/11 repo_get_merge_bases_many_dirty(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 22, 2024
  32. 00/11 The merge-base logic vs missing commit objectsJohannes Schindelin via GitGitGadget, Feb 27, 2024
  33. 01/11 paint_down_to_common: plug two memory leaksJohannes Schindelin via GitGitGadget, Feb 27, 2024
  34. 02/11 Prepare `repo_in_merge_bases_many()` to optionally expect missing commitsJohannes Schindelin via GitGitGadget, Feb 27, 2024
  35. 04/11 Prepare `paint_down_to_common()` for handling shallow commitsJohannes Schindelin via GitGitGadget, Feb 27, 2024
  36. Dirk GoudersFeb 27, 2024
  37. Johannes SchindelinFeb 27, 2024
  38. Junio C HamanoFeb 27, 2024
  39. Junio C HamanoFeb 27, 2024
  40. Dirk GoudersFeb 27, 2024
  41. 03/11 Start reporting missing commits in `repo_in_merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  42. 05/11 commit-reach: start reporting errors in `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  43. Dirk GoudersFeb 27, 2024
  44. Johannes SchindelinFeb 27, 2024
  45. Junio C HamanoFeb 27, 2024
  46. 06/11 merge_bases_many(): pass on errors from `paint_down_to_common()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  47. Junio C HamanoFeb 27, 2024
  48. 07/11 get_merge_bases_many_0(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  49. 08/11 repo_get_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  50. 09/11 get_octopus_merge_bases(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  51. 10/11 repo_get_merge_bases_many(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  52. 11/11 repo_get_merge_bases_many_dirty(): pass on errors from `merge_bases_many()`Johannes Schindelin via GitGitGadget, Feb 27, 2024
  53. 00/11 The merge-base logic vs missing commit objectsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  54. 01/11 commit-reach(paint_down_to_common): plug two memory leaksJohannes Schindelin via GitGitGadget, Feb 28, 2024
  55. 02/11 commit-reach(repo_in_merge_bases_many): optionally expect missing commitsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  56. 03/11 commit-reach(repo_in_merge_bases_many): report missing commitsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  57. Jeff KingMar 1, 2024
  58. Junio C HamanoMar 1, 2024
  59. 04/11 commit-reach(paint_down_to_common): prepare for handling shallow commitsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  60. Junio C HamanoFeb 28, 2024
  61. Dirk GoudersFeb 28, 2024
  62. Johannes SchindelinFeb 29, 2024
  63. Johannes SchindelinFeb 29, 2024
  64. 05/11 commit-reach(paint_down_to_common): start reporting errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  65. 06/11 commit-reach(merge_bases_many): pass on "missing commits" errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  66. 07/11 commit-reach(get_merge_bases_many_0): pass on "missing commits" errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  67. 08/11 commit-reach(repo_get_merge_bases): pass on "missing commits" errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  68. 09/11 commit-reach(get_octopus_merge_bases): pass on "missing commits" errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  69. 10/11 commit-reach(repo_get_merge_bases_many): pass on "missing commits" errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024
  70. 11/11 commit-reach(repo_get_merge_bases_many_dirty): pass on errorsJohannes Schindelin via GitGitGadget, Feb 28, 2024

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.