Commit cfcdbc100a993094ac1f094aa908ed4da472d106

Vicent Martí 2013-05-01T03:03:17

Merge pull request #1523 from libgit2/vmg/namespaces Namespace support

diff --git a/include/git2/repository.h b/include/git2/repository.h
index 08024cd..cd238e1 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -626,6 +626,28 @@ typedef enum {
  */
 GIT_EXTERN(int) git_repository_state(git_repository *repo);
 
+/**
+ * Sets the active namespace for this Git Repository
+ *
+ * This namespace affects all reference operations for the repo.
+ * See `man gitnamespaces`
+ *
+ * @param repo The repo
+ * @param nmspace The namespace. This should not include the refs
+ *	folder, e.g. to namespace all references under `refs/namespaces/foo/`,
+ *	use `foo` as the namespace.
+ *	@return 0 on success, -1 on error
+ */
+GIT_EXTERN(int) git_repository_set_namespace(git_repository *repo, const char *nmspace);
+
+/**
+ * Get the currently active namespace for this repository
+ *
+ * @param repo The repo
+ * @return the active namespace, or NULL if there isn't one
+ */
+GIT_EXTERN(const char *) git_repository_get_namespace(git_repository *repo);
+
 /** @} */
 GIT_END_DECL
 #endif
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 2f2e671..5228cb8 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -41,7 +41,7 @@ typedef struct refdb_fs_backend {
 	git_refdb_backend parent;
 
 	git_repository *repo;
-	const char *path;
+	char *path;
 
 	git_refcache refcache;
 } refdb_fs_backend;
@@ -993,6 +993,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
 	backend = (refdb_fs_backend *)_backend;
 
 	refcache_free(&backend->refcache);
+	git__free(backend->path);
 	git__free(backend);
 }
 
@@ -1000,13 +1001,19 @@ int git_refdb_backend_fs(
 	git_refdb_backend **backend_out,
 	git_repository *repository)
 {
+	git_buf path = GIT_BUF_INIT;
 	refdb_fs_backend *backend;
 
 	backend = git__calloc(1, sizeof(refdb_fs_backend));
 	GITERR_CHECK_ALLOC(backend);
 
 	backend->repo = repository;
-	backend->path = repository->path_repository;
+
+	git_buf_puts(&path, repository->path_repository);
+	if (repository->namespace != NULL)
+		git_buf_printf(&path, "refs/%s/", repository->namespace);
+
+	backend->path = git_buf_detach(&path);
 
 	backend->parent.exists = &refdb_fs_backend__exists;
 	backend->parent.lookup = &refdb_fs_backend__lookup;
diff --git a/src/repository.c b/src/repository.c
index 2161aa6..e6eaf75 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -111,6 +111,7 @@ void git_repository_free(git_repository *repo)
 
 	git__free(repo->path_repository);
 	git__free(repo->workdir);
+	git__free(repo->namespace);
 
 	git__free(repo);
 }
@@ -764,6 +765,23 @@ void git_repository_set_index(git_repository *repo, git_index *index)
 	set_index(repo, index);
 }
 
+int git_repository_set_namespace(git_repository *repo, const char *namespace)
+{
+	git__free(repo->namespace);
+
+	if (namespace == NULL) {
+		repo->namespace = NULL;
+		return 0;
+	}
+
+	return (repo->namespace = git__strdup(namespace)) ? 0 : -1;
+}
+
+const char *git_repository_get_namespace(git_repository *repo)
+{
+	return repo->namespace;
+}
+
 static int check_repositoryformatversion(git_config *config)
 {
 	int version;
diff --git a/src/repository.h b/src/repository.h
index f7f9ecb..bd5f63d 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -111,6 +111,7 @@ struct git_repository {
 
 	char *path_repository;
 	char *workdir;
+	char *namespace;
 
 	unsigned is_bare:1;
 	unsigned int lru_counter;