]> git.ipfire.org Git - thirdparty/git.git/commitdiff
commit-reach(merge_bases_many): pass on "missing commits" errors
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 28 Feb 2024 09:44:12 +0000 (09:44 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 29 Feb 2024 16:06:01 +0000 (08:06 -0800)
The `paint_down_to_common()` function was just taught to indicate
parsing errors, and now the `merge_bases_many()` function is aware of
that, too.

One tricky aspect is that `merge_bases_many()` parses commits of its
own, but wants to gracefully handle the scenario where NULL is passed as
a merge head, returning the empty list of merge bases. The way this was
handled involved calling `repo_parse_commit(NULL)` and relying on it to
return an error. This has to be done differently now so that we can
handle missing commits correctly by producing a fatal error.

Next step: adjust the caller of `merge_bases_many()`:
`get_merge_bases_many_0()`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit-reach.c

index 267fcfc6caffe1e04b36e81740ad5e7801cca03a..2585b895d3a53d037df32809a6639435a8213a96 100644 (file)
@@ -130,41 +130,49 @@ static int paint_down_to_common(struct repository *r,
        return 0;
 }
 
-static struct commit_list *merge_bases_many(struct repository *r,
-                                           struct commit *one, int n,
-                                           struct commit **twos)
+static int merge_bases_many(struct repository *r,
+                           struct commit *one, int n,
+                           struct commit **twos,
+                           struct commit_list **result)
 {
        struct commit_list *list = NULL;
-       struct commit_list *result = NULL;
        int i;
 
        for (i = 0; i < n; i++) {
-               if (one == twos[i])
+               if (one == twos[i]) {
                        /*
                         * We do not mark this even with RESULT so we do not
                         * have to clean it up.
                         */
-                       return commit_list_insert(one, &result);
+                       *result = commit_list_insert(one, result);
+                       return 0;
+               }
        }
 
+       if (!one)
+               return 0;
        if (repo_parse_commit(r, one))
-               return NULL;
+               return error(_("could not parse commit %s"),
+                            oid_to_hex(&one->object.oid));
        for (i = 0; i < n; i++) {
+               if (!twos[i])
+                       return 0;
                if (repo_parse_commit(r, twos[i]))
-                       return NULL;
+                       return error(_("could not parse commit %s"),
+                                    oid_to_hex(&twos[i]->object.oid));
        }
 
        if (paint_down_to_common(r, one, n, twos, 0, 0, &list)) {
                free_commit_list(list);
-               return NULL;
+               return -1;
        }
 
        while (list) {
                struct commit *commit = pop_commit(&list);
                if (!(commit->object.flags & STALE))
-                       commit_list_insert_by_date(commit, &result);
+                       commit_list_insert_by_date(commit, result);
        }
-       return result;
+       return 0;
 }
 
 struct commit_list *get_octopus_merge_bases(struct commit_list *in)
@@ -409,10 +417,11 @@ static struct commit_list *get_merge_bases_many_0(struct repository *r,
 {
        struct commit_list *list;
        struct commit **rslt;
-       struct commit_list *result;
+       struct commit_list *result = NULL;
        int cnt, i;
 
-       result = merge_bases_many(r, one, n, twos);
+       if (merge_bases_many(r, one, n, twos, &result) < 0)
+               return NULL;
        for (i = 0; i < n; i++) {
                if (one == twos[i])
                        return result;