Skip to content

Commit e17cec2

Browse files
committed
Merge branch 'rs/lose-leak-pending' into maint
API clean-up around revision traversal. * rs/lose-leak-pending: commit: remove unused function clear_commit_marks_for_object_array() revision: remove the unused flag leak_pending checkout: avoid using the rev_info flag leak_pending bundle: avoid using the rev_info flag leak_pending bisect: avoid using the rev_info flag leak_pending object: add clear_commit_marks_all() ref-filter: use clear_commit_marks_many() in do_merge_filter() commit: use clear_commit_marks_many() in remove_redundant() commit: avoid allocation in clear_commit_marks_many()
2 parents 04afcc2 + 6fcec2f commit e17cec2

File tree

10 files changed

+46
-86
lines changed

10 files changed

+46
-86
lines changed

bisect.c

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -792,11 +792,9 @@ static void handle_skipped_merge_base(const struct object_id *mb)
792792
* - If one is "skipped", we can't know but we should warn.
793793
* - If we don't know, we should check it out and ask the user to test.
794794
*/
795-
static void check_merge_bases(int no_checkout)
795+
static void check_merge_bases(int rev_nr, struct commit **rev, int no_checkout)
796796
{
797797
struct commit_list *result;
798-
int rev_nr;
799-
struct commit **rev = get_bad_and_good_commits(&rev_nr);
800798

801799
result = get_merge_bases_many(rev[0], rev_nr - 1, rev + 1);
802800

@@ -814,34 +812,21 @@ static void check_merge_bases(int no_checkout)
814812
}
815813
}
816814

817-
free(rev);
818815
free_commit_list(result);
819816
}
820817

821-
static int check_ancestors(const char *prefix)
818+
static int check_ancestors(int rev_nr, struct commit **rev, const char *prefix)
822819
{
823820
struct rev_info revs;
824-
struct object_array pending_copy;
825821
int res;
826822

827823
bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
828824

829-
/* Save pending objects, so they can be cleaned up later. */
830-
pending_copy = revs.pending;
831-
revs.leak_pending = 1;
832-
833-
/*
834-
* bisect_common calls prepare_revision_walk right away, which
835-
* (together with .leak_pending = 1) makes us the sole owner of
836-
* the list of pending objects.
837-
*/
838825
bisect_common(&revs);
839826
res = (revs.commits != NULL);
840827

841828
/* Clean up objects used, as they will be reused. */
842-
clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS);
843-
844-
object_array_clear(&pending_copy);
829+
clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS);
845830

846831
return res;
847832
}
@@ -858,7 +843,8 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
858843
{
859844
char *filename = git_pathdup("BISECT_ANCESTORS_OK");
860845
struct stat st;
861-
int fd;
846+
int fd, rev_nr;
847+
struct commit **rev;
862848

863849
if (!current_bad_oid)
864850
die(_("a %s revision is needed"), term_bad);
@@ -872,8 +858,10 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
872858
goto done;
873859

874860
/* Check if all good revs are ancestor of the bad rev. */
875-
if (check_ancestors(prefix))
876-
check_merge_bases(no_checkout);
861+
rev = get_bad_and_good_commits(&rev_nr);
862+
if (check_ancestors(rev_nr, rev, prefix))
863+
check_merge_bases(rev_nr, rev, no_checkout);
864+
free(rev);
877865

878866
/* Create file BISECT_ANCESTORS_OK. */
879867
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);

builtin/checkout.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,6 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new)
791791
{
792792
struct rev_info revs;
793793
struct object *object = &old->object;
794-
struct object_array refs;
795794

796795
init_revisions(&revs, NULL);
797796
setup_revisions(0, NULL, &revs, NULL);
@@ -802,14 +801,6 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new)
802801
for_each_ref(add_pending_uninteresting_ref, &revs);
803802
add_pending_oid(&revs, "HEAD", &new->object.oid, UNINTERESTING);
804803

805-
/* Save pending objects, so they can be cleaned up later. */
806-
refs = revs.pending;
807-
revs.leak_pending = 1;
808-
809-
/*
810-
* prepare_revision_walk (together with .leak_pending = 1) makes us
811-
* the sole owner of the list of pending objects.
812-
*/
813804
if (prepare_revision_walk(&revs))
814805
die(_("internal error in revision walk"));
815806
if (!(old->object.flags & UNINTERESTING))
@@ -818,9 +809,7 @@ static void orphaned_commit_warning(struct commit *old, struct commit *new)
818809
describe_detached_head(_("Previous HEAD position was"), old);
819810

820811
/* Clean up objects used, as they will be reused. */
821-
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
822-
823-
object_array_clear(&refs);
812+
clear_commit_marks_all(ALL_REV_FLAGS);
824813
}
825814

