Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@elego.de>2012-07-21 18:23:49 +0400
committerCarlos Martín Nieto <cmn@elego.de>2012-07-21 18:23:49 +0400
commit507523c32f71056a106f85712fe2086fdb94fbd0 (patch)
treed369f3f39a14fa48a06a24a632b1f1916b93670d
parent71d273583755c0a2b7f5d608f017f4586add51e4 (diff)
odb: allow creating an ODB backend from a packfile index
git_odb_backend_one_packfile() allows us to create an ODB backend out of an .idx file.
-rw-r--r--include/git2/odb_backend.h1
-rw-r--r--src/odb_pack.c35
-rw-r--r--tests-clar/odb/foreach.c23
-rw-r--r--tests-clar/odb/pack_data_one.h19
-rw-r--r--tests-clar/odb/packed_one.c58
5 files changed, 130 insertions, 6 deletions
diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h
index 3f67202d1..b93ef204f 100644
--- a/include/git2/odb_backend.h
+++ b/include/git2/odb_backend.h
@@ -100,6 +100,7 @@ struct git_odb_stream {
GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir);
GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync);
+GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **backend_out, const char *index_file);
GIT_END_DECL
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 4b860e864..0f34ebdf8 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -458,6 +458,41 @@ static void pack_backend__free(git_odb_backend *_backend)
git__free(backend);
}
+int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
+{
+ struct pack_backend *backend = NULL;
+ struct git_pack_file *packfile = NULL;
+
+ if (git_packfile_check(&packfile, idx) < 0)
+ return -1;
+
+ backend = git__calloc(1, sizeof(struct pack_backend));
+ GITERR_CHECK_ALLOC(backend);
+
+ if (git_vector_init(&backend->packs, 1, NULL) < 0)
+ goto on_error;
+
+ if (git_vector_insert(&backend->packs, packfile) < 0)
+ goto on_error;
+
+ backend->parent.read = &pack_backend__read;
+ backend->parent.read_prefix = &pack_backend__read_prefix;
+ backend->parent.read_header = NULL;
+ backend->parent.exists = &pack_backend__exists;
+ backend->parent.foreach = &pack_backend__foreach;
+ backend->parent.free = &pack_backend__free;
+
+ *backend_out = (git_odb_backend *)backend;
+
+ return 0;
+
+on_error:
+ git_vector_free(&backend->packs);
+ git__free(backend);
+ git__free(packfile);
+ return -1;
+}
+
int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
{
struct pack_backend *backend = NULL;
diff --git a/tests-clar/odb/foreach.c b/tests-clar/odb/foreach.c
index 525c70c09..9b90aff7b 100644
--- a/tests-clar/odb/foreach.c
+++ b/tests-clar/odb/foreach.c
@@ -7,12 +7,6 @@ static git_odb *_odb;
static git_repository *_repo;
static int nobj;
-void test_odb_foreach__initialize(void)
-{
- cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
- git_repository_odb(&_odb, _repo);
-}
-
void test_odb_foreach__cleanup(void)
{
git_odb_free(_odb);
@@ -31,6 +25,23 @@ static int foreach_cb(git_oid *oid, void *data)
void test_odb_foreach__foreach(void)
{
+ cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
+ git_repository_odb(&_odb, _repo);
+
cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL));
cl_assert(nobj == 1683);
}
+
+void test_odb_foreach__one_pack(void)
+{
+ git_odb_backend *backend = NULL;
+
+ cl_git_pass(git_odb_new(&_odb));
+ cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")));
+ cl_git_pass(git_odb_add_backend(_odb, backend, 1));
+ _repo = NULL;
+
+ nobj = 0;
+ cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL));
+ cl_assert(nobj == 1628);
+}
diff --git a/tests-clar/odb/pack_data_one.h b/tests-clar/odb/pack_data_one.h
new file mode 100644
index 000000000..13570ba78
--- /dev/null
+++ b/tests-clar/odb/pack_data_one.h
@@ -0,0 +1,19 @@
+/* Just a few to make sure it's working, the rest is tested already */
+static const char *packed_objects_one[] = {
+ "9fcf811e00fa469688943a9152c16d4ee90fb9a9",
+ "a93f42a5b5e9de40fa645a9ff1e276a021c9542b",
+ "12bf5f3e3470d90db177ccf1b5e8126409377fc6",
+ "ed1ea164cdbe3c4b200fb4fa19861ea90eaee222",
+ "dfae6ed8f6dd8acc3b40a31811ea316239223559",
+ "aefe66d192771201e369fde830530f4475beec30",
+ "775e4b4c1296e9e3104f2a36ca9cf9356a130959",
+ "412ec4e4a6a7419bc1be00561fe474e54cb499fe",
+ "236e7579fed7763be77209efb8708960982f3cb3",
+ "09fe9364461cf60dd1c46b0e9545b1e47bb1a297",
+ "d76d8a6390d1cf32138d98a91b1eb7e0275a12f5",
+ "d0fdf2dcff2f548952eec536ccc6d266550041bc",
+ "a20d733a9fa79fa5b4cbb9639864f93325ec27a6",
+ "785d3fe8e7db5ade2c2242fecd46c32a7f4dc59f",
+ "4d8d0fd9cb6045075385701c3f933ec13345e9c4",
+ "0cfd861bd547b6520d1fc2e190e8359e0a9c9b90"
+};
diff --git a/tests-clar/odb/packed_one.c b/tests-clar/odb/packed_one.c
new file mode 100644
index 000000000..a064829dd
--- /dev/null
+++ b/tests-clar/odb/packed_one.c
@@ -0,0 +1,58 @@
+#include "clar_libgit2.h"
+#include "odb.h"
+#include "pack_data_one.h"
+#include "pack.h"
+
+static git_odb *_odb;
+
+void test_odb_packed_one__initialize(void)
+{
+ git_odb_backend *backend = NULL;
+
+ cl_git_pass(git_odb_new(&_odb));
+ cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")));
+ cl_git_pass(git_odb_add_backend(_odb, backend, 1));
+}
+
+void test_odb_packed_one__cleanup(void)
+{
+ git_odb_free(_odb);
+}
+
+void test_odb_packed_one__mass_read(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) {
+ git_oid id;
+ git_odb_object *obj;
+
+ cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i]));
+ cl_assert(git_odb_exists(_odb, &id) == 1);
+ cl_git_pass(git_odb_read(&obj, _odb, &id));
+
+ git_odb_object_free(obj);
+ }
+}
+
+void test_odb_packed_one__read_header_0(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(packed_objects_one); ++i) {
+ git_oid id;
+ git_odb_object *obj;
+ size_t len;
+ git_otype type;
+
+ cl_git_pass(git_oid_fromstr(&id, packed_objects_one[i]));
+
+ cl_git_pass(git_odb_read(&obj, _odb, &id));
+ cl_git_pass(git_odb_read_header(&len, &type, _odb, &id));
+
+ cl_assert(obj->raw.len == len);
+ cl_assert(obj->raw.type == type);
+
+ git_odb_object_free(obj);
+ }
+}