Skip to content

Commit 0941d60

Browse files
committed
Merge branch 'rs/pending'
* rs/pending: commit: factor out clear_commit_marks_for_object_array checkout: use leak_pending flag bundle: use leak_pending flag bisect: use leak_pending flag revision: add leak_pending flag checkout: use add_pending_{object,sha1} in orphan check revision: factor out add_pending_sha1 checkout: check for "Previous HEAD" notice in t2020 Conflicts: builtin/checkout.c revision.c
2 parents dd57c76 + 86a0a40 commit 0941d60

File tree

8 files changed

+64
-49
lines changed

8 files changed

+64
-49
lines changed

bisect.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -800,25 +800,25 @@ static int check_ancestors(const char *prefix)
800800
{
801801
struct rev_info revs;
802802
struct object_array pending_copy;
803-
int i, res;
803+
int res;
804804

805805
bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
806806

807807
/* Save pending objects, so they can be cleaned up later. */
808-
memset(&pending_copy, 0, sizeof(pending_copy));
809-
for (i = 0; i < revs.pending.nr; i++)
810-
add_object_array(revs.pending.objects[i].item,
811-
revs.pending.objects[i].name,
812-
&pending_copy);
808+
pending_copy = revs.pending;
809+
revs.leak_pending = 1;
813810

811+
/*
812+
* bisect_common calls prepare_revision_walk right away, which
813+
* (together with .leak_pending = 1) makes us the sole owner of
814+
* the list of pending objects.
815+
*/
814816
bisect_common(&revs);
815817
res = (revs.commits != NULL);
816818

817819
/* Clean up objects used, as they will be reused. */
818-
for (i = 0; i < pending_copy.nr; i++) {
819-
struct object *o = pending_copy.objects[i].item;
820-
clear_commit_marks((struct commit *)o, ALL_REV_FLAGS);
821-
}
820+
clear_commit_marks_for_object_array(&pending_copy, ALL_REV_FLAGS);
821+
free(pending_copy.objects);
822822

823823
return res;
824824
}

builtin/checkout.c

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -589,23 +589,11 @@ static void update_refs_for_switch(struct checkout_opts *opts,
589589
report_tracking(new);
590590
}
591591

592-
static int add_one_ref_to_rev_list_arg(const char *refname,
593-
const unsigned char *sha1,
594-
int flags,
595-
void *cb_data)
592+
static int add_pending_uninteresting_ref(const char *refname,
593+
const unsigned char *sha1,
594+
int flags, void *cb_data)
596595
{
597-
argv_array_push(cb_data, refname);
598-
return 0;
599-
}
600-
601-
static int clear_commit_marks_from_one_ref(const char *refname,
602-
const unsigned char *sha1,
603-
int flags,
604-
void *cb_data)
605-
{
606-
struct commit *commit = lookup_commit_reference_gently(sha1, 1);
607-
if (commit)
608-
clear_commit_marks(commit, -1);
596+
add_pending_sha1(cb_data, refname, sha1, flags | UNINTERESTING);
609597
return 0;
610598
}
611599

@@ -674,28 +662,30 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
674662
*/
675663
static void orphaned_commit_warning(struct commit *commit)
676664
{
677-
struct argv_array args = ARGV_ARRAY_INIT;
678665
struct rev_info revs;
679-
680-
argv_array_push(&args, "(internal)");
681-
argv_array_push(&args, sha1_to_hex(commit->object.sha1));
682-
argv_array_push(&args, "--not");
683-
for_each_ref(add_one_ref_to_rev_list_arg, &args);
684-
argv_array_push(&args, "--");
666+
struct object *object = &commit->object;
667+
struct object_array refs;
685668

686669
init_revisions(&revs, NULL);
687-
if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
688-
die(_("internal error: only -- alone should have been left"));
670+
setup_revisions(0, NULL, &revs, NULL);
671+
672+
object->flags &= ~UNINTERESTING;
673+
add_pending_object(&revs, object, sha1_to_hex(object->sha1));
674+
675+
for_each_ref(add_pending_uninteresting_ref, &revs);
676+
677+
refs = revs.pending;
678+
revs.leak_pending = 1;
679+
689680
if (prepare_revision_walk(&revs))
690681
die(_("internal error in revision walk"));
691682
if (!(commit->object.flags & UNINTERESTING))
692683
suggest_reattach(commit, &revs);
693684
else
694685
describe_detached_head(_("Previous HEAD position was"), commit);
695686

696-
argv_array_clear(&args);
697-
clear_commit_marks(commit, -1);
698-
for_each_ref(clear_commit_marks_from_one_ref, NULL);
687+
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
688+
free(refs.objects);
699689
}
700690

