fix: Recognize relative worktrees extension

Git supports relative worktrees since Git v2.48 - cf6f63ea6b/Documentation/RelNotes/2.48.0.adoc (L57)

This was already handled programatically in libgit2, but was
not recognized as an extension, meaning downstream consumers
like Nix had issues with relative worktree-enabled repos.

Fixes #7210
This commit is contained in:
Cameron Will
2026-05-08 15:14:16 -04:00
parent de73c97d74
commit 3d1e45895e
3 changed files with 23 additions and 8 deletions

View File

@@ -1907,6 +1907,7 @@ static const char *builtin_extensions[] = {
"worktreeconfig",
"preciousobjects",
"refstorage",
"relativeworktrees",
};
static git_vector user_extensions = { 0, git__strcmp_cb };

View File

@@ -34,12 +34,13 @@ void test_core_opts__extensions_query(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 5);
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_s("noop", out.strings[0]);
cl_assert_equal_s("objectformat", out.strings[1]);
cl_assert_equal_s("preciousobjects", out.strings[2]);
cl_assert_equal_s("refstorage", out.strings[3]);
cl_assert_equal_s("worktreeconfig", out.strings[4]);
cl_assert_equal_s("relativeworktrees", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
git_strarray_dispose(&out);
}
@@ -52,13 +53,14 @@ void test_core_opts__extensions_add(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_sz(out.count, 7);
cl_assert_equal_s("foo", out.strings[0]);
cl_assert_equal_s("noop", out.strings[1]);
cl_assert_equal_s("objectformat", out.strings[2]);
cl_assert_equal_s("preciousobjects", out.strings[3]);
cl_assert_equal_s("refstorage", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
cl_assert_equal_s("relativeworktrees", out.strings[5]);
cl_assert_equal_s("worktreeconfig", out.strings[6]);
git_strarray_dispose(&out);
}
@@ -71,13 +73,14 @@ void test_core_opts__extensions_remove(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 6);
cl_assert_equal_sz(out.count, 7);
cl_assert_equal_s("bar", out.strings[0]);
cl_assert_equal_s("baz", out.strings[1]);
cl_assert_equal_s("objectformat", out.strings[2]);
cl_assert_equal_s("preciousobjects", out.strings[3]);
cl_assert_equal_s("refstorage", out.strings[4]);
cl_assert_equal_s("worktreeconfig", out.strings[5]);
cl_assert_equal_s("relativeworktrees", out.strings[5]);
cl_assert_equal_s("worktreeconfig", out.strings[6]);
git_strarray_dispose(&out);
}
@@ -90,14 +93,15 @@ void test_core_opts__extensions_uniq(void)
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_EXTENSIONS, in, ARRAY_SIZE(in)));
cl_git_pass(git_libgit2_opts(GIT_OPT_GET_EXTENSIONS, &out));
cl_assert_equal_sz(out.count, 7);
cl_assert_equal_sz(out.count, 8);
cl_assert_equal_s("bar", out.strings[0]);
cl_assert_equal_s("foo", out.strings[1]);
cl_assert_equal_s("noop", out.strings[2]);
cl_assert_equal_s("objectformat", out.strings[3]);
cl_assert_equal_s("preciousobjects", out.strings[4]);
cl_assert_equal_s("refstorage", out.strings[5]);
cl_assert_equal_s("worktreeconfig", out.strings[6]);
cl_assert_equal_s("relativeworktrees", out.strings[6]);
cl_assert_equal_s("worktreeconfig", out.strings[7]);
git_strarray_dispose(&out);
}

View File

@@ -80,3 +80,13 @@ void test_repo_extensions__preciousobjects(void)
cl_git_pass(git_repository_open(&extended, "empty_bare.git"));
git_repository_free(extended);
}
void test_repo_extensions__relativeworktrees(void)
{
git_repository *extended = NULL;
cl_repo_set_string(repo, "extensions.relativeWorktrees", "true");
cl_git_pass(git_repository_open(&extended, "empty_bare.git"));
git_repository_free(extended);
}