Merge pull request #1523 from libgit2/vmg/namespaces Namespace support
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
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;