diff options
author | Junio C Hamano <gitster@pobox.com> | 2024-03-11 22:12:30 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-03-11 22:12:30 +0100 |
commit | 7745f92507517c4e60dc2a7faad40eee49ee670b (patch) | |
tree | f9eb30d1767f40a69db6b874f50bbdc8953d745d /merge-ort.c | |
parent | The fifth batch (diff) | |
parent | merge-ort/merge-recursive: do report errors in `merge_submodule()` (diff) | |
download | git-7745f92507517c4e60dc2a7faad40eee49ee670b.tar.xz git-7745f92507517c4e60dc2a7faad40eee49ee670b.zip |
Merge branch 'js/merge-base-with-missing-commit'
Make sure failure return from merge_bases_many() is properly caught.
* js/merge-base-with-missing-commit:
merge-ort/merge-recursive: do report errors in `merge_submodule()`
merge-recursive: prepare for `merge_submodule()` to report errors
commit-reach(repo_get_merge_bases_many_dirty): pass on errors
commit-reach(repo_get_merge_bases_many): pass on "missing commits" errors
commit-reach(get_octopus_merge_bases): pass on "missing commits" errors
commit-reach(repo_get_merge_bases): pass on "missing commits" errors
commit-reach(get_merge_bases_many_0): pass on "missing commits" errors
commit-reach(merge_bases_many): pass on "missing commits" errors
commit-reach(paint_down_to_common): start reporting errors
commit-reach(paint_down_to_common): prepare for handling shallow commits
commit-reach(repo_in_merge_bases_many): report missing commits
commit-reach(repo_in_merge_bases_many): optionally expect missing commits
commit-reach(paint_down_to_common): plug two memory leaks
Diffstat (limited to 'merge-ort.c')
-rw-r--r-- | merge-ort.c | 92 |
1 files changed, 81 insertions, 11 deletions
diff --git a/merge-ort.c b/merge-ort.c index 817f7b57c7..201f8f7775 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -543,6 +543,7 @@ enum conflict_and_info_types { CONFLICT_SUBMODULE_HISTORY_NOT_AVAILABLE, CONFLICT_SUBMODULE_MAY_HAVE_REWINDS, CONFLICT_SUBMODULE_NULL_MERGE_BASE, + CONFLICT_SUBMODULE_CORRUPT, /* Keep this entry _last_ in the list */ NB_CONFLICT_TYPES, @@ -595,7 +596,9 @@ static const char *type_short_descriptions[] = { [CONFLICT_SUBMODULE_MAY_HAVE_REWINDS] = "CONFLICT (submodule may have rewinds)", [CONFLICT_SUBMODULE_NULL_MERGE_BASE] = - "CONFLICT (submodule lacks merge base)" + "CONFLICT (submodule lacks merge base)", + [CONFLICT_SUBMODULE_CORRUPT] = + "CONFLICT (submodule corrupt)" }; struct logical_conflict_info { @@ -1710,7 +1713,14 @@ static int find_first_merges(struct repository *repo, die("revision walk setup failed"); while ((commit = get_revision(&revs)) != NULL) { struct object *o = &(commit->object); - if (repo_in_merge_bases(repo, b, commit)) + int ret = repo_in_merge_bases(repo, b, commit); + + if (ret < 0) { + object_array_clear(&merges); + release_revisions(&revs); + return ret; + } + if (ret > 0) add_object_array(o, NULL, &merges); } reset_revision_walk(); @@ -1725,9 +1735,17 @@ static int find_first_merges(struct repository *repo, contains_another = 0; for (j = 0; j < merges.nr; j++) { struct commit *m2 = (struct commit *) merges.objects[j].item; - if (i != j && repo_in_merge_bases(repo, m2, m1)) { - contains_another = 1; - break; + if (i != j) { + int ret = repo_in_merge_bases(repo, m2, m1); + if (ret < 0) { + object_array_clear(&merges); + release_revisions(&revs); + return ret; + } + if (ret > 0) { + contains_another = 1; + break; + } } } @@ -1749,7 +1767,7 @@ static int merge_submodule(struct merge_options *opt, { struct repository subrepo; struct strbuf sb = STRBUF_INIT; - int ret = 0; + int ret = 0, ret2; struct commit *commit_o, *commit_a, *commit_b; int parent_count; struct object_array merges; @@ -1796,8 +1814,28 @@ static int merge_submodule(struct merge_options *opt, } /* check whether both changes are forward */ - if (!repo_in_merge_bases(&subrepo, commit_o, commit_a) || - !repo_in_merge_bases(&subrepo, commit_o, commit_b)) { + ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_a); + if (ret2 < 0) { + path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0, + path, NULL, NULL, NULL, + _("Failed to merge submodule %s " + "(repository corrupt)"), + path); + ret = -1; + goto cleanup; + } + if (ret2 > 0) + ret2 = repo_in_merge_bases(&subrepo, commit_o, commit_b); + if (ret2 < 0) { + path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0, + path, NULL, NULL, NULL, + _("Failed to merge submodule %s " + "(repository corrupt)"), + path); + ret = -1; + goto cleanup; + } + if (!ret2) { path_msg(opt, CONFLICT_SUBMODULE_MAY_HAVE_REWINDS, 0, path, NULL, NULL, NULL, _("Failed to merge submodule %s " @@ -1807,7 +1845,17 @@ static int merge_submodule(struct merge_options *opt, } /* Case #1: a is contained in b or vice versa */ - if (repo_in_merge_bases(&subrepo, commit_a, commit_b)) { + ret2 = repo_in_merge_bases(&subrepo, commit_a, commit_b); + if (ret2 < 0) { + path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0, + path, NULL, NULL, NULL, + _("Failed to merge submodule %s " + "(repository corrupt)"), + path); + ret = -1; + goto cleanup; + } + if (ret2 > 0) { oidcpy(result, b); path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1, path, NULL, NULL, NULL, @@ -1816,7 +1864,17 @@ static int merge_submodule(struct merge_options *opt, ret = 1; goto cleanup; } - if (repo_in_merge_bases(&subrepo, commit_b, commit_a)) { + ret2 = repo_in_merge_bases(&subrepo, commit_b, commit_a); + if (ret2 < 0) { + path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0, + path, NULL, NULL, NULL, + _("Failed to merge submodule %s " + "(repository corrupt)"), + path); + ret = -1; + goto cleanup; + } + if (ret2 > 0) { oidcpy(result, a); path_msg(opt, INFO_SUBMODULE_FAST_FORWARDING, 1, path, NULL, NULL, NULL, @@ -1841,6 +1899,14 @@ static int merge_submodule(struct merge_options *opt, parent_count = find_first_merges(&subrepo, path, commit_a, commit_b, &merges); switch (parent_count) { + case -1: + path_msg(opt, CONFLICT_SUBMODULE_CORRUPT, 0, + path, NULL, NULL, NULL, + _("Failed to merge submodule %s " + "(repository corrupt)"), + path); + ret = -1; + break; case 0: path_msg(opt, CONFLICT_SUBMODULE_FAILED_TO_MERGE, 0, path, NULL, NULL, NULL, @@ -5014,7 +5080,11 @@ static void merge_ort_internal(struct merge_options *opt, struct strbuf merge_base_abbrev = STRBUF_INIT; if (!merge_bases) { - merge_bases = repo_get_merge_bases(the_repository, h1, h2); + if (repo_get_merge_bases(the_repository, h1, h2, + &merge_bases) < 0) { + result->clean = -1; + return; + } /* See merge-ort.h:merge_incore_recursive() declaration NOTE */ merge_bases = reverse_commit_list(merge_bases); } |