ref_iterator: keep track of whether the iterator output is ordered
References are iterated over in order by refname, but reflogs are not. Some consumers of reference iteration care about the difference. Teach each `ref_iterator` to keep track of whether its output is ordered. `overlay_ref_iterator` is one of the picky consumers. Add a sanity check in `overlay_ref_iterator_begin()` to verify that its inputs are ordered. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
5e00a6c873
commit
8738a8a4df
@ -25,9 +25,11 @@ int ref_iterator_abort(struct ref_iterator *ref_iterator)
|
||||
}
|
||||
|
||||
void base_ref_iterator_init(struct ref_iterator *iter,
|
||||
struct ref_iterator_vtable *vtable)
|
||||
struct ref_iterator_vtable *vtable,
|
||||
int ordered)
|
||||
{
|
||||
iter->vtable = vtable;
|
||||
iter->ordered = !!ordered;
|
||||
iter->refname = NULL;
|
||||
iter->oid = NULL;
|
||||
iter->flags = 0;
|
||||
@ -72,7 +74,7 @@ struct ref_iterator *empty_ref_iterator_begin(void)
|
||||
struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter));
|
||||
struct ref_iterator *ref_iterator = &iter->base;
|
||||
|
||||
base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable);
|
||||
base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1);
|
||||
return ref_iterator;
|
||||
}
|
||||
|
||||
@ -205,6 +207,7 @@ static struct ref_iterator_vtable merge_ref_iterator_vtable = {
|
||||
};
|
||||
|
||||
struct ref_iterator *merge_ref_iterator_begin(
|
||||
int ordered,
|
||||
struct ref_iterator *iter0, struct ref_iterator *iter1,
|
||||
ref_iterator_select_fn *select, void *cb_data)
|
||||
{
|
||||
@ -219,7 +222,7 @@ struct ref_iterator *merge_ref_iterator_begin(
|
||||
* references through only if they exist in both iterators.
|
||||
*/
|
||||
|
||||
base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable);
|
||||
base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered);
|
||||
iter->iter0 = iter0;
|
||||
iter->iter1 = iter1;
|
||||
iter->select = select;
|
||||
@ -268,9 +271,11 @@ struct ref_iterator *overlay_ref_iterator_begin(
|
||||
} else if (is_empty_ref_iterator(back)) {
|
||||
ref_iterator_abort(back);
|
||||
return front;
|
||||
} else if (!front->ordered || !back->ordered) {
|
||||
BUG("overlay_ref_iterator requires ordered inputs");
|
||||
}
|
||||
|
||||
return merge_ref_iterator_begin(front, back,
|
||||
return merge_ref_iterator_begin(1, front, back,
|
||||
overlay_iterator_select, NULL);
|
||||
}
|
||||
|
||||
@ -361,7 +366,7 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
|
||||
iter = xcalloc(1, sizeof(*iter));
|
||||
ref_iterator = &iter->base;
|
||||
|
||||
base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable);
|
||||
base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered);
|
||||
|
||||
iter->iter0 = iter0;
|
||||
iter->prefix = xstrdup(prefix);
|
||||
|
Reference in New Issue
Block a user