checkout: use leak_pending flag

Instead of going through all the references again when we clear the commit marks, do it like bisect and bundle and gain ownership of the list of pending objects which we constructed from those references. We simply copy the struct object_array that points to the list, set the flag leak_pending and then prepare_revision_walk won't destroy it and it's ours. We use it to clear the marks and free it at the end. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Oct 1, 2011 at 18:09 UTC 1062141928aaa1d272be8ce007d371168e8daef6
1 file changed +12 -13
builtin/checkout.c
+12 -13
@@ -596,17 +596,6 @@ static int add_pending_uninteresting_ref(const char *refname,
596 return 0;
597 }
598
599 -static int clear_commit_marks_from_one_ref(const char *refname,
600 - const unsigned char *sha1,
601 - int flags,
602 - void *cb_data)
603 -{
604 - struct commit *commit = lookup_commit_reference_gently(sha1, 1);
605 - if (commit)
606 - clear_commit_marks(commit, -1);
607 - return 0;
608 -}
609 -
599 static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
600 {
601 parse_commit(commit);
@@ -673,6 +662,8 @@ static void orphaned_commit_warning(struct commit *commit)
662 {
663 struct rev_info revs;
664 struct object *object = &commit->object;
665 + struct object_array refs;
666 + unsigned int i;
667
668 init_revisions(&revs, NULL);
669 setup_revisions(0, NULL, &revs, NULL);
@@ -682,6 +673,9 @@ static void orphaned_commit_warning(struct commit *commit)
673
674 for_each_ref(add_pending_uninteresting_ref, &revs);
675
676 + refs = revs.pending;
677 + revs.leak_pending = 1;
678 +
679 if (prepare_revision_walk(&revs))
680 die(_("internal error in revision walk"));
681 if (!(commit->object.flags & UNINTERESTING))
@@ -689,8 +683,13 @@ static void orphaned_commit_warning(struct commit *commit)
683 else
684 describe_detached_head(_("Previous HEAD position was"), commit);
685
692 - clear_commit_marks(commit, -1);
693 - for_each_ref(clear_commit_marks_from_one_ref, NULL);
686 + for (i = 0; i < refs.nr; i++) {
687 + struct object *o = refs.objects[i].item;
688 + struct commit *c = lookup_commit_reference_gently(o->sha1, 1);
689 + if (c)
690 + clear_commit_marks(c, ALL_REV_FLAGS);
691 + }
692 + free(refs.objects);
693 }
694
695 static int switch_branches(struct checkout_opts *opts, struct branch_info *new)