From ecd6fdf1f70b785f24e2d17bec516ac88be0cf2c Mon Sep 17 00:00:00 2001 From: Marc Pegon Date: Fri, 27 May 2011 18:49:09 +0200 Subject: [PATCH] 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). --- include/git2/odb_backend.h | 13 +++++++++++++ src/backends/hiredis.c | 16 ++++++++++++++++ src/backends/sqlite.c | 16 ++++++++++++++++ src/odb_loose.c | 15 +++++++++++++++ src/odb_pack.c | 15 +++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index ba41f726c..44049b6f1 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 f0c5da234..739e3bbef 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 abf14f180..c9c3b8049 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 9fb86f8bf..41b7f0b4d 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 574fbc639..3125a8c94 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;