diff options
author | Russell Belfer <rb@github.com> | 2014-03-04 15:34:23 -0800 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2014-03-04 15:34:23 -0800 |
commit | f5753999e4cac020c2dd3a4669fe9ba14df93cb5 (patch) | |
tree | 13e38551546181a59c0dae367192008c555e1fee /src/odb.c | |
parent | 0a62caf4e4927cbf74f40d8a2cb44b84267a30da (diff) | |
download | libgit2-f5753999e4cac020c2dd3a4669fe9ba14df93cb5.tar.gz |
Add exists_prefix to ODB backend and ODB API
Diffstat (limited to 'src/odb.c')
-rw-r--r-- | src/odb.c | 55 |
1 files changed, 55 insertions, 0 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; |