Commit ec3c7a16c260fa6540cfe8daf37c1324100f51bf

Vicent Marti 2011-01-13T04:54:14

Add new Repository initialization method Lets the user specify the ODB that will be used by the repository manually. Signed-off-by: Vicent Marti <tanoku@gmail.com>

diff --git a/src/git2/repository.h b/src/git2/repository.h
index 4eaa6f2..37a541f 100644
--- a/src/git2/repository.h
+++ b/src/git2/repository.h
@@ -98,6 +98,42 @@ GIT_EXTERN(int) git_repository_open2(git_repository **repository,
 
 
 /**
+ * Open a git repository by manually specifying its paths and
+ * the object database it will use.
+ *
+ * @param repository pointer to the repo which will be opened
+ *
+ * @param git_dir The full path to the repository folder
+ *		e.g. a '.git' folder for live repos, any folder for bare
+ *		Equivalent to $GIT_DIR. 
+ *		Cannot be NULL.
+ *
+ * @param object_database A pointer to a git_odb created & initialized
+ *		by the user (e.g. with custom backends). This object database
+ *		will be owned by the repository and will be automatically free'd.
+ *		It should not be manually free'd by the user, or this
+ *		git_repository object will become invalid.
+ *
+ * @param git_index_file The full path to the index (dircache) file
+ *		Equivalent to $GIT_INDEX_FILE.
+ *		If NULL, "$GIT_DIR/index" is assumed.
+ *
+ * @param git_work_tree The full path to the working tree of the repository,
+ *		if the repository is not bare.
+ *		Equivalent to $GIT_WORK_TREE.
+ *		If NULL, the repository is assumed to be bare.
+ *
+ * @return 0 on success; error code otherwise
+ */
+
+GIT_EXTERN(int) git_repository_open3(git_repository **repository,
+		const char *git_dir,
+		git_odb *object_database,
+		const char *git_index_file,
+		const char *git_work_tree);
+
+
+/**
  * Lookup a reference to one of the objects in the repostory.
  *
  * The generated reference is owned by the repository and
diff --git a/src/odb.c b/src/odb.c
index d54ad83..26b457b 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -277,8 +277,8 @@ int git_odb_read(git_rawobj *out, git_odb *db, const git_oid *id)
 	for (i = 0; i < db->backends.length && error < 0; ++i) {
 		git_odb_backend *b = git_vector_get(&db->backends, i);
 
-		assert(b->read != NULL);
-		error = b->read(out, b, id);
+		if (b->read != NULL)
+			error = b->read(out, b, id);
 	}
 
 	return error;
diff --git a/src/repository.c b/src/repository.c
index f0c822f..7e56a4b 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -225,6 +225,49 @@ static git_repository *repository_alloc()
 	return repo;
 }
 
+static int init_odb(git_repository *repo)
+{
+	return git_odb_open(&repo->db, repo->path_odb);
+}
+
+int git_repository_open3(git_repository **repo_out,
+		const char *git_dir,
+		git_odb *object_database,
+		const char *git_index_file,
+		const char *git_work_tree)
+{
+	git_repository *repo;
+	int error = GIT_SUCCESS;
+
+	assert(repo_out);
+
+	if (object_database == NULL)
+		return GIT_ERROR;
+
+	repo = repository_alloc();
+	if (repo == NULL)
+		return GIT_ENOMEM;
+
+	error = assign_repository_DIRs(repo, 
+			git_dir, 
+			NULL,
+			git_index_file,
+			git_work_tree);
+
+	if (error < GIT_SUCCESS)
+		goto cleanup;
+
+	repo->db = object_database;
+
+	*repo_out = repo;
+	return GIT_SUCCESS;
+
+cleanup:
+	git_repository_free(repo);
+	return error;
+}
+
+
 int git_repository_open2(git_repository **repo_out,
 		const char *git_dir,
 		const char *git_object_directory,
@@ -249,7 +292,7 @@ int git_repository_open2(git_repository **repo_out,
 	if (error < GIT_SUCCESS)
 		goto cleanup;
 
-	error = git_odb_open(&repo->db, repo->path_odb);
+	error = init_odb(repo);
 	if (error < GIT_SUCCESS)
 		goto cleanup;
 
@@ -276,8 +319,7 @@ int git_repository_open(git_repository **repo_out, const char *path)
 	if (error < GIT_SUCCESS)
 		goto cleanup;
 
-
-	error = git_odb_open(&repo->db, repo->path_odb);
+	error = init_odb(repo);
 	if (error < GIT_SUCCESS)
 		goto cleanup;