Skip to content

Commit b31b236

Browse files
author
Edward Thomson
authored
Merge pull request libgit2#4154 from libgit2/ethomson/namespaces
Support namespaced references again
2 parents 467185f + 8358056 commit b31b236

File tree

2 files changed

+71
-26
lines changed

2 files changed

+71
-26
lines changed

src/refdb_fs.c

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,48 +1433,50 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend)
14331433
git__free(backend);
14341434
}
14351435

1436-
static int setup_namespace(git_buf *gitpath, git_repository *repo)
1436+
static char *setup_namespace(git_repository *repo, const char *in)
14371437
{
1438-
char *parts, *start, *end;
1438+
git_buf path = GIT_BUF_INIT;
1439+
char *parts, *start, *end, *out = NULL;
14391440

1440-
/* Not all repositories have a gitpath */
1441-
if (repo->gitdir == NULL)
1442-
return 0;
1443-
if (repo->commondir == NULL)
1444-
return 0;
1441+
if (!in)
1442+
goto done;
14451443

1446-
/* Load the path to the repo first */
1447-
git_buf_puts(gitpath, repo->gitdir);
1444+
git_buf_puts(&path, in);
14481445

14491446
/* if the repo is not namespaced, nothing else to do */
1450-
if (repo->namespace == NULL)
1451-
return 0;
1447+
if (repo->namespace == NULL) {
1448+
out = git_buf_detach(&path);
1449+
goto done;
1450+
}
14521451

14531452
parts = end = git__strdup(repo->namespace);
14541453
if (parts == NULL)
1455-
return -1;
1454+
goto done;
14561455

14571456
/*
14581457
* From `man gitnamespaces`:
14591458
* namespaces which include a / will expand to a hierarchy
14601459
* of namespaces; for example, GIT_NAMESPACE=foo/bar will store
14611460
* refs under refs/namespaces/foo/refs/namespaces/bar/
14621461
*/
1463-
while ((start = git__strsep(&end, "/")) != NULL) {
1464-
git_buf_printf(gitpath, "refs/namespaces/%s/", start);
1465-
}
1462+
while ((start = git__strsep(&end, "/")) != NULL)
1463+
git_buf_printf(&path, "refs/namespaces/%s/", start);
14661464

1467-
git_buf_printf(gitpath, "refs/namespaces/%s/refs", end);
1465+
git_buf_printf(&path, "refs/namespaces/%s/refs", end);
14681466
git__free(parts);
14691467

14701468
/* Make sure that the folder with the namespace exists */
1471-
if (git_futils_mkdir_relative(git_buf_cstr(gitpath), repo->commondir,
1472-
0777, GIT_MKDIR_PATH, NULL) < 0)
1473-
return -1;
1469+
if (git_futils_mkdir_relative(git_buf_cstr(&path), in, 0777,
1470+
GIT_MKDIR_PATH, NULL) < 0)
1471+
goto done;
14741472

14751473
/* Return root of the namespaced gitpath, i.e. without the trailing '/refs' */
1476-
git_buf_rtruncate_at_char(gitpath, '/');
1477-
return 0;
1474+
git_buf_rtruncate_at_char(&path, '/');
1475+
out = git_buf_detach(&path);
1476+
1477+
done:
1478+
git_buf_free(&path);
1479+
return out;
14781480
}
14791481

14801482
static int reflog_alloc(git_reflog **reflog, const char *name)
@@ -1979,12 +1981,19 @@ int git_refdb_backend_fs(
19791981

19801982
backend->repo = repository;
19811983

1982-
if (setup_namespace(&gitpath, repository) < 0)
1983-
goto fail;
1984+
if (repository->gitdir) {
1985+
backend->gitpath = setup_namespace(repository, repository->gitdir);
19841986

1985-
backend->gitpath = backend->commonpath = git_buf_detach(&gitpath);
1986-
if (repository->commondir)
1987-
backend->commonpath = git__strdup(repository->commondir);
1987+
if (backend->gitpath == NULL)
1988+
goto fail;
1989+
}
1990+
1991+
if (repository->commondir) {
1992+
backend->commonpath = setup_namespace(repository, repository->commondir);
1993+
1994+
if (backend->commonpath == NULL)
1995+
goto fail;
1996+
}
19881997

19891998
if (git_buf_joinpath(&gitpath, backend->commonpath, GIT_PACKEDREFS_FILE) < 0 ||
19901999
git_sortedcache_new(

tests/refs/namespaces.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "clar_libgit2.h"
2+
3+
#include "repository.h"
4+
5+
static git_repository *g_repo;
6+
7+
void test_refs_namespaces__initialize(void)
8+
{
9+
g_repo = cl_git_sandbox_init("testrepo");
10+
}
11+
12+
void test_refs_namespaces__cleanup(void)
13+
{
14+
cl_git_sandbox_cleanup();
15+
}
16+
17+
void test_refs_namespaces__get_and_set(void)
18+
{
19+
cl_assert_equal_s(NULL, git_repository_get_namespace(g_repo));
20+
21+
cl_git_pass(git_repository_set_namespace(g_repo, "namespace"));
22+
cl_assert_equal_s("namespace", git_repository_get_namespace(g_repo));
23+
24+
cl_git_pass(git_repository_set_namespace(g_repo, NULL));
25+
cl_assert_equal_s(NULL, git_repository_get_namespace(g_repo));
26+
}
27+
28+
void test_refs_namespaces__namespace_doesnt_show_normal_refs(void)
29+
{
30+
static git_strarray ref_list;
31+
32+
cl_git_pass(git_repository_set_namespace(g_repo, "namespace"));
33+
cl_git_pass(git_reference_list(&ref_list, g_repo));
34+
cl_assert_equal_i(0, ref_list.count);
35+
git_strarray_free(&ref_list);
36+
}

0 commit comments

Comments
 (0)