@@ -63,6 +63,12 @@ Note that this setting should only be set by linkgit:git-init[1] or
linkgit:git-clone[1]. Trying to change it after initialization will not
work and will produce hard-to-diagnose issues.
+relativeWorktrees::
+ If enabled, indicates at least one worktree has been linked with
+ relative paths. Automatically set if a worktree has been created or
+ repaired with either the `--relative-paths` option or with the
+ `worktree.useRelativePaths` config set to `true`.
+
worktreeConfig::
If enabled, then worktrees will load config settings from the
`$GIT_DIR/config.worktree` file in addition to the
@@ -283,6 +283,7 @@ int repo_init(struct repository *repo,
repo_set_compat_hash_algo(repo, format.compat_hash_algo);
repo_set_ref_storage_format(repo, format.ref_storage_format);
repo->repository_format_worktree_config = format.worktree_config;
+ repo->repository_format_relative_worktrees = format.relative_worktrees;
/* take ownership of format.partial_clone */
repo->repository_format_partial_clone = format.partial_clone;
@@ -150,6 +150,7 @@ struct repository {
/* Configurations */
int repository_format_worktree_config;
+ int repository_format_relative_worktrees;
/* Indicate if a repository has a different 'commondir' from 'gitdir' */
unsigned different_commondir:1;
@@ -683,6 +683,9 @@ static enum extension_result handle_extension(const char *var,
"extensions.refstorage", value);
data->ref_storage_format = format;
return EXTENSION_OK;
+ } else if (!strcmp(ext, "relativeworktrees")) {
+ data->relative_worktrees = git_config_bool(var, value);
+ return EXTENSION_OK;
}
return EXTENSION_UNKNOWN;
}
@@ -1854,6 +1857,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
repo_fmt.ref_storage_format);
the_repository->repository_format_worktree_config =
repo_fmt.worktree_config;
+ the_repository->repository_format_relative_worktrees =
+ repo_fmt.relative_worktrees;
/* take ownership of repo_fmt.partial_clone */
the_repository->repository_format_partial_clone =
repo_fmt.partial_clone;
@@ -1950,6 +1955,8 @@ void check_repository_format(struct repository_format *fmt)
fmt->ref_storage_format);
the_repository->repository_format_worktree_config =
fmt->worktree_config;
+ the_repository->repository_format_relative_worktrees =
+ fmt->relative_worktrees;
the_repository->repository_format_partial_clone =
xstrdup_or_null(fmt->partial_clone);
clear_repository_format(&repo_fmt);
@@ -129,6 +129,7 @@ struct repository_format {
int precious_objects;
char *partial_clone; /* value of extensions.partialclone */
int worktree_config;
+ int relative_worktrees;
int is_bare;
int hash_algo;
int compat_hash_algo;
@@ -1248,4 +1248,17 @@ test_expect_success 'move repo without breaking relative internal links' '
)
'
+test_expect_success 'relative worktree sets extension config' '
+ test_when_finished "rm -rf repo" &&
+ git init repo &&
+ git -C repo commit --allow-empty -m base &&
+ git -C repo worktree add --relative-paths ./foo &&
+ git -C repo config get core.repositoryformatversion >actual &&
+ echo 1 >expected &&
+ test_cmp expected actual &&
+ git -C repo config get extensions.relativeworktrees >actual &&
+ echo true >expected &&
+ test_cmp expected actual
+'
+
test_done
@@ -1025,6 +1025,14 @@ void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir)
strbuf_strip_suffix(&repo, "/gitdir");
strbuf_realpath(&repo, repo.buf, 1);
+ if (use_relative_paths && !the_repository->repository_format_relative_worktrees) {
+ if (upgrade_repository_format(1) < 0)
+ die(_("unable to upgrade repository format to support relative worktrees"));
+ if (git_config_set_gently("extensions.relativeWorktrees", "true"))
+ die(_("unable to set extensions.relativeWorktrees setting"));
+ the_repository->repository_format_relative_worktrees = 1;
+ }
+
if (use_relative_paths) {
write_file(gitdir.buf, "%s/.git", relative_path(path.buf, repo.buf, &tmp));
write_file(dotgit.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp));
A new extension, `relativeWorktrees`, is added to indicate that at least one worktree in the repository has been linked with relative paths. This extension is automatically set when a worktree is created or repaired using the `--relative-paths` option, or when the `worktree.useRelativePaths` config is set to `true`. The `relativeWorktrees` extension ensures older Git versions do not attempt to automatically prune worktrees with relative paths, as they would not not recognize the paths as being valid. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Caleb White <cdwhite3@pm.me> --- Documentation/config/extensions.txt | 6 ++++++ repository.c | 1 + repository.h | 1 + setup.c | 7 +++++++ setup.h | 1 + t/t2400-worktree-add.sh | 13 +++++++++++++ worktree.c | 8 ++++++++ 7 files changed, 37 insertions(+)