fix insert_ref() to provide ordering similar to path lists
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
diff --git a/lib/reference.c b/lib/reference.c
index 5bf2f2a..978e204 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -460,39 +460,47 @@ insert_ref(struct got_reflist_head *refs, struct got_reference *ref,
{
const struct got_error *err;
struct got_object_id *id;
- struct got_reflist_entry *re, *prev = NULL;
+ struct got_reflist_entry *new, *re, *prev;
int cmp;
+ err = got_ref_resolve(&id, repo, ref);
+ if (err)
+ return err;
+
+ new = malloc(sizeof(*re));
+ if (new == NULL) {
+ free(id);
+ return got_error_from_errno();
+ }
+ new->ref = ref;
+ new->id = id;
+
/*
* We must de-duplicate entries on insert because packed-refs may
* contain redundant entries. On-disk refs take precedence.
* This code assumes that on-disk revs are read before packed-refs.
* We're iterating the list anyway, so insert elements sorted by name.
*/
- SIMPLEQ_FOREACH(re, refs, entry) {
- cmp = strcmp(got_ref_get_name(re->ref), got_ref_get_name(ref));
+ re = SIMPLEQ_FIRST(refs);
+ while (re) {
+ cmp = got_path_cmp(got_ref_get_name(re->ref),
+ got_ref_get_name(ref));
if (cmp == 0) {
- free(ref);
+ free(ref); /* duplicate */
return NULL;
- } else if (cmp > 0)
- break;
- else
+ } else if (cmp > 0) {
+ if (prev)
+ SIMPLEQ_INSERT_AFTER(refs, prev, new, entry);
+ else
+ SIMPLEQ_INSERT_HEAD(refs, new, entry);
+ return NULL;
+ } else {
prev = re;
+ re = SIMPLEQ_NEXT(re, entry);
+ }
}
- err = got_ref_resolve(&id, repo, ref);
- if (err)
- return err;
- re = malloc(sizeof(*re));
- if (re == NULL)
- return got_error_from_errno();
- re->ref = ref;
- re->id = id;
- if (prev)
- SIMPLEQ_INSERT_AFTER(refs, prev, re, entry);
- else
- SIMPLEQ_INSERT_TAIL(refs, re, entry);
-
+ SIMPLEQ_INSERT_TAIL(refs, new, entry);
return NULL;
}