worktree: add `relativeWorktrees` extension

A new extension, `relativeWorktrees`, is added to indicate that at least one worktree in the repository has been linked with relative paths. This 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> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Caleb White committed Nov 29, 2024 at 22:22 UTC 1860ba1a2a96c587fca1c294d8288accf9554096
5 files changed +16
Documentation/config/extensions.txt
+6
@@ -63,6 +63,12 @@ Note that this setting should only be set by linkgit:git-init[1] or
63 linkgit:git-clone[1]. Trying to change it after initialization will not
64 work and will produce hard-to-diagnose issues.
65
66 +relativeWorktrees::
67 + If enabled, indicates at least one worktree has been linked with
68 + relative paths. Automatically set if a worktree has been created or
69 + repaired with either the `--relative-paths` option or with the
70 + `worktree.useRelativePaths` config set to `true`.
71 +
72 worktreeConfig::
73 If enabled, then worktrees will load config settings from the
74 `$GIT_DIR/config.worktree` file in addition to the
repository.c
+1
@@ -283,6 +283,7 @@ int repo_init(struct repository *repo,
283 repo_set_compat_hash_algo(repo, format.compat_hash_algo);
284 repo_set_ref_storage_format(repo, format.ref_storage_format);
285 repo->repository_format_worktree_config = format.worktree_config;
286 + repo->repository_format_relative_worktrees = format.relative_worktrees;
287
288 /* take ownership of format.partial_clone */
289 repo->repository_format_partial_clone = format.partial_clone;
repository.h
+1
@@ -150,6 +150,7 @@ struct repository {
150
151 /* Configurations */
152 int repository_format_worktree_config;
153 + int repository_format_relative_worktrees;
154
155 /* Indicate if a repository has a different 'commondir' from 'gitdir' */
156 unsigned different_commondir:1;
setup.c
+7
@@ -683,6 +683,9 @@ static enum extension_result handle_extension(const char *var,
683 "extensions.refstorage", value);
684 data->ref_storage_format = format;
685 return EXTENSION_OK;
686 + } else if (!strcmp(ext, "relativeworktrees")) {
687 + data->relative_worktrees = git_config_bool(var, value);
688 + return EXTENSION_OK;
689 }
690 return EXTENSION_UNKNOWN;
691 }
@@ -1854,6 +1857,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
1857 repo_fmt.ref_storage_format);
1858 the_repository->repository_format_worktree_config =
1859 repo_fmt.worktree_config;
1860 + the_repository->repository_format_relative_worktrees =
1861 + repo_fmt.relative_worktrees;
1862 /* take ownership of repo_fmt.partial_clone */
1863 the_repository->repository_format_partial_clone =
1864 repo_fmt.partial_clone;
@@ -1950,6 +1955,8 @@ void check_repository_format(struct repository_format *fmt)
1955 fmt->ref_storage_format);
1956 the_repository->repository_format_worktree_config =
1957 fmt->worktree_config;
1958 + the_repository->repository_format_relative_worktrees =
1959 + fmt->relative_worktrees;
1960 the_repository->repository_format_partial_clone =
1961 xstrdup_or_null(fmt->partial_clone);
1962 clear_repository_format(&repo_fmt);
setup.h
+1
@@ -129,6 +129,7 @@ struct repository_format {
129 int precious_objects;
130 char *partial_clone; /* value of extensions.partialclone */
131 int worktree_config;
132 + int relative_worktrees;
133 int is_bare;
134 int hash_algo;
135 int compat_hash_algo;