701691
static int switch_branches(struct checkout_opts *opts, struct branch_info *new)

bundle.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,8 @@ int verify_bundle(struct bundle_header *header, int verbose)
122122
req_nr = revs.pending.nr;
123123
setup_revisions(2, argv, &revs, NULL);
124124

125-
memset(&refs, 0, sizeof(struct object_array));
126-
for (i = 0; i < revs.pending.nr; i++) {
127-
struct object_array_entry *e = revs.pending.objects + i;
128-
add_object_array(e->item, e->name, &refs);
129-
}
125+
refs = revs.pending;
126+
revs.leak_pending = 1;
130127

131128
if (prepare_revision_walk(&revs))
132129
die("revision walk setup failed");
@@ -144,8 +141,8 @@ int verify_bundle(struct bundle_header *header, int verbose)
144141
refs.objects[i].name);
145142
}
146143

147-
for (i = 0; i < refs.nr; i++)
148-
clear_commit_marks((struct commit *)refs.objects[i].item, -1);
144+
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
145+
free(refs.objects);
149146

150147
if (verbose) {
151148
struct ref_list *r;

commit.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,20 @@ void clear_commit_marks(struct commit *commit, unsigned int mark)
442442
}
443443
}
444444

445+
void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark)
446+
{
447+
struct object *object;
448+
struct commit *commit;
449+
unsigned int i;
450+
451+
for (i = 0; i < a->nr; i++) {
452+
object = a->objects[i].item;
453+
commit = lookup_commit_reference_gently(object->sha1, 1);
454+
if (commit)
455+
clear_commit_marks(commit, mark);
456+
}
457+
}
458+
445459
struct commit *pop_commit(struct commit_list **stack)
446460
{
447461
struct commit_list *top = *stack;

commit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ struct commit *pop_most_recent_commit(struct commit_list **list,
133133
struct commit *pop_commit(struct commit_list **stack);
134134

135135
void clear_commit_marks(struct commit *commit, unsigned int mark);
136+
void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark);
136137

137138
/*
138139
* Performs an in-place topological sort of list supplied.

revision.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ static struct object *get_reference(struct rev_info *revs, const char *name, con
226226
return object;
227227
}
228228

229+
void add_pending_sha1(struct rev_info *revs, const char *name,
230+
const unsigned char *sha1, unsigned int flags)
231+
{
232+
struct object *object = get_reference(revs, name, sha1, flags);
233+
add_pending_object(revs, object, name);
234+
}
235+
229236
static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name)
230237
{
231238
unsigned long flags = object->flags;
@@ -897,7 +904,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
897904
struct object *object = get_reference(cb->all_revs, path, sha1,
898905
cb->all_flags);
899906
add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
900-
add_pending_object(cb->all_revs, object, path);
907+
add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags);
901908
return 0;
902909
}
903910

@@ -2050,7 +2057,8 @@ int prepare_revision_walk(struct rev_info *revs)
20502057
}
20512058
e++;
20522059
}
2053-
free(list);
2060+
if (!revs->leak_pending)
2061+
free(list);
20542062

20552063
if (revs->no_walk)
20562064
return 0;

revision.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ struct rev_info {
118118
date_mode_explicit:1,
119119
preserve_subject:1;
120120
unsigned int disable_stdin:1;
121+
unsigned int leak_pending:1;
121122

122123
enum date_mode date_mode;
123124

@@ -214,6 +215,7 @@ extern void add_object(struct object *obj,
214215
const char *name);
215216

216217
extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
218+
extern void add_pending_sha1(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags);
217219

218220
extern void add_head_to_pending(struct rev_info *);
219221

t/t2020-checkout-detach.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@ check_not_detached () {
1212
}
1313

1414
ORPHAN_WARNING='you are leaving .* commit.*behind'
15+
PREV_HEAD_DESC='Previous HEAD position was'
1516
check_orphan_warning() {
16-
test_i18ngrep "$ORPHAN_WARNING" "$1"
17+
test_i18ngrep "$ORPHAN_WARNING" "$1" &&
18+
test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
1719
}
1820
check_no_orphan_warning() {
19-
test_i18ngrep ! "$ORPHAN_WARNING" "$1"
21+
test_i18ngrep ! "$ORPHAN_WARNING" "$1" &&
22+
test_i18ngrep "$PREV_HEAD_DESC" "$1"
2023
}
2124

2225
reset () {

0 commit comments

Comments
 (0)