]> git.ipfire.org Git - thirdparty/git.git/commitdiff
object-name: move logic to compute loose abbreviation length
authorPatrick Steinhardt <ps@pks.im>
Fri, 20 Mar 2026 07:07:38 +0000 (08:07 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 20 Mar 2026 20:16:42 +0000 (13:16 -0700)
The function `repo_find_unique_abbrev_r()` takes as input an object ID
as well as a minimum object ID length and returns the minimum required
prefix to make the object ID unique.

The logic that computes the abbreviation length for loose objects is
deeply tied to the loose object storage format. As such, it would fail
in case a different object storage format was used.

Prepare for making this logic generic to the backend by moving the logic
into a new `odb_source_loose_find_abbrev_len()` function that is part of
"object-file.c".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file.c
object-file.h
object-name.c

index 13732f324f5bccfe84d2575d3da0fd13921dcef7..4f77ce0982625d996b189d8e6a70e3013f32260d 100644 (file)
@@ -1952,6 +1952,44 @@ out:
        return ret;
 }
 
+struct find_abbrev_len_data {
+       const struct object_id *oid;
+       unsigned len;
+};
+
+static int find_abbrev_len_cb(const struct object_id *oid,
+                             struct object_info *oi UNUSED,
+                             void *cb_data)
+{
+       struct find_abbrev_len_data *data = cb_data;
+       unsigned len = oid_common_prefix_hexlen(oid, data->oid);
+       if (len != hash_algos[oid->algo].hexsz && len >= data->len)
+               data->len = len + 1;
+       return 0;
+}
+
+int odb_source_loose_find_abbrev_len(struct odb_source *source,
+                                    const struct object_id *oid,
+                                    unsigned min_len,
+                                    unsigned *out)
+{
+       struct odb_for_each_object_options opts = {
+               .prefix = oid,
+               .prefix_hex_len = min_len,
+       };
+       struct find_abbrev_len_data data = {
+               .oid = oid,
+               .len = min_len,
+       };
+       int ret;
+
+       ret = odb_source_loose_for_each_object(source, NULL, find_abbrev_len_cb,
+                                              &data, &opts);
+       *out = data.len;
+
+       return ret;
+}
+
 static int append_loose_object(const struct object_id *oid,
                               const char *path UNUSED,
                               void *data)
index f11ad58f6c08745c84054a9af0a9b5e07699ec95..3686f182e4deb0b357e1a061c701578cef9ab016 100644 (file)
@@ -146,6 +146,18 @@ int odb_source_loose_count_objects(struct odb_source *source,
                                   enum odb_count_objects_flags flags,
                                   unsigned long *out);
 
+/*
+ * Find the shortest unique prefix for the given object ID, where `min_len` is
+ * the minimum length that the prefix should have.
+ *
+ * Returns 0 on success, in which case the computed length will be written to
+ * `out`. Otherwise, a negative error code is returned.
+ */
+int odb_source_loose_find_abbrev_len(struct odb_source *source,
+                                    const struct object_id *oid,
+                                    unsigned min_len,
+                                    unsigned *out);
+
 /**
  * format_object_header() is a thin wrapper around s xsnprintf() that
  * writes the initial "<type> <obj-len>" part of the loose object
index 32e9c23e402ab9b1ef010b53714448462baa4bcd..4e21dbfa97bf1ced6bca8446feae70d991b9796a 100644 (file)
@@ -598,28 +598,6 @@ static int extend_abbrev_len(const struct object_id *oid,
        return 0;
 }
 
-static int extend_abbrev_len_loose(const struct object_id *oid,
-                                  struct object_info *oi UNUSED,
-                                  void *cb_data)
-{
-       struct min_abbrev_data *data = cb_data;
-       extend_abbrev_len(oid, data);
-       return 0;
-}
-
-static void find_abbrev_len_loose(struct min_abbrev_data *mad)
-{
-       struct odb_for_each_object_options opts = {
-               .prefix = mad->oid,
-               .prefix_hex_len = mad->cur_len,
-       };
-       struct odb_source *source;
-
-       for (source = mad->repo->objects->sources; source; source = source->next)
-               odb_source_loose_for_each_object(source, NULL, extend_abbrev_len_loose,
-                                                mad, &opts);
-}
-
 static void find_abbrev_len_for_midx(struct multi_pack_index *m,
                                     struct min_abbrev_data *mad)
 {
@@ -772,7 +750,10 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
        mad.oid = oid;
 
        find_abbrev_len_packed(&mad);
-       find_abbrev_len_loose(&mad);
+
+       odb_prepare_alternates(r->objects);
+       for (struct odb_source *s = r->objects->sources; s; s = s->next)
+               odb_source_loose_find_abbrev_len(s, mad.oid, mad.cur_len, &mad.cur_len);
 
        hex[mad.cur_len] = 0;
        return mad.cur_len;