Skip to content

Commit f2a1cec

Browse files
authored
Merge pull request libgit2#4686 from tiennou/fix/more-worktree-from-bare
Fix git_worktree_validate failing on bare repositories
2 parents 8a00de0 + 1da6329 commit f2a1cec

File tree

6 files changed

+117
-68
lines changed

6 files changed

+117
-68
lines changed

src/worktree.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -234,40 +234,30 @@ void git_worktree_free(git_worktree *wt)
234234

235235
int git_worktree_validate(const git_worktree *wt)
236236
{
237-
git_buf buf = GIT_BUF_INIT;
238-
int err = 0;
239-
240237
assert(wt);
241238

242-
git_buf_puts(&buf, wt->gitdir_path);
243-
if (!is_worktree_dir(buf.ptr)) {
239+
if (!is_worktree_dir(wt->gitdir_path)) {
244240
giterr_set(GITERR_WORKTREE,
245241
"Worktree gitdir ('%s') is not valid",
246242
wt->gitlink_path);
247-
err = -1;
248-
goto out;
243+
return GIT_ERROR;
249244
}
250245

251-
if (!git_path_exists(wt->parent_path)) {
246+
if (wt->parent_path && !git_path_exists(wt->parent_path)) {
252247
giterr_set(GITERR_WORKTREE,
253248
"Worktree parent directory ('%s') does not exist ",
254249
wt->parent_path);
255-
err = -2;
256-
goto out;
250+
return GIT_ERROR;
257251
}
258252

259253
if (!git_path_exists(wt->commondir_path)) {
260254
giterr_set(GITERR_WORKTREE,
261255
"Worktree common directory ('%s') does not exist ",
262256
wt->commondir_path);
263-
err = -3;
264-
goto out;
257+
return GIT_ERROR;
265258
}
266259

267-
out:
268-
git_buf_dispose(&buf);
269-
270-
return err;
260+
return 0;
271261
}
272262

273263
int git_worktree_add_init_options(git_worktree_add_options *opts,

tests/clar_libgit2.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,35 @@ const char* cl_git_path_url(const char *path)
319319
return url;
320320
}
321321

322+
const char *cl_git_sandbox_path(int is_dir, ...)
323+
{
324+
const char *path = NULL;
325+
static char _temp[GIT_PATH_MAX];
326+
git_buf buf = GIT_BUF_INIT;
327+
va_list arg;
328+
329+
cl_git_pass(git_buf_sets(&buf, clar_sandbox_path()));
330+
331+
va_start(arg, is_dir);
332+
333+
while ((path = va_arg(arg, const char *)) != NULL) {
334+
cl_git_pass(git_buf_joinpath(&buf, buf.ptr, path));
335+
}
336+
va_end(arg);
337+
338+
cl_git_pass(git_path_prettify(&buf, buf.ptr, NULL));
339+
if (is_dir)
340+
git_path_to_dir(&buf);
341+
342+
/* make sure we won't truncate */
343+
cl_assert(git_buf_len(&buf) < sizeof(_temp));
344+
git_buf_copy_cstr(_temp, sizeof(_temp), &buf);
345+
346+
git_buf_dispose(&buf);
347+
348+
return _temp;
349+
}
350+
322351
typedef struct {
323352
const char *filename;
324353
size_t filename_len;

tests/clar_libgit2.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ git_repository *cl_git_sandbox_init_new(const char *name);
181181
void cl_git_sandbox_cleanup(void);
182182
git_repository *cl_git_sandbox_reopen(void);
183183

184+
/*
185+
* build a sandbox-relative from path segments
186+
* is_dir will add a trailing slash
187+
* vararg must be a NULL-terminated char * list
188+
*/
189+
const char *cl_git_sandbox_path(int is_dir, ...);
190+
184191
/* Local-repo url helpers */
185192
const char* cl_git_fixture_url(const char *fixturename);
186193
const char* cl_git_path_url(const char *path);

tests/worktree/bare.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "clar_libgit2.h"
2+
#include "worktree_helpers.h"
3+
#include "submodule/submodule_helpers.h"
4+
5+
#define COMMON_REPO "testrepo.git"
6+
#define WORKTREE_REPO "worktree"
7+
8+
static git_repository *g_repo;
9+
10+
void test_worktree_bare__initialize(void)
11+
{
12+
g_repo = cl_git_sandbox_init(COMMON_REPO);
13+
14+
cl_assert_equal_i(1, git_repository_is_bare(g_repo));
15+
cl_assert_equal_i(0, git_repository_is_worktree(g_repo));
16+
}
17+
18+
void test_worktree_bare__cleanup(void)
19+
{
20+
cl_fixture_cleanup(WORKTREE_REPO);
21+
cl_git_sandbox_cleanup();
22+
}
23+
24+
void test_worktree_bare__list(void)
25+
{
26+
git_strarray wts;
27+
28+
cl_git_pass(git_worktree_list(&wts, g_repo));
29+
cl_assert_equal_i(wts.count, 0);
30+
31+
git_strarray_free(&wts);
32+
}
33+
34+
void test_worktree_bare__add(void)
35+
{
36+
git_worktree *wt;
37+
git_repository *wtrepo;
38+
git_strarray wts;
39+
40+
cl_git_pass(git_worktree_add(&wt, g_repo, "name", WORKTREE_REPO, NULL));
41+
42+
cl_git_pass(git_worktree_list(&wts, g_repo));
43+
cl_assert_equal_i(wts.count, 1);
44+
45+
cl_git_pass(git_worktree_validate(wt));
46+
47+
cl_git_pass(git_repository_open(&wtrepo, WORKTREE_REPO));
48+
cl_assert_equal_i(0, git_repository_is_bare(wtrepo));
49+
cl_assert_equal_i(1, git_repository_is_worktree(wtrepo));
50+
51+
git_strarray_free(&wts);
52+
git_worktree_free(wt);
53+
git_repository_free(wtrepo);
54+
}
55+
56+
void test_worktree_bare__repository_path(void)
57+
{
58+
git_worktree *wt;
59+
git_repository *wtrepo;
60+
61+
cl_git_pass(git_worktree_add(&wt, g_repo, "name", WORKTREE_REPO, NULL));
62+
cl_assert_equal_s(git_worktree_path(wt), cl_git_sandbox_path(0, WORKTREE_REPO, NULL));
63+
64+
cl_git_pass(git_repository_open(&wtrepo, WORKTREE_REPO));
65+
cl_assert_equal_s(git_repository_path(wtrepo), cl_git_sandbox_path(1, COMMON_REPO, "worktrees", "name", NULL));
66+
67+
cl_assert_equal_s(git_repository_commondir(g_repo), git_repository_commondir(wtrepo));
68+
cl_assert_equal_s(git_repository_workdir(wtrepo), cl_git_sandbox_path(1, WORKTREE_REPO, NULL));
69+
70+
git_repository_free(wtrepo);
71+
git_worktree_free(wt);
72+
}

tests/worktree/open.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,11 @@ static worktree_fixture fixture =
1111

1212
static void assert_worktree_valid(git_repository *wt, const char *parentdir, const char *wtdir)
1313
{
14-
git_buf path = GIT_BUF_INIT;
15-
1614
cl_assert(wt->is_worktree);
1715

18-
cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), wtdir));
19-
cl_git_pass(git_path_prettify(&path, path.ptr, NULL));
20-
cl_git_pass(git_path_to_dir(&path));
21-
cl_assert_equal_s(wt->workdir, path.ptr);
22-
23-
cl_git_pass(git_buf_joinpath(&path, path.ptr, ".git"));
24-
cl_git_pass(git_path_prettify(&path, path.ptr, NULL));
25-
cl_assert_equal_s(wt->gitlink, path.ptr);
26-
27-
cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), parentdir));
28-
cl_git_pass(git_buf_joinpath(&path, path.ptr, ".git"));
29-
cl_git_pass(git_buf_joinpath(&path, path.ptr, "worktrees"));
30-
cl_git_pass(git_buf_joinpath(&path, path.ptr, wtdir));
31-
cl_git_pass(git_path_prettify(&path, path.ptr, NULL));
32-
cl_git_pass(git_path_to_dir(&path));
33-
cl_assert_equal_s(wt->gitdir, path.ptr);
34-
35-
git_buf_dispose(&path);
16+
cl_assert_equal_s(wt->workdir, cl_git_sandbox_path(1, wtdir, NULL));
17+
cl_assert_equal_s(wt->gitlink, cl_git_sandbox_path(0, wtdir, ".git", NULL));
18+
cl_assert_equal_s(wt->gitdir, cl_git_sandbox_path(1, parentdir, ".git", "worktrees", wtdir, NULL));
3619
}
3720

