Skip to content

Commit 24b9c4b

Browse files
committed
repo: honor GIT_COMMON_DIR when respecting env
When the repository is opened with `GIT_REPOSITORY_OPEN_FROM_ENV`, honor the `GIT_COMMON_DIR` environment variable.
1 parent b41c3df commit 24b9c4b

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

src/libgit2/repository.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,23 @@ void git_repository_free(git_repository *repo)
191191
}
192192

193193
/* Check if we have a separate commondir (e.g. we have a worktree) */
194-
static int lookup_commondir(bool *separate, git_str *commondir, git_str *repository_path)
194+
static int lookup_commondir(
195+
bool *separate,
196+
git_str *commondir,
197+
git_str *repository_path,
198+
uint32_t flags)
195199
{
196-
git_str common_link = GIT_STR_INIT;
200+
git_str common_link = GIT_STR_INIT;
197201
int error;
198202

203+
/* Environment variable overrides configuration */
204+
if ((flags & GIT_REPOSITORY_OPEN_FROM_ENV)) {
205+
error = git__getenv(commondir, "GIT_COMMON_DIR");
206+
207+
if (!error || error != GIT_ENOTFOUND)
208+
goto done;
209+
}
210+
199211
/*
200212
* If there's no commondir file, the repository path is the
201213
* common path, but it needs a trailing slash.
@@ -222,12 +234,11 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit
222234
git_str_swap(commondir, &common_link);
223235
}
224236

225-
git_str_dispose(&common_link);
226-
227237
/* Make sure the commondir path always has a trailing slash */
228238
error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL);
229239

230240
done:
241+
git_str_dispose(&common_link);
231242
return error;
232243
}
233244

@@ -252,14 +263,19 @@ GIT_INLINE(int) validate_repo_path(git_str *path)
252263
*
253264
* Open a repository object from its path
254265
*/
255-
static int is_valid_repository_path(bool *out, git_str *repository_path, git_str *common_path)
266+
static int is_valid_repository_path(
267+
bool *out,
268+
git_str *repository_path,
269+
git_str *common_path,
270+
uint32_t flags)
256271
{
257272
bool separate_commondir = false;
258273
int error;
259274

260275
*out = false;
261276

262-
if ((error = lookup_commondir(&separate_commondir, common_path, repository_path)) < 0)
277+
if ((error = lookup_commondir(&separate_commondir,
278+
common_path, repository_path, flags)) < 0)
263279
return error;
264280

265281
/* Ensure HEAD file exists */
@@ -742,7 +758,7 @@ static int find_repo_traverse(
742758
break;
743759

744760
if (S_ISDIR(st.st_mode)) {
745-
if ((error = is_valid_repository_path(&is_valid, &path, &common_link)) < 0)
761+
if ((error = is_valid_repository_path(&is_valid, &path, &common_link, flags)) < 0)
746762
goto out;
747763

748764
if (is_valid) {
@@ -759,7 +775,7 @@ static int find_repo_traverse(
759775
}
760776
} else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
761777
if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
762-
(error = is_valid_repository_path(&is_valid, &repo_link, &common_link)) < 0)
778+
(error = is_valid_repository_path(&is_valid, &repo_link, &common_link, flags)) < 0)
763779
goto out;
764780

765781
if (is_valid) {
@@ -934,7 +950,7 @@ int git_repository_open_bare(
934950
git_config *config;
935951

936952
if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
937-
(error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
953+
(error = is_valid_repository_path(&is_valid, &path, &common_path, 0)) < 0)
938954
return error;
939955

940956
if (!is_valid) {
@@ -2668,7 +2684,7 @@ int git_repository_init_ext(
26682684

26692685
wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path);
26702686

2671-
if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
2687+
if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path, opts->flags)) < 0)
26722688
goto out;
26732689

26742690
if (is_valid) {

tests/libgit2/repo/env.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,23 @@ void test_repo_env__work_tree(void)
295295
git_repository_free(repo);
296296
cl_setenv("GIT_WORK_TREE", NULL);
297297
}
298+
299+
void test_repo_env__commondir(void)
300+
{
301+
git_repository *repo;
302+
const char *test_path;
303+
304+
cl_fixture_sandbox("attr");
305+
cl_git_pass(p_rename("attr/.gitted", "attr/.git"));
306+
307+
cl_fixture_sandbox("testrepo.git");
308+
cl_git_pass(p_rename("testrepo.git", "test_commondir"));
309+
310+
test_path = cl_git_sandbox_path(1, "test_commondir", NULL);
311+
312+
cl_setenv("GIT_COMMON_DIR", test_path);
313+
cl_git_pass(git_repository_open_ext(&repo, "attr", GIT_REPOSITORY_OPEN_FROM_ENV, NULL));
314+
cl_assert_equal_s(test_path, git_repository_commondir(repo));
315+
git_repository_free(repo);
316+
cl_setenv("GIT_COMMON_DIR", NULL);
317+
}

0 commit comments

Comments
 (0)