The SHA1 reference is either an index into a SHA1 table using the variable
length number encoding, or the literal 20 bytes SHA1 prefixed with a 0.

The index 0 discriminates between an actual index value or the literal
SHA1.  Therefore when the index is used its value must be increased by 1.

Signed-off-by: Nicolas Pitre <n...@fluxnic.net>
---
 packv4-create.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/packv4-create.c b/packv4-create.c
index 012129b..12527c0 100644
--- a/packv4-create.c
+++ b/packv4-create.c
@@ -12,6 +12,7 @@
 #include "object.h"
 #include "tree-walk.h"
 #include "pack.h"
+#include "varint.h"
 
 struct data_entry {
        unsigned offset;
@@ -245,6 +246,34 @@ static void dict_dump(void)
        dump_dict_table(tree_path_table);
 }
 
+/*
+ * Encode an object SHA1 reference with either an object index into the
+ * pack SHA1 table incremented by 1, or the literal SHA1 value prefixed
+ * with a zero byte if the needed SHA1 is not available in the table.
+ */
+static struct pack_idx_entry *all_objs;
+static unsigned all_objs_nr;
+static int encode_sha1ref(const unsigned char *sha1, unsigned char *buf)
+{
+       unsigned lo = 0, hi = all_objs_nr;
+
+       do {
+               unsigned mi = (lo + hi) / 2;
+               int cmp = hashcmp(all_objs[mi].sha1, sha1);
+
+               if (cmp == 0)
+                       return encode_varint(mi + 1, buf);
+               if (cmp > 0)
+                       hi = mi;
+               else
+                       lo = mi+1;
+       } while (lo < hi);
+
+       *buf++ = 0;
+       hashcpy(buf, sha1);
+       return 1 + 20;
+}
+
 static struct pack_idx_entry *get_packed_object_list(struct packed_git *p)
 {
        unsigned i, nr_objects = p->num_objects;
-- 
1.8.4.38.g317e65b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to