diff options
author | Vicent Marti <vicent@github.com> | 2014-03-06 00:47:05 +0100 |
---|---|---|
committer | Vicent Marti <vicent@github.com> | 2014-03-06 00:47:05 +0100 |
commit | a064dc2d0b6206116a35be4b62c58c3c1170d5de (patch) | |
tree | ca3a9de862d9ec7042d5446a302cb8cf924618e1 /src/odb.c | |
parent | a62ad3c353380fb95d0f482859b445d430018aa9 (diff) | |
parent | 26875825df19d484c24921e355963e75dc0a4476 (diff) | |
download | libgit2-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.c | 56 |
1 files changed, 55 insertions, 1 deletions
@@ -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; |