diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2024-02-28 10:44:09 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2024-02-28 18:47:03 +0100 |
commit | 24876ebf68baf90075dad5ca3acba8a305f308d4 (patch) | |
tree | 99968921866edefd3c3a357073df5652232f3f85 /merge-recursive.c | |
parent | commit-reach(repo_in_merge_bases_many): optionally expect missing commits (diff) | |
download | git-24876ebf68baf90075dad5ca3acba8a305f308d4.tar.xz git-24876ebf68baf90075dad5ca3acba8a305f308d4.zip |
commit-reach(repo_in_merge_bases_many): report missing commits
Some functions in Git's source code follow the convention that returning
a negative value indicates a fatal error, e.g. repository corruption.
Let's use this convention in `repo_in_merge_bases()` to report when one
of the specified commits is missing (i.e. when `repo_parse_commit()`
reports an error).
Also adjust the callers of `repo_in_merge_bases()` to handle such
negative return values.
Note: As of this patch, errors are returned only if any of the specified
merge heads is missing. Over the course of the next patches, missing
commits will also be reported by the `paint_down_to_common()` function,
which is called by `repo_in_merge_bases_many()`, and those errors will
be properly propagated back to the caller at that stage.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'merge-recursive.c')
-rw-r--r-- | merge-recursive.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index a0c3e7a2d9..ae23a62048 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1139,7 +1139,13 @@ 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) add_object_array(o, NULL, &merges); } reset_revision_walk(); @@ -1154,9 +1160,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; + } } } @@ -1192,7 +1206,7 @@ static int merge_submodule(struct merge_options *opt, const struct object_id *b) { struct repository subrepo; - int ret = 0; + int ret = 0, ret2; struct commit *commit_base, *commit_a, *commit_b; int parent_count; struct object_array merges; @@ -1229,14 +1243,29 @@ static int merge_submodule(struct merge_options *opt, } /* check whether both changes are forward */ - if (!repo_in_merge_bases(&subrepo, commit_base, commit_a) || - !repo_in_merge_bases(&subrepo, commit_base, commit_b)) { + ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_a); + if (ret2 < 0) { + output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path); + goto cleanup; + } + if (ret2 > 0) + ret2 = repo_in_merge_bases(&subrepo, commit_base, commit_b); + if (ret2 < 0) { + output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path); + goto cleanup; + } + if (!ret2) { output(opt, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path); goto cleanup; } /* 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) { + output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path); + goto cleanup; + } + if (ret2) { oidcpy(result, b); if (show(opt, 3)) { output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); @@ -1249,7 +1278,12 @@ 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) { + output(opt, 1, _("Failed to merge submodule %s (repository corrupt)"), path); + goto cleanup; + } + if (ret2) { oidcpy(result, a); if (show(opt, 3)) { output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); @@ -1397,6 +1431,8 @@ static int merge_mode_and_contents(struct merge_options *opt, &o->oid, &a->oid, &b->oid); + if (result->clean < 0) + return -1; } else if (S_ISLNK(a->mode)) { switch (opt->recursive_variant) { case MERGE_VARIANT_NORMAL: |