reflog: change one->many worktree->refnames to use a string_list

Change the FLEX_ARRAY pattern added in bda3a31cc79 (reflog-expire: Avoid creating new files in a directory inside readdir(3) loop, 2008-01-25) the string-list API instead. This does not change any behavior, allows us to delete much of this code as it's replaced by things we get from the string-list API for free, as a result we need just one struct to keep track of this data, instead of two. The "DUP" -> "string_list_append_nodup(..., strbuf_detach(...))" pattern here is the same as that used in a recent memory leak fix in b202e51b154 (grep: fix a "path_list" memory leak, 2021-10-22). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Dec 22, 2021 at 05:06 UTC f2919bae9836d552a399b67f4f7d26d30128b6d5
1 file changed +18 -29
builtin/reflog.c
+18 -29
@@ -48,16 +48,9 @@ struct expire_reflog_policy_cb {
48 struct commit_list *tips;
49 };
50
51 -struct collected_reflog {
52 - struct object_id oid;
53 - char reflog[FLEX_ARRAY];
54 -};
55 -
56 -struct collect_reflog_cb {
57 - struct collected_reflog **e;
58 - int alloc;
59 - int nr;
60 - struct worktree *wt;
51 +struct worktree_reflogs {
52 + struct worktree *worktree;
53 + struct string_list reflogs;
54 };
55
56 /* Remember to update object flag allocation in object.h */
@@ -403,24 +396,20 @@ static void reflog_expiry_cleanup(void *cb_data)
396
397 static int collect_reflog(const char *ref, const struct object_id *oid, int unused, void *cb_data)
398 {
406 - struct collected_reflog *e;
407 - struct collect_reflog_cb *cb = cb_data;
399 + struct worktree_reflogs *cb = cb_data;
400 + struct worktree *worktree = cb->worktree;
401 struct strbuf newref = STRBUF_INIT;
402
403 /*
404 * Avoid collecting the same shared ref multiple times because
405 * they are available via all worktrees.
406 */
414 - if (!cb->wt->is_current && ref_type(ref) == REF_TYPE_NORMAL)
407 + if (!worktree->is_current && ref_type(ref) == REF_TYPE_NORMAL)
408 return 0;
409
417 - strbuf_worktree_ref(cb->wt, &newref, ref);
418 - FLEX_ALLOC_STR(e, reflog, newref.buf);
419 - strbuf_release(&newref);
410 + strbuf_worktree_ref(worktree, &newref, ref);
411 + string_list_append_nodup(&cb->reflogs, strbuf_detach(&newref, NULL));
412
421 - oidcpy(&e->oid, oid);
422 - ALLOC_GROW(cb->e, cb->nr + 1, cb->alloc);
423 - cb->e[cb->nr++] = e;
413 return 0;
414 }
415
@@ -609,33 +598,33 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
598 }
599
600 if (do_all) {
612 - struct collect_reflog_cb collected;
601 + struct worktree_reflogs collected = {
602 + .reflogs = STRING_LIST_INIT_DUP,
603 + };
604 + struct string_list_item *item;
605 struct worktree **worktrees, **p;
614 - int i;
606
616 - memset(&collected, 0, sizeof(collected));
607 worktrees = get_worktrees();
608 for (p = worktrees; *p; p++) {
609 if (!all_worktrees && !(*p)->is_current)
610 continue;
621 - collected.wt = *p;
611 + collected.worktree = *p;
612 refs_for_each_reflog(get_worktree_ref_store(*p),
613 collect_reflog, &collected);
614 }
615 free_worktrees(worktrees);
626 - for (i = 0; i < collected.nr; i++) {
627 - struct collected_reflog *e = collected.e[i];
616 +
617 + for_each_string_list_item(item, &collected.reflogs) {
618 struct expire_reflog_policy_cb cb = { .cmd = cmd };
619
630 - set_reflog_expiry_param(&cb.cmd, explicit_expiry, e->reflog);
631 - status |= reflog_expire(e->reflog, flags,
620 + set_reflog_expiry_param(&cb.cmd, explicit_expiry, item->string);
621 + status |= reflog_expire(item->string, flags,
622 reflog_expiry_prepare,
623 should_expire_reflog_ent,
624 reflog_expiry_cleanup,
625 &cb);
636 - free(e);
626 }
638 - free(collected.e);
627 + string_list_clear(&collected.reflogs, 0);
628 }
629
630 for (; i < argc; i++) {