Merge pull request #4630 from tiennou/fix/worktree-from-bare Worktrees can be made from bare repositories
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
diff --git a/src/repository.c b/src/repository.c
index 90b778e..3c89879 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -268,11 +268,15 @@ static int load_config_data(git_repository *repo, const git_config *config)
{
int is_bare;
+ int err = git_config_get_bool(&is_bare, config, "core.bare");
+ if (err < 0 && err != GIT_ENOTFOUND)
+ return err;
+
/* Try to figure out if it's bare, default to non-bare if it's not set */
- if (git_config_get_bool(&is_bare, config, "core.bare") < 0)
- repo->is_bare = 0;
+ if (err != GIT_ENOTFOUND)
+ repo->is_bare = is_bare && !repo->is_worktree;
else
- repo->is_bare = is_bare;
+ repo->is_bare = 0;
return 0;
}
diff --git a/src/worktree.c b/src/worktree.c
index 30f03dd..48d3ef9 100644
--- a/src/worktree.c
+++ b/src/worktree.c
@@ -139,7 +139,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
if ((wt->name = git__strdup(name)) == NULL
|| (wt->commondir_path = git_worktree__read_link(dir, "commondir")) == NULL
|| (wt->gitlink_path = git_worktree__read_link(dir, "gitdir")) == NULL
- || (wt->parent_path = git__strdup(parent)) == NULL
+ || (parent && (wt->parent_path = git__strdup(parent)) == NULL)
|| (wt->worktree_path = git_path_dirname(wt->gitlink_path)) == NULL) {
error = -1;
goto out;
diff --git a/tests/worktree/worktree.c b/tests/worktree/worktree.c
index 70ccd50..cbdd084 100644
--- a/tests/worktree/worktree.c
+++ b/tests/worktree/worktree.c
@@ -228,6 +228,26 @@ void test_worktree_worktree__init(void)
git_repository_free(repo);
}
+void test_worktree_worktree__add_from_bare(void)
+{
+ git_worktree *wt;
+ git_repository *repo, *wtrepo;
+
+ repo = cl_git_sandbox_init("short_tag.git");
+
+ cl_assert_equal_i(1, git_repository_is_bare(repo));
+ cl_assert_equal_i(0, git_repository_is_worktree(repo));
+
+ cl_git_pass(git_worktree_add(&wt, repo, "worktree-frombare", "worktree-frombare", NULL));
+ cl_git_pass(git_repository_open(&wtrepo, "worktree-frombare"));
+ cl_assert_equal_i(0, git_repository_is_bare(wtrepo));
+ cl_assert_equal_i(1, git_repository_is_worktree(wtrepo));
+
+ git_worktree_free(wt);
+ git_repository_free(repo);
+ git_repository_free(wtrepo);
+}
+
void test_worktree_worktree__add_locked(void)
{
git_worktree *wt;