refs/files: simplify iterating through root refs

When iterating through root refs we first need to determine the directory in which the refs live. This is done by retrieving the root of the loose refs via `refs->loose->root->name`, and putting it through `files_ref_path()` to derive the final path. This is somewhat redundant though: the root name of the loose files cache is always going to be the empty string. As such, we always end up passing that empty string to `files_ref_path()` as the ref hierarchy we want to start. And this actually makes sense: `files_ref_path()` already computes the location of the root directory, so of course we need to pass the empty string for the ref hierarchy itself. So going via the loose ref cache to figure out that the root of a ref hierarchy is empty is only causing confusion. But next to the added confusion, it can also lead to a segfault. The loose ref cache is populated lazily, so it may not always be set. It seems to be sheer luck that this is a condition we do not currently hit. The right thing to do would be to call `get_loose_ref_cache()`, which knows to populate the cache if required. Simplify the code and fix the potential segfault by simply removing the indirection via the loose ref cache completely. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 12, 2026 at 10:02 UTC df971a7c42fa5506cb7e845ac175104093c35e8d
1 file changed +3 -8
refs/files-backend.c
+3 -8
@@ -354,13 +354,11 @@ static int for_each_root_ref(struct files_ref_store *refs,
354 void *cb_data)
355 {
356 struct strbuf path = STRBUF_INIT, refname = STRBUF_INIT;
357 - const char *dirname = refs->loose->root->name;
357 struct dirent *de;
359 - size_t dirnamelen;
358 int ret;
359 DIR *d;
360
363 - files_ref_path(refs, &path, dirname);
361 + files_ref_path(refs, &path, "");
362
363 d = opendir(path.buf);
364 if (!d) {
@@ -368,9 +366,6 @@ static int for_each_root_ref(struct files_ref_store *refs,
366 return -1;
367 }
368
371 - strbuf_addstr(&refname, dirname);
372 - dirnamelen = refname.len;
373 -
369 while ((de = readdir(d)) != NULL) {
370 unsigned char dtype;
371
@@ -378,6 +373,8 @@ static int for_each_root_ref(struct files_ref_store *refs,
373 continue;
374 if (ends_with(de->d_name, ".lock"))
375 continue;
376 +
377 + strbuf_reset(&refname);
378 strbuf_addstr(&refname, de->d_name);
379
380 dtype = get_dtype(de, &path, 1);
@@ -386,8 +383,6 @@ static int for_each_root_ref(struct files_ref_store *refs,
383 if (ret)
384 goto done;
385 }
389 -
390 - strbuf_setlen(&refname, dirnamelen);
386 }
387
388 ret = 0;