]> git.ipfire.org Git - thirdparty/git.git/blobdiff - object-name.c
Merge branch 'tb/make-indent-conditional-with-non-spaces'
[thirdparty/git.git] / object-name.c
index bd77695d7eac539ff114c4b6a031cdd81931d7d8..523af6f64f33512d1d7587bf0ce96cbe23b63b94 100644 (file)
@@ -23,6 +23,7 @@
 #include "midx.h"
 #include "commit-reach.h"
 #include "date.h"
+#include "object-file-convert.h"
 
 static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);
 
@@ -47,6 +48,7 @@ struct disambiguate_state {
 
 static void update_candidates(struct disambiguate_state *ds, const struct object_id *current)
 {
+       /* The hash algorithm of current has already been filtered */
        if (ds->always_call_fn) {
                ds->ambiguous = ds->fn(ds->repo, current, ds->cb_data) ? 1 : 0;
                return;
@@ -132,6 +134,8 @@ static void unique_in_midx(struct multi_pack_index *m,
 {
        uint32_t num, i, first = 0;
        const struct object_id *current = NULL;
+       int len = ds->len > ds->repo->hash_algo->hexsz ?
+               ds->repo->hash_algo->hexsz : ds->len;
        num = m->num_objects;
 
        if (!num)
@@ -147,7 +151,7 @@ static void unique_in_midx(struct multi_pack_index *m,
        for (i = first; i < num && !ds->ambiguous; i++) {
                struct object_id oid;
                current = nth_midxed_object_oid(&oid, m, i);
-               if (!match_hash(ds->len, ds->bin_pfx.hash, current->hash))
+               if (!match_hash(len, ds->bin_pfx.hash, current->hash))
                        break;
                update_candidates(ds, current);
        }
@@ -157,6 +161,8 @@ static void unique_in_pack(struct packed_git *p,
                           struct disambiguate_state *ds)
 {
        uint32_t num, i, first = 0;
+       int len = ds->len > ds->repo->hash_algo->hexsz ?
+               ds->repo->hash_algo->hexsz : ds->len;
 
        if (p->multi_pack_index)
                return;
@@ -175,7 +181,7 @@ static void unique_in_pack(struct packed_git *p,
        for (i = first; i < num && !ds->ambiguous; i++) {
                struct object_id oid;
                nth_packed_object_id(&oid, p, i);
-               if (!match_hash(ds->len, ds->bin_pfx.hash, oid.hash))
+               if (!match_hash(len, ds->bin_pfx.hash, oid.hash))
                        break;
                update_candidates(ds, &oid);
        }
@@ -186,6 +192,10 @@ static void find_short_packed_object(struct disambiguate_state *ds)
        struct multi_pack_index *m;
        struct packed_git *p;
 
+       /* Skip, unless oids from the storage hash algorithm are wanted */
+       if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo))
+               return;
+
        for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous;
             m = m->next)
                unique_in_midx(m, ds);
@@ -324,11 +334,12 @@ int set_disambiguate_hint_config(const char *var, const char *value)
 
 static int init_object_disambiguation(struct repository *r,
                                      const char *name, int len,
+                                     const struct git_hash_algo *algo,
                                      struct disambiguate_state *ds)
 {
        int i;
 
-       if (len < MINIMUM_ABBREV || len > the_hash_algo->hexsz)
+       if (len < MINIMUM_ABBREV || len > GIT_MAX_HEXSZ)
                return -1;
 
        memset(ds, 0, sizeof(*ds));
@@ -355,6 +366,7 @@ static int init_object_disambiguation(struct repository *r,
        ds->len = len;
        ds->hex_pfx[len] = '\0';
        ds->repo = r;
+       ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
        prepare_alt_odb(r);
        return 0;
 }
@@ -489,9 +501,10 @@ static int repo_collect_ambiguous(struct repository *r UNUSED,
        return collect_ambiguous(oid, data);
 }
 
-static int sort_ambiguous(const void *a, const void *b, void *ctx)
+static int sort_ambiguous(const void *va, const void *vb, void *ctx)
 {
        struct repository *sort_ambiguous_repo = ctx;
+       const struct object_id *a = va, *b = vb;
        int a_type = oid_object_info(sort_ambiguous_repo, a, NULL);
        int b_type = oid_object_info(sort_ambiguous_repo, b, NULL);
        int a_type_sort;
@@ -501,8 +514,12 @@ static int sort_ambiguous(const void *a, const void *b, void *ctx)
         * Sorts by hash within the same object type, just as
         * oid_array_for_each_unique() would do.
         */
-       if (a_type == b_type)
-               return oidcmp(a, b);
+       if (a_type == b_type) {
+               if (a->algo == b->algo)
+                       return oidcmp(a, b);
+               else
+                       return a->algo > b->algo ? 1 : -1;
+       }
 
        /*
         * Between object types show tags, then commits, and finally
@@ -531,8 +548,12 @@ static enum get_oid_result get_short_oid(struct repository *r,
        int status;
        struct disambiguate_state ds;
        int quietly = !!(flags & GET_OID_QUIETLY);
+       const struct git_hash_algo *algo = r->hash_algo;
+
+       if (flags & GET_OID_HASH_ANY)
+               algo = NULL;
 
-       if (init_object_disambiguation(r, name, len, &ds) < 0)
+       if (init_object_disambiguation(r, name, len, algo, &ds) < 0)
                return -1;
 
        if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
@@ -586,7 +607,7 @@ static enum get_oid_result get_short_oid(struct repository *r,
                if (!ds.ambiguous)
                        ds.fn = NULL;
 
-               repo_for_each_abbrev(r, ds.hex_pfx, collect_ambiguous, &collect);
+               repo_for_each_abbrev(r, ds.hex_pfx, algo, collect_ambiguous, &collect);
                sort_ambiguous_oid_array(r, &collect);
 
                if (oid_array_for_each(&collect, show_ambiguous_object, &out))
@@ -608,13 +629,14 @@ static enum get_oid_result get_short_oid(struct repository *r,
 }
 
 int repo_for_each_abbrev(struct repository *r, const char *prefix,
+                        const struct git_hash_algo *algo,
                         each_abbrev_fn fn, void *cb_data)
 {
        struct oid_array collect = OID_ARRAY_INIT;
        struct disambiguate_state ds;
        int ret;
 
-       if (init_object_disambiguation(r, prefix, strlen(prefix), &ds) < 0)
+       if (init_object_disambiguation(r, prefix, strlen(prefix), algo, &ds) < 0)
                return -1;
 
        ds.always_call_fn = 1;
@@ -785,10 +807,12 @@ void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
 int repo_find_unique_abbrev_r(struct repository *r, char *hex,
                              const struct object_id *oid, int len)
 {
+       const struct git_hash_algo *algo =
+               oid->algo ? &hash_algos[oid->algo] : r->hash_algo;
        struct disambiguate_state ds;
        struct min_abbrev_data mad;
        struct object_id oid_ret;
-       const unsigned hexsz = r->hash_algo->hexsz;
+       const unsigned hexsz = algo->hexsz;
 
        if (len < 0) {
                unsigned long count = repo_approximate_object_count(r);
@@ -824,7 +848,7 @@ int repo_find_unique_abbrev_r(struct repository *r, char *hex,
 
        find_abbrev_len_packed(&mad);
 
-       if (init_object_disambiguation(r, hex, mad.cur_len, &ds) < 0)
+       if (init_object_disambiguation(r, hex, mad.cur_len, algo, &ds) < 0)
                return -1;
 
        ds.fn = repo_extend_abbrev_len;