diff options
-rw-r--r-- | bisect.c | 3 | ||||
-rw-r--r-- | builtin/checkout.c | 9 | ||||
-rw-r--r-- | bundle.c | 9 | ||||
-rw-r--r-- | revision.h | 11 |
4 files changed, 29 insertions, 3 deletions
@@ -826,7 +826,8 @@ static int check_ancestors(const char *prefix) /* Clean up objects used, as they will be reused. */ clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS); - free(pending_copy.objects); + + object_array_clear(&pending_copy); return res; } diff --git a/builtin/checkout.c b/builtin/checkout.c index 2d75ac66c7..52f1b67708 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -796,9 +796,14 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new) for_each_ref(add_pending_uninteresting_ref, &revs); add_pending_oid(&revs, "HEAD", &new->object.oid, UNINTERESTING); + /* Save pending objects, so they can be cleaned up later. */ refs = revs.pending; revs.leak_pending = 1; + /* + * prepare_revision_walk (together with .leak_pending = 1) makes us + * the sole owner of the list of pending objects. + */ if (prepare_revision_walk(&revs)) die(_("internal error in revision walk")); if (!(old->object.flags & UNINTERESTING)) @@ -806,8 +811,10 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new) else describe_detached_head(_("Previous HEAD position was"), old); + /* Clean up objects used, as they will be reused. */ clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS); - free(refs.objects); + + object_array_clear(&refs); } static int switch_branches(const struct checkout_opts *opts, @@ -157,9 +157,14 @@ int verify_bundle(struct bundle_header *header, int verbose) req_nr = revs.pending.nr; setup_revisions(2, argv, &revs, NULL); + /* Save pending objects, so they can be cleaned up later. */ refs = revs.pending; revs.leak_pending = 1; + /* + * prepare_revision_walk (together with .leak_pending = 1) makes us + * the sole owner of the list of pending objects. + */ if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); @@ -176,8 +181,10 @@ int verify_bundle(struct bundle_header *header, int verbose) refs.objects[i].name); } + /* Clean up objects used, as they will be reused. */ clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS); - free(refs.objects); + + object_array_clear(&refs); if (verbose) { struct ref_list *r; diff --git a/revision.h b/revision.h index bc18487d6f..3162cc78e8 100644 --- a/revision.h +++ b/revision.h @@ -149,6 +149,17 @@ struct rev_info { date_mode_explicit:1, preserve_subject:1; unsigned int disable_stdin:1; + /* + * Set `leak_pending` to prevent `prepare_revision_walk()` from clearing + * the array of pending objects (`pending`). It will still forget about + * the array and its entries, so they really are leaked. This can be + * useful if the `struct object_array` `pending` is copied before + * calling `prepare_revision_walk()`. By setting `leak_pending`, you + * effectively claim ownership of the old array, so you should most + * likely call `object_array_clear(&pending_copy)` once you are done. + * Observe that this is about ownership of the array and its entries, + * not the commits referenced by those entries. + */ unsigned int leak_pending:1; /* --show-linear-break */ unsigned int track_linear:1, |