summaryrefslogtreecommitdiff
path: root/src/odb.c
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2014-03-06 00:47:05 +0100
committerVicent Marti <vicent@github.com>2014-03-06 00:47:05 +0100
commita064dc2d0b6206116a35be4b62c58c3c1170d5de (patch)
treeca3a9de862d9ec7042d5446a302cb8cf924618e1 /src/odb.c
parenta62ad3c353380fb95d0f482859b445d430018aa9 (diff)
parent26875825df19d484c24921e355963e75dc0a4476 (diff)
downloadlibgit2-a064dc2d0b6206116a35be4b62c58c3c1170d5de.tar.gz
Merge pull request #2159 from libgit2/rb/odb-exists-prefix
Add ODB API to check for existence by prefix and object id shortener
Diffstat (limited to 'src/odb.c')
-rw-r--r--src/odb.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/src/odb.c b/src/odb.c
index 139949e31..30bba9603 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -635,6 +635,61 @@ int git_odb_exists(git_odb *db, const git_oid *id)
return (int)found;
}
+int git_odb_exists_prefix(
+ git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
+{
+ int error = GIT_ENOTFOUND, num_found = 0;
+ size_t i;
+ git_oid last_found = {{0}}, found;
+
+ assert(db && short_id);
+
+ if (len < GIT_OID_MINPREFIXLEN)
+ return git_odb__error_ambiguous("prefix length too short");
+ if (len > GIT_OID_HEXSZ)
+ len = GIT_OID_HEXSZ;
+
+ if (len == GIT_OID_HEXSZ) {
+ if (git_odb_exists(db, short_id)) {
+ if (out)
+ git_oid_cpy(out, short_id);
+ return 0;
+ } else {
+ return git_odb__error_notfound("no match for id prefix", short_id);
+ }
+ }
+
+ for (i = 0; i < db->backends.length; ++i) {
+ backend_internal *internal = git_vector_get(&db->backends, i);
+ git_odb_backend *b = internal->backend;
+
+ if (!b->exists_prefix)
+ continue;
+
+ error = b->exists_prefix(&found, b, short_id, len);
+ if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
+ continue;
+ if (error)
+ return error;
+
+ /* make sure found item doesn't introduce ambiguity */
+ if (num_found) {
+ if (git_oid__cmp(&last_found, &found))
+ return git_odb__error_ambiguous("multiple matches for prefix");
+ } else {
+ git_oid_cpy(&last_found, &found);
+ num_found++;
+ }
+ }
+
+ if (!num_found)
+ return git_odb__error_notfound("no match for id prefix", short_id);
+ if (out)
+ git_oid_cpy(out, &last_found);
+
+ return error;
+}
+
int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id)
{
int error;
@@ -745,7 +800,6 @@ int git_odb_read_prefix(
if (len < GIT_OID_MINPREFIXLEN)
return git_odb__error_ambiguous("prefix length too short");
-
if (len > GIT_OID_HEXSZ)
len = GIT_OID_HEXSZ;