odb/source-packed: wire up `find_abbrev_len()` callback

Move `packfile_store_find_abbrev_len()` and its associated helpers from "packfile.c" into "odb/source-packed.c" and wire it up as the `find_abbrev_len()` callback of the "packed" source. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jun 17, 2026 at 08:39 UTC 3c0f7b732e37b885009cdc64a13541591ebab00e
4 files changed +114 -117
odb/source-files.c
+1 -1
@@ -133,7 +133,7 @@ static int odb_source_files_find_abbrev_len(struct odb_source *source,
133 unsigned len = min_len;
134 int ret;
135
136 - ret = packfile_store_find_abbrev_len(files->packed, oid, len, &len);
136 + ret = odb_source_find_abbrev_len(&files->packed->base, oid, len, &len);
137 if (ret < 0)
138 goto out;
139
odb/source-packed.c
+113
@@ -370,6 +370,118 @@ out:
370 return ret;
371 }
372
373 +static int extend_abbrev_len(const struct object_id *a,
374 + const struct object_id *b,
375 + unsigned *out)
376 +{
377 + unsigned len = oid_common_prefix_hexlen(a, b);
378 + if (len != hash_algos[a->algo].hexsz && len >= *out)
379 + *out = len + 1;
380 + return 0;
381 +}
382 +
383 +static void find_abbrev_len_for_midx(struct multi_pack_index *m,
384 + const struct object_id *oid,
385 + unsigned min_len,
386 + unsigned *out)
387 +{
388 + unsigned len = min_len;
389 +
390 + for (; m; m = m->base_midx) {
391 + int match = 0;
392 + uint32_t num, first = 0;
393 + struct object_id found_oid;
394 +
395 + if (!m->num_objects)
396 + continue;
397 +
398 + num = m->num_objects + m->num_objects_in_base;
399 + match = bsearch_one_midx(oid, m, &first);
400 +
401 + /*
402 + * first is now the position in the packfile where we
403 + * would insert the object ID if it does not exist (or the
404 + * position of the object ID if it does exist). Hence, we
405 + * consider a maximum of two objects nearby for the
406 + * abbreviation length.
407 + */
408 +
409 + if (!match) {
410 + if (nth_midxed_object_oid(&found_oid, m, first))
411 + extend_abbrev_len(&found_oid, oid, &len);
412 + } else if (first < num - 1) {
413 + if (nth_midxed_object_oid(&found_oid, m, first + 1))
414 + extend_abbrev_len(&found_oid, oid, &len);
415 + }
416 + if (first > 0) {
417 + if (nth_midxed_object_oid(&found_oid, m, first - 1))
418 + extend_abbrev_len(&found_oid, oid, &len);
419 + }
420 + }
421 +
422 + *out = len;
423 +}
424 +
425 +static void find_abbrev_len_for_pack(struct packed_git *p,
426 + const struct object_id *oid,
427 + unsigned min_len,
428 + unsigned *out)
429 +{
430 + int match;
431 + uint32_t num, first = 0;
432 + struct object_id found_oid;
433 + unsigned len = min_len;
434 +
435 + num = p->num_objects;
436 + match = bsearch_pack(oid, p, &first);
437 +
438 + /*
439 + * first is now the position in the packfile where we would insert
440 + * the object ID if it does not exist (or the position of mad->hash if
441 + * it does exist). Hence, we consider a maximum of two objects
442 + * nearby for the abbreviation length.
443 + */
444 + if (!match) {
445 + if (!nth_packed_object_id(&found_oid, p, first))
446 + extend_abbrev_len(&found_oid, oid, &len);
447 + } else if (first < num - 1) {
448 + if (!nth_packed_object_id(&found_oid, p, first + 1))
449 + extend_abbrev_len(&found_oid, oid, &len);
450 + }
451 + if (first > 0) {
452 + if (!nth_packed_object_id(&found_oid, p, first - 1))
453 + extend_abbrev_len(&found_oid, oid, &len);
454 + }
455 +
456 + *out = len;
457 +}
458 +
459 +static int odb_source_packed_find_abbrev_len(struct odb_source *source,
460 + const struct object_id *oid,
461 + unsigned min_len,
462 + unsigned *out)
463 +{
464 + struct odb_source_packed *packed = odb_source_packed_downcast(source);
465 + struct packfile_list_entry *e;
466 + struct multi_pack_index *m;
467 +
468 + m = get_multi_pack_index(&packed->files->base);
469 + if (m)
470 + find_abbrev_len_for_midx(m, oid, min_len, &min_len);
471 +
472 + for (e = packfile_store_get_packs(packed); e; e = e->next) {
473 + if (e->pack->multi_pack_index)
474 + continue;
475 + if (open_pack_index(e->pack) || !e->pack->num_objects)
476 + continue;
477 +
478 + find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len);
479 + }
480 +
481 + *out = min_len;
482 + return 0;
483 +}
484 +
485 void (*report_garbage)(unsigned seen_bits, const char *path);
486
487 static void report_helper(const struct string_list *list,
@@ -582,6 +694,7 @@ struct odb_source_packed *odb_source_packed_new(struct odb_source_files *parent)
694 packed->base.read_object_stream = odb_source_packed_read_object_stream;
695 packed->base.for_each_object = odb_source_packed_for_each_object;
696 packed->base.count_objects = odb_source_packed_count_objects;
697 + packed->base.find_abbrev_len = odb_source_packed_find_abbrev_len;
698
699 if (!is_absolute_path(parent->base.path))
700 chdir_notify_register(NULL, odb_source_packed_reparent, packed);
packfile.c
-111
@@ -2037,117 +2037,6 @@ int for_each_object_in_pack(struct packed_git *p,
2037 return r;
2038 }
2039
2040 -static int extend_abbrev_len(const struct object_id *a,
2041 - const struct object_id *b,
2042 - unsigned *out)
2043 -{
2044 - unsigned len = oid_common_prefix_hexlen(a, b);
2045 - if (len != hash_algos[a->algo].hexsz && len >= *out)
2046 - *out = len + 1;
2047 - return 0;
2048 -}
2049 -
2050 -static void find_abbrev_len_for_midx(struct multi_pack_index *m,
2051 - const struct object_id *oid,
2052 - unsigned min_len,
2053 - unsigned *out)
2054 -{
2055 - unsigned len = min_len;
2056 -
2057 - for (; m; m = m->base_midx) {
2058 - int match = 0;
2059 - uint32_t num, first = 0;
2060 - struct object_id found_oid;
2061 -
2062 - if (!m->num_objects)
2063 - continue;
2064 -
2065 - num = m->num_objects + m->num_objects_in_base;
2066 - match = bsearch_one_midx(oid, m, &first);
2067 -
2068 - /*
2069 - * first is now the position in the packfile where we
2070 - * would insert the object ID if it does not exist (or the
2071 - * position of the object ID if it does exist). Hence, we
2072 - * consider a maximum of two objects nearby for the
2073 - * abbreviation length.
2074 - */
2075 -
2076 - if (!match) {
2077 - if (nth_midxed_object_oid(&found_oid, m, first))
2078 - extend_abbrev_len(&found_oid, oid, &len);
2079 - } else if (first < num - 1) {
2080 - if (nth_midxed_object_oid(&found_oid, m, first + 1))
2081 - extend_abbrev_len(&found_oid, oid, &len);
2082 - }
2083 - if (first > 0) {
2084 - if (nth_midxed_object_oid(&found_oid, m, first - 1))
2085 - extend_abbrev_len(&found_oid, oid, &len);
2086 - }
2087 - }
2088 -
2089 - *out = len;
2090 -}
2091 -
2092 -static void find_abbrev_len_for_pack(struct packed_git *p,
2093 - const struct object_id *oid,
2094 - unsigned min_len,
2095 - unsigned *out)
2096 -{
2097 - int match;
2098 - uint32_t num, first = 0;
2099 - struct object_id found_oid;
2100 - unsigned len = min_len;
2101 -
2102 - num = p->num_objects;
2103 - match = bsearch_pack(oid, p, &first);
2104 -
2105 - /*
2106 - * first is now the position in the packfile where we would insert
2107 - * the object ID if it does not exist (or the position of mad->hash if
2108 - * it does exist). Hence, we consider a maximum of two objects
2109 - * nearby for the abbreviation length.
2110 - */
2111 - if (!match) {
2112 - if (!nth_packed_object_id(&found_oid, p, first))
2113 - extend_abbrev_len(&found_oid, oid, &len);
2114 - } else if (first < num - 1) {
2115 - if (!nth_packed_object_id(&found_oid, p, first + 1))
2116 - extend_abbrev_len(&found_oid, oid, &len);
2117 - }
2118 - if (first > 0) {
2119 - if (!nth_packed_object_id(&found_oid, p, first - 1))
2120 - extend_abbrev_len(&found_oid, oid, &len);
2121 - }
2122 -
2123 - *out = len;
2124 -}
2125 -
2126 -int packfile_store_find_abbrev_len(struct odb_source_packed *store,
2127 - const struct object_id *oid,
2128 - unsigned min_len,
2129 - unsigned *out)
2130 -{
2131 - struct packfile_list_entry *e;
2132 - struct multi_pack_index *m;
2133 -
2134 - m = get_multi_pack_index(&store->files->base);
2135 - if (m)
2136 - find_abbrev_len_for_midx(m, oid, min_len, &min_len);
2137 -
2138 - for (e = packfile_store_get_packs(store); e; e = e->next) {
2139 - if (e->pack->multi_pack_index)
2140 - continue;
2141 - if (open_pack_index(e->pack) || !e->pack->num_objects)
2142 - continue;
2143 -
2144 - find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len);
2145 - }
2146 -
2147 - *out = min_len;
2148 - return 0;
2149 -}
2150 -
2040 struct add_promisor_object_data {
2041 struct repository *repo;
2042 struct oidset *set;
packfile.h
-5
@@ -217,11 +217,6 @@ int for_each_object_in_pack(struct packed_git *p,
217 each_packed_object_fn, void *data,
218 enum odb_for_each_object_flags flags);
219
220 -int packfile_store_find_abbrev_len(struct odb_source_packed *store,
221 - const struct object_id *oid,
222 - unsigned min_len,
223 - unsigned *out);
224 -
220 /* A hook to report invalid files in pack directory */
221 #define PACKDIR_FILE_PACK 1
222 #define PACKDIR_FILE_IDX 2