3821
void test_worktree_open__initialize(void)

tests/worktree/worktree.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,6 @@ void test_worktree_worktree__list_in_worktree_repo(void)
8484
git_strarray_free(&wts);
8585
}
8686

87-
void test_worktree_worktree__list_bare(void)
88-
{
89-
git_repository *repo;
90-
git_strarray wts;
91-
92-
repo = cl_git_sandbox_init("testrepo.git");
93-
cl_git_pass(git_worktree_list(&wts, repo));
94-
cl_assert_equal_i(wts.count, 0);
95-
96-
git_repository_free(repo);
97-
}
98-
9987
void test_worktree_worktree__list_without_worktrees(void)
10088
{
10189
git_repository *repo;
@@ -228,26 +216,6 @@ void test_worktree_worktree__init(void)
228216
git_repository_free(repo);
229217
}
230218

231-
void test_worktree_worktree__add_from_bare(void)
232-
{
233-
git_worktree *wt;
234-
git_repository *repo, *wtrepo;
235-
236-
repo = cl_git_sandbox_init("short_tag.git");
237-
238-
cl_assert_equal_i(1, git_repository_is_bare(repo));
239-
cl_assert_equal_i(0, git_repository_is_worktree(repo));
240-
241-
cl_git_pass(git_worktree_add(&wt, repo, "worktree-frombare", "worktree-frombare", NULL));
242-
cl_git_pass(git_repository_open(&wtrepo, "worktree-frombare"));
243-
cl_assert_equal_i(0, git_repository_is_bare(wtrepo));
244-
cl_assert_equal_i(1, git_repository_is_worktree(wtrepo));
245-
246-
git_worktree_free(wt);
247-
git_repository_free(repo);
248-
git_repository_free(wtrepo);
249-
}
250-
251219
void test_worktree_worktree__add_locked(void)
252220
{
253221
git_worktree *wt;

0 commit comments

Comments
 (0)