commit fb95e70d03a91abd90acdff115ea7aa7ce29b9a4 from: Stefan Sperling via: Thomas Adam date: Sat Nov 20 22:47:47 2021 UTC implement got_reflist_sort() which sorts a ref list in-place commit - e87a53ff87b118b0f2144d7d2e111986d2380240 commit + fb95e70d03a91abd90acdff115ea7aa7ce29b9a4 blob - 927c10b5f2d5bd38831138167a2c77e989ca9afe blob + dedfb8f826bb8de777445aaff9b19bc8a855d36e --- include/got_reference.h +++ include/got_reference.h @@ -140,6 +140,11 @@ const struct got_error * got_reflist_insert(struct got_reflist_entry **newp, struct got_reflist_head *refs, struct got_reference *ref, got_ref_cmp_cb cmp_cb, void *cmp_arg); +/* Sort a list of references with the provided comparison callback. */ +const struct got_error * +got_reflist_sort(struct got_reflist_head *refs, got_ref_cmp_cb cmp_cb, + void *cmp_arg); + /* Indicate whether the provided reference is symbolic (points at another * refernce) or not (points at an object ID). */ int got_ref_is_symbolic(struct got_reference *); blob - daf8aad1354470865d9b76172bd39ea13f3d397f blob + ef49f6ae3027c24639570e51b560c120d68f78e6 --- lib/reference.c +++ lib/reference.c @@ -888,7 +888,32 @@ got_reflist_insert(struct got_reflist_entry **newp, st TAILQ_INSERT_HEAD(refs, new, entry); return NULL; } + +const struct got_error * +got_reflist_sort(struct got_reflist_head *refs, + got_ref_cmp_cb cmp_cb, void *cmp_arg) +{ + const struct got_error *err = NULL; + struct got_reflist_entry *re, *tmp, *new; + struct got_reflist_head sorted; + TAILQ_INIT(&sorted); + + TAILQ_FOREACH_SAFE(re, refs, entry, tmp) { + struct got_reference *ref = re->ref; + TAILQ_REMOVE(refs, re, entry); + free(re); + err = got_reflist_insert(&new, &sorted, ref, cmp_cb, cmp_arg); + if (err || new == NULL /* duplicate */) + got_ref_close(ref); + if (err) + return err; + } + + TAILQ_CONCAT(refs, &sorted, entry); + return NULL; +} + static const struct got_error * gather_on_disk_refs(struct got_reflist_head *refs, const char *path_refs, const char *subdir, struct got_repository *repo,