summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorMartin Ågren <martin.agren@gmail.com>2017-09-22 23:34:51 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-09-24 01:05:57 (GMT)
commitb2ccdf7fc15e866a883b706540055b5d05fb9aef (patch)
tree971aea7e1716ea78dbcf3de8d9baf353d019dab3 /builtin
parentcb7b29eb67772d08e2365ed07ede9d954d0344c1 (diff)
downloadgit-b2ccdf7fc15e866a883b706540055b5d05fb9aef.zip
git-b2ccdf7fc15e866a883b706540055b5d05fb9aef.tar.gz
git-b2ccdf7fc15e866a883b706540055b5d05fb9aef.tar.bz2
leak_pending: use `object_array_clear()`, not `free()`
Setting `leak_pending = 1` tells `prepare_revision_walk()` not to release the `pending` array, and makes that the caller's responsibility. See 4a43d374f (revision: add leak_pending flag, 2011-10-01) and 353f5657a (bisect: use leak_pending flag, 2011-10-01). Commit 1da1e07c8 (clean up name allocation in prepare_revision_walk, 2014-10-15) fixed a memory leak in `prepare_revision_walk()` by switching from `free()` to `object_array_clear()`. However, where we use the `leak_pending`-mechanism, we're still only calling `free()`. Use `object_array_clear()` instead. Copy some helpful comments from 353f5657a to the other callers that we update to clarify the memory responsibilities, and to highlight that the commits are not affected when we clear the array -- it is indeed correct to both tidy up the commit flags and clear the object array. Document `leak_pending` in revision.h to help future users get this right. Signed-off-by: Martin Ågren <martin.agren@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/checkout.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2d75ac6..52f1b67 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,