summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/git/odb.h11
-rw-r--r--src/odb.c60
2 files changed, 71 insertions, 0 deletions
diff --git a/src/git/odb.h b/src/git/odb.h
index 0a7ee40d3..8a8cd3e5f 100644
--- a/src/git/odb.h
+++ b/src/git/odb.h
@@ -152,6 +152,17 @@ GIT_EXTERN(int) git_obj__loose_object_type(git_otype type);
*/
GIT_EXTERN(int) git_obj_hash(git_oid *id, git_obj *obj);
+/**
+ * Determine if the given object can be found in the object database.
+ *
+ * @param db database to be searched for the given object.
+ * @param id the object to search for.
+ * @return
+ * - true, if the object was found
+ * - false, otherwise
+ */
+GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/odb.c b/src/odb.c
index fc58168ad..f34fd002b 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -819,6 +819,66 @@ static git_packlist *packlist_get(git_odb *db)
return pl;
}
+static int search_packs(git_pack **p, off_t *offset, git_odb *db, const git_oid *id)
+{
+ git_packlist *pl = packlist_get(db);
+ size_t j;
+
+ if (!pl)
+ return GIT_ENOTFOUND;
+
+ for (j = 0; j < pl->n_packs; j++) {
+
+ git_pack *pack = pl->packs[j];
+ off_t pos;
+ int res;
+
+ if (pack_openidx(pack))
+ continue;
+ res = pack->idx_search(&pos, pack, id);
+ pack_decidx(pack);
+
+ if (!res) {
+ packlist_dec(db,pl);
+ if (p)
+ *p = pack;
+ if (offset)
+ *offset = pos;
+ return GIT_SUCCESS;
+ }
+
+ }
+
+ packlist_dec(db,pl);
+ return GIT_ENOTFOUND;
+}
+
+static int exists_packed(git_odb *db, const git_oid *id)
+{
+ return !search_packs(NULL, NULL, db, id);
+}
+
+static int exists_loose(git_odb *db, const git_oid *id)
+{
+ char file[GIT_PATH_MAX];
+
+ if (object_file_name(file, sizeof(file), db->objects_dir, id) < 0)
+ return 0;
+
+ if (gitfo_exists(file) < 0)
+ return 0;
+
+ return 1;
+}
+
+int git_odb_exists(git_odb *db, const git_oid *id)
+{
+ /* TODO: extend to search alternate db's */
+ if (exists_packed(db, id))
+ return 1;
+ return exists_loose(db, id);
+}
+
int git_odb_open(git_odb **out, const char *objects_dir)
{
git_odb *db = git__calloc(1, sizeof(*db));