Create unique_in_midx() to mimic behavior of unique_in_pack().

Create find_abbrev_len_for_midx() to mimic behavior of
find_abbrev_len_for_pack().

Consume these methods when interacting with abbreviations.

Signed-off-by: Derrick Stolee <dsto...@microsoft.com>
---
 sha1_name.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 611c7d24dd..2f426e136e 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -10,6 +10,7 @@
 #include "dir.h"
 #include "sha1-array.h"
 #include "packfile.h"
+#include "midx.h"
 
 static int get_oid_oneline(const char *, struct object_id *, struct 
commit_list *);
 
@@ -190,11 +191,40 @@ static void unique_in_pack(struct packed_git *p,
        }
 }
 
+static void unique_in_midx(struct midxed_git *m,
+                          struct disambiguate_state *ds)
+{
+       uint32_t num, i, first = 0;
+       const struct object_id *current = NULL;
+
+       if (!m->num_objects)
+               return;
+
+       num = m->num_objects;
+       bsearch_midx(m, ds->bin_pfx.hash, &first);
+
+       /*
+        * At this point, "first" is the location of the lowest object
+        * with an object name that could match "bin_pfx".  See if we have
+        * 0, 1 or more objects that actually match(es).
+        */
+       for (i = first; i < num && !ds->ambiguous; i++) {
+               struct object_id oid;
+               current = nth_midxed_object_oid(&oid, m, i);
+               if (!match_sha(ds->len, ds->bin_pfx.hash, current->hash))
+                       break;
+               update_candidates(ds, current);
+       }
+}
+
 static void find_short_packed_object(struct disambiguate_state *ds)
 {
        struct packed_git *p;
+       struct midxed_git *m;
 
-       prepare_packed_git();
+       prepare_packed_git_internal(1);
+       for (m = midxed_git; m && !ds->ambiguous; m = m->next)
+               unique_in_midx(m, ds);
        for (p = packed_git; p && !ds->ambiguous; p = p->next)
                unique_in_pack(p, ds);
 }
@@ -508,6 +538,39 @@ static int extend_abbrev_len(const struct object_id *oid, 
void *cb_data)
        return 0;
 }
 
+static void find_abbrev_len_for_midx(struct midxed_git *m,
+                                    struct min_abbrev_data *mad)
+{
+       int match = 0;
+       uint32_t first = 0;
+       struct object_id oid;
+
+       if (!m->num_objects)
+               return;
+
+       match = bsearch_midx(m, mad->hash, &first);
+
+       /*
+        * first is now the position in the packfile where we would insert
+        * mad->hash if it does not exist (or the position of mad->hash if
+        * it does exist). Hence, we consider a maximum of three objects
+        * nearby for the abbreviation length.
+        */
+       mad->init_len = 0;
+       if (!match) {
+               nth_midxed_object_oid(&oid, m, first);
+               extend_abbrev_len(&oid, mad);
+       } else if (first < m->num_objects - 1) {
+               nth_midxed_object_oid(&oid, m, first + 1);
+               extend_abbrev_len(&oid, mad);
+       }
+       if (first > 0) {
+               nth_midxed_object_oid(&oid, m, first - 1);
+               extend_abbrev_len(&oid, mad);
+       }
+       mad->init_len = mad->cur_len;
+}
+
 static void find_abbrev_len_for_pack(struct packed_git *p,
                                     struct min_abbrev_data *mad)
 {
@@ -563,8 +626,11 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
 static void find_abbrev_len_packed(struct min_abbrev_data *mad)
 {
        struct packed_git *p;
+       struct midxed_git *m;
 
-       prepare_packed_git();
+       prepare_packed_git_internal(1);
+       for (m = midxed_git; m; m = m->next)
+               find_abbrev_len_for_midx(m, mad);
        for (p = packed_git; p; p = p->next)
                find_abbrev_len_for_pack(p, mad);
 }
-- 
2.15.0

Reply via email to