Added a read_unique_short_oid method to backends, to make it possible to find objects from sha1 prefixes in the future. Default implementations throw GIT_ENOTIMPLEMENTED for strict prefixes (i.e. length < GIT_OID_HEXSZ).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index ba41f72..44049b6 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -49,6 +49,19 @@ struct git_odb_backend {
struct git_odb_backend *,
const git_oid *);
+ /* To find a unique object given a prefix
+ * of its oid.
+ * The oid given must be so that the
+ * remaining (GIT_OID_HEXSZ - len)*4 bits
+ * are 0s.
+ */
+ int (* read_unique_short_oid)(
+ git_oid *,
+ void **, size_t *, git_otype *,
+ struct git_odb_backend *,
+ const git_oid *,
+ unsigned int len);
+
int (* read_header)(
size_t *, git_otype *,
struct git_odb_backend *,
diff --git a/src/backends/hiredis.c b/src/backends/hiredis.c
index f0c5da2..739e3bb 100644
--- a/src/backends/hiredis.c
+++ b/src/backends/hiredis.c
@@ -107,6 +107,21 @@ int hiredis_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_o
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to read backend");
}
+int hiredis_backend__read_unique_short_oid(git_oid *out_oid, void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend,
+ const git_oid *short_oid, unsigned int len) {
+ if (len >= GIT_OID_HEXSZ) {
+ /* Just match the full identifier */
+ int error = hiredis_backend__read(data_p, len_p, type_p, backend, short_oid);
+ if (error == GIT_SUCCESS)
+ git_oid_cpy(out_oid, short_oid);
+
+ return error;
+ } else if (len < GIT_OID_HEXSZ) {
+ /* TODO */
+ return git__throw(GIT_ENOTIMPLEMENTED, "Hiredis backend cannot search objects from short oid");
+ }
+}
+
int hiredis_backend__exists(git_odb_backend *_backend, const git_oid *oid) {
hiredis_backend *backend;
int found;
@@ -174,6 +189,7 @@ int git_odb_backend_hiredis(git_odb_backend **backend_out, const char *host, int
goto cleanup;
backend->parent.read = &hiredis_backend__read;
+ backend->parent.read_unique_short_oid = &hiredis_backend__read_unique_short_oid;
backend->parent.read_header = &hiredis_backend__read_header;
backend->parent.write = &hiredis_backend__write;
backend->parent.exists = &hiredis_backend__exists;
diff --git a/src/backends/sqlite.c b/src/backends/sqlite.c
index abf14f1..c9c3b80 100644
--- a/src/backends/sqlite.c
+++ b/src/backends/sqlite.c
@@ -103,6 +103,21 @@ int sqlite_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_od
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "SQLite backend: Failed to read");
}
+int sqlite_backend__read_unique_short_oid(git_oid *out_oid, void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend,
+ const git_oid *short_oid, unsigned int len) {
+ if (len >= GIT_OID_HEXSZ) {
+ /* Just match the full identifier */
+ int error = sqlite_backend__read(data_p, len_p, type_p, _backend, short_oid);
+ if (error == GIT_SUCCESS)
+ git_oid_cpy(out_oid, short_oid);
+
+ return error;
+ } else if (len < GIT_OID_HEXSZ) {
+ /* TODO */
+ return git__throw(GIT_ENOTIMPLEMENTED, "Sqlite backend cannot search objects from short oid");
+ }
+}
+
int sqlite_backend__exists(git_odb_backend *_backend, const git_oid *oid)
{
sqlite_backend *backend;
@@ -255,6 +270,7 @@ int git_odb_backend_sqlite(git_odb_backend **backend_out, const char *sqlite_db)
goto cleanup;
backend->parent.read = &sqlite_backend__read;
+ backend->parent.read_unique_short_oid = &sqlite_backend__read_unique_short_oid;
backend->parent.read_header = &sqlite_backend__read_header;
backend->parent.write = &sqlite_backend__write;
backend->parent.exists = &sqlite_backend__exists;
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 9fb86f8..41b7f0b 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -524,6 +524,20 @@ int loose_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_o
return GIT_SUCCESS;
}
+int loose_backend__read_unique_short_oid(git_oid *out_oid, void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend,
+ const git_oid *short_oid, unsigned int len)
+{
+ if (len >= GIT_OID_HEXSZ) {
+ int error = loose_backend__read(buffer_p, len_p, type_p, backend, short_oid);
+ if (error == GIT_SUCCESS)
+ git_oid_cpy(out_oid, short_oid);
+
+ return error;
+ } else if (len < GIT_OID_HEXSZ) {
+ return git__throw(GIT_ENOTIMPLEMENTED, "Loose backend cannot search objects from short oid");
+ }
+}
+
int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
{
char object_path[GIT_PATH_MAX];
@@ -663,6 +677,7 @@ int git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir
backend->fsync_object_files = 0;
backend->parent.read = &loose_backend__read;
+ backend->parent.read_unique_short_oid = &loose_backend__read_unique_short_oid;
backend->parent.read_header = &loose_backend__read_header;
backend->parent.writestream = &loose_backend__stream;
backend->parent.exists = &loose_backend__exists;
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 574fbc6..3125a8c 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -1364,6 +1364,20 @@ int pack_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p, git_od
return GIT_SUCCESS;
}
+int pack_backend__read_unique_short_oid(git_oid *out_oid, void **buffer_p, size_t *len_p, git_otype *type_p, git_odb_backend *backend,
+ const git_oid *short_oid, unsigned int len)
+{
+ if (len >= GIT_OID_HEXSZ) {
+ int error = pack_backend__read(buffer_p, len_p, type_p, backend, short_oid);
+ if (error == GIT_SUCCESS)
+ git_oid_cpy(out_oid, short_oid);
+
+ return error;
+ } else if (len < GIT_OID_HEXSZ) {
+ return git__throw(GIT_ENOTIMPLEMENTED, "Pack backend cannot search objects from short oid");
+ }
+}
+
int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
{
struct pack_entry e;
@@ -1418,6 +1432,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
}
backend->parent.read = &pack_backend__read;
+ backend->parent.read_unique_short_oid = &pack_backend__read_unique_short_oid;
backend->parent.read_header = NULL;
backend->parent.exists = &pack_backend__exists;
backend->parent.free = &pack_backend__free;