826815
static int switch_branches(const struct checkout_opts *opts,

bundle.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ int verify_bundle(struct bundle_header *header, int verbose)
134134
struct ref_list *p = &header->prerequisites;
135135
struct rev_info revs;
136136
const char *argv[] = {NULL, "--all", NULL};
137-
struct object_array refs;
138137
struct commit *commit;
139138
int i, ret = 0, req_nr;
140139
const char *message = _("Repository lacks these prerequisite commits:");
@@ -157,14 +156,6 @@ int verify_bundle(struct bundle_header *header, int verbose)
157156
req_nr = revs.pending.nr;
158157
setup_revisions(2, argv, &revs, NULL);
159158

160-
/* Save pending objects, so they can be cleaned up later. */
161-
refs = revs.pending;
162-
revs.leak_pending = 1;
163-
164-
/*
165-
* prepare_revision_walk (together with .leak_pending = 1) makes us
166-
* the sole owner of the list of pending objects.
167-
*/
168159
if (prepare_revision_walk(&revs))
169160
die(_("revision walk setup failed"));
170161

@@ -173,18 +164,24 @@ int verify_bundle(struct bundle_header *header, int verbose)
173164
if (commit->object.flags & PREREQ_MARK)
174165
i--;
175166

176-
for (i = 0; i < req_nr; i++)
177-
if (!(refs.objects[i].item->flags & SHOWN)) {
178-
if (++ret == 1)
179-
error("%s", message);
180-
error("%s %s", oid_to_hex(&refs.objects[i].item->oid),
181-
refs.objects[i].name);
182-
}
167+
for (i = 0; i < p->nr; i++) {
168+
struct ref_list_entry *e = p->list + i;
169+
struct object *o = parse_object(&e->oid);
170+
assert(o); /* otherwise we'd have returned early */
171+
if (o->flags & SHOWN)
172+
continue;
173+
if (++ret == 1)
174+
error("%s", message);
175+
error("%s %s", oid_to_hex(&e->oid), e->name);
176+
}
183177

184178
/* Clean up objects used, as they will be reused. */
185-
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
186-
187-
object_array_clear(&refs);
179+
for (i = 0; i < p->nr; i++) {
180+
struct ref_list_entry *e = p->list + i;
181+
commit = lookup_commit_reference_gently(&e->oid, 1);
182+
if (commit)
183+
clear_commit_marks(commit, ALL_REV_FLAGS);
184+
}
188185

189186
if (verbose) {
190187
struct ref_list *r;

commit.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark)
547547
struct commit_list *list = NULL;
548548

549549
while (nr--) {
550-
commit_list_insert(*commit, &list);
550+
clear_commit_marks_1(&list, *commit, mark);
551551
commit++;
552552
}
553553
while (list)
@@ -559,20 +559,6 @@ void clear_commit_marks(struct commit *commit, unsigned int mark)
559559
clear_commit_marks_many(1, &commit, mark);
560560
}
561561

562-
void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark)
563-
{
564-
struct object *object;
565-
struct commit *commit;
566-
unsigned int i;
567-
568-
for (i = 0; i < a->nr; i++) {
569-
object = a->objects[i].item;
570-
commit = lookup_commit_reference_gently(&object->oid, 1);
571-
if (commit)
572-
clear_commit_marks(commit, mark);
573-
}
574-
}
575-
576562
struct commit *pop_commit(struct commit_list **stack)
577563
{
578564
struct commit_list *top = *stack;
@@ -929,8 +915,7 @@ static int remove_redundant(struct commit **array, int cnt)
929915
if (work[j]->object.flags & PARENT1)
930916
redundant[filled_index[j]] = 1;
931917
clear_commit_marks(array[i], all_flags);
932-
for (j = 0; j < filled; j++)
933-
clear_commit_marks(work[j], all_flags);
918+
clear_commit_marks_many(filled, work, all_flags);
934919
free_commit_list(common);
935920
}
936921

commit.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ struct commit *pop_commit(struct commit_list **stack);
140140

141141
void clear_commit_marks(struct commit *commit, unsigned int mark);
142142
void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark);
143-
void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark);
144143

145144

146145
enum rev_sort_order {

object.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,14 @@ void clear_object_flags(unsigned flags)
434434
obj->flags &= ~flags;
435435
}
436436
}
437+
438+
void clear_commit_marks_all(unsigned int flags)
439+
{
440+
int i;
441+
442+
for (i = 0; i < obj_hash_size; i++) {
443+
struct object *obj = obj_hash[i];
444+
if (obj && obj->type == OBJ_COMMIT)
445+
obj->flags &= ~flags;
446+
}
447+
}

object.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,9 @@ void object_array_clear(struct object_array *array);
149149

150150
void clear_object_flags(unsigned flags);
151151

152+
/*
153+
* Clear the specified object flags from all in-core commit objects.
154+
*/
155+
extern void clear_commit_marks_all(unsigned int flags);
156+
152157
#endif /* OBJECT_H */

ref-filter.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,8 +1995,7 @@ static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata)
19951995
free_array_item(item);
19961996
}
19971997

1998-
for (i = 0; i < old_nr; i++)
1999-
clear_commit_marks(to_clear[i], ALL_REV_FLAGS);
1998+
clear_commit_marks_many(old_nr, to_clear, ALL_REV_FLAGS);
20001999
clear_commit_marks(filter->merge_commit, ALL_REV_FLAGS);
20012000
free(to_clear);
20022001
}

revision.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,8 +2862,7 @@ int prepare_revision_walk(struct rev_info *revs)
28622862
}
28632863
}
28642864
}
2865-
if (!revs->leak_pending)
2866-
object_array_clear(&old_pending);
2865+
object_array_clear(&old_pending);
28672866

28682867
/* Signal whether we need per-parent treesame decoration */
28692868
if (revs->simplify_merges ||

revision.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,18 +151,6 @@ struct rev_info {
151151
date_mode_explicit:1,
152152
preserve_subject:1;
153153
unsigned int disable_stdin:1;
154-
/*
155-
* Set `leak_pending` to prevent `prepare_revision_walk()` from clearing
156-
* the array of pending objects (`pending`). It will still forget about
157-
* the array and its entries, so they really are leaked. This can be
158-
* useful if the `struct object_array` `pending` is copied before
159-
* calling `prepare_revision_walk()`. By setting `leak_pending`, you
160-
* effectively claim ownership of the old array, so you should most
161-
* likely call `object_array_clear(&pending_copy)` once you are done.
162-
* Observe that this is about ownership of the array and its entries,
163-
* not the commits referenced by those entries.
164-
*/
165-
unsigned int leak_pending:1;
166154
/* --show-linear-break */
167155
unsigned int track_linear:1,
168156
track_first_time:1,

0 commit comments

Comments
 (0)