refs/files: extract function to iterate through root refs

Extract a new function that can be used to iterate through all root refs known to the "files" backend. This will be used in the next commit, where we start to teach ref backends to remove themselves. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 6, 2024 at 07:29 UTC 120b67172f7858a70b36941fa31af58a0534020e
1 file changed +42 -9
refs/files-backend.c
+42 -9
@@ -323,17 +323,15 @@ static void loose_fill_ref_dir(struct ref_store *ref_store,
323 add_per_worktree_entries_to_dir(dir, dirname);
324 }
325
326 -/*
327 - * Add root refs to the ref dir by parsing the directory for any files which
328 - * follow the root ref syntax.
329 - */
330 -static void add_root_refs(struct files_ref_store *refs,
331 - struct ref_dir *dir)
326 +static int for_each_root_ref(struct files_ref_store *refs,
327 + int (*cb)(const char *refname, void *cb_data),
328 + void *cb_data)
329 {
330 struct strbuf path = STRBUF_INIT, refname = STRBUF_INIT;
331 const char *dirname = refs->loose->root->name;
332 struct dirent *de;
333 size_t dirnamelen;
334 + int ret;
335 DIR *d;
336
337 files_ref_path(refs, &path, dirname);
@@ -341,7 +339,7 @@ static void add_root_refs(struct files_ref_store *refs,
339 d = opendir(path.buf);
340 if (!d) {
341 strbuf_release(&path);
344 - return;
342 + return -1;
343 }
344
345 strbuf_addstr(&refname, dirname);
@@ -357,14 +355,49 @@ static void add_root_refs(struct files_ref_store *refs,
355 strbuf_addstr(&refname, de->d_name);
356
357 dtype = get_dtype(de, &path, 1);
360 - if (dtype == DT_REG && is_root_ref(de->d_name))
361 - loose_fill_ref_dir_regular_file(refs, refname.buf, dir);
358 + if (dtype == DT_REG && is_root_ref(de->d_name)) {
359 + ret = cb(refname.buf, cb_data);
360 + if (ret)
361 + goto done;
362 + }
363
364 strbuf_setlen(&refname, dirnamelen);
365 }
366 +
367 + ret = 0;
368 +
369 +done:
370 strbuf_release(&refname);
371 strbuf_release(&path);
372 closedir(d);
373 + return ret;
374 +}
375 +
376 +struct fill_root_ref_data {
377 + struct files_ref_store *refs;
378 + struct ref_dir *dir;
379 +};
380 +
381 +static int fill_root_ref(const char *refname, void *cb_data)
382 +{
383 + struct fill_root_ref_data *data = cb_data;
384 + loose_fill_ref_dir_regular_file(data->refs, refname, data->dir);
385 + return 0;
386 +}
387 +
388 +/*
389 + * Add root refs to the ref dir by parsing the directory for any files which
390 + * follow the root ref syntax.
391 + */
392 +static void add_root_refs(struct files_ref_store *refs,
393 + struct ref_dir *dir)
394 +{
395 + struct fill_root_ref_data data = {
396 + .refs = refs,
397 + .dir = dir,
398 + };
399 +
400 + for_each_root_ref(refs, fill_root_ref, &data);
401 }
402
403 static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs,