object-name: abbreviate loose object names without `disambiguate_state`

The function `find_short_object_filename()` takes an object ID and computes the minimum required object name length to make it unique. This is done by reusing the object disambiguation infrastructure, where we iterate through every loose object and then update the disambiguate state one by one. Ultimately, we don't care about the disambiguate state though. It is used because this infrastructure knows how to enumerate only those objects that match a given prefix. But now that we have extended the `odb_for_each_object()` function to do this for us we have an easier way to do this. Consequently, we really only use the disambiguate state now to propagate `struct min_abbrev_data`. Refactor the code and drop this indirection so that we use `struct min_abbrev_data` directly. This also allows us to drop some now-unused logic from the disambiguate infrastructure. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Mar 20, 2026 at 08:07 UTC 67f47eab61c3a2c14f2d0351c3844f12fbd95dd2
1 file changed +20 -34
object-name.c
+20 -34
@@ -48,7 +48,6 @@ struct disambiguate_state {
48 unsigned candidate_ok:1;
49 unsigned disambiguate_fn_used:1;
50 unsigned ambiguous:1;
51 - unsigned always_call_fn:1;
51 };
52
53 static int update_disambiguate_state(const struct object_id *current,
@@ -58,10 +57,6 @@ static int update_disambiguate_state(const struct object_id *current,
57 struct disambiguate_state *ds = cb_data;
58
59 /* The hash algorithm of current has already been filtered */
61 - if (ds->always_call_fn) {
62 - ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
63 - return ds->ambiguous;
64 - }
60 if (!ds->candidate_exists) {
61 /* this is the first candidate */
62 oidcpy(&ds->candidate, current);
@@ -107,19 +102,6 @@ static int update_disambiguate_state(const struct object_id *current,
102 return 0;
103 }
104
110 -static void find_short_object_filename(struct disambiguate_state *ds)
111 -{
112 - struct odb_for_each_object_options opts = {
113 - .prefix = &ds->bin_pfx,
114 - .prefix_hex_len = ds->len,
115 - };
116 - struct odb_source *source;
117 -
118 - for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next)
119 - odb_source_loose_for_each_object(source, NULL, update_disambiguate_state,
120 - ds, &opts);
121 -}
122 -
105 static int finish_object_disambiguation(struct disambiguate_state *ds,
106 struct object_id *oid)
107 {
@@ -632,11 +614,26 @@ static int extend_abbrev_len(const struct object_id *oid,
614 return 0;
615 }
616
635 -static int repo_extend_abbrev_len(struct repository *r UNUSED,
636 - const struct object_id *oid,
637 - void *cb_data)
617 +static int extend_abbrev_len_loose(const struct object_id *oid,
618 + struct object_info *oi UNUSED,
619 + void *cb_data)
620 {
639 - return extend_abbrev_len(oid, cb_data);
621 + struct min_abbrev_data *data = cb_data;
622 + extend_abbrev_len(oid, data);
623 + return 0;
624 +}
625 +
626 +static void find_abbrev_len_loose(struct min_abbrev_data *mad)
627 +{
628 + struct odb_for_each_object_options opts = {
629 + .prefix = mad->oid,
630 + .prefix_hex_len = mad->cur_len,
631 + };
632 + struct odb_source *source;
633 +
634 + for (source = mad->repo->objects->sources; source; source = source->next)
635 + odb_source_loose_for_each_object(source, NULL, extend_abbrev_len_loose,
636 + mad, &opts);
637 }
638
639 static void find_abbrev_len_for_midx(struct multi_pack_index *m,
@@ -752,9 +749,7 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
749 {
750 const struct git_hash_algo *algo =
751 oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
755 - struct disambiguate_state ds;
752 struct min_abbrev_data mad;
757 - struct object_id oid_ret;
753 const unsigned hexsz = algo->hexsz;
754
755 if (len < 0) {
@@ -794,16 +789,7 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
789 mad.oid = oid;
790
791 find_abbrev_len_packed(&mad);
797 -
798 - if (init_object_disambiguation(r, hex, mad.cur_len, algo, &ds) < 0)
799 - return -1;
800 -
801 - ds.fn = repo_extend_abbrev_len;
802 - ds.always_call_fn = 1;
803 - ds.cb_data = (void *)&mad;
804 -
805 - find_short_object_filename(&ds);
806 - (void)finish_object_disambiguation(&ds, &oid_ret);
792 + find_abbrev_len_loose(&mad);
793
794 hex[mad.cur_len] = 0;
795 return mad.cur_len;