Add the git_odb_exists() object query function This function determines if the given object can be found in the object database. At present, only the local object database is searched. Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
diff --git a/src/git/odb.h b/src/git/odb.h
index 0a7ee40..8a8cd3e 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 fc58168..f34fd00 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));