Skip to content

Commit 7316dc5

Browse files
derrickstoleegitster
authored andcommitted
sparse-checkout: set worktree-config correctly
`git sparse-checkout set/init` enables worktree-specific configuration[*] by setting extensions.worktreeConfig=true, but neglects to perform the additional necessary bookkeeping of relocating `core.bare=true` and `core.worktree` from $GIT_COMMON_DIR/config to $GIT_COMMON_DIR/config.worktree, as documented in git-worktree.txt. As a result of this oversight, these settings, which are nonsensical for secondary worktrees, can cause Git commands to incorrectly consider a worktree bare (in the case of `core.bare`) or operate on the wrong worktree (in the case of `core.worktree`). Fix this problem by taking advantage of the recently-added init_worktree_config() which enables `extensions.worktreeConfig` and takes care of necessary bookkeeping. While at it, for backward-compatibility reasons, also stop upgrading the repository format to "1" since doing so is (unintentionally) not required to take advantage of `extensions.worktreeConfig`, as explained by 1166419 ("Revert "check_repository_format_gently(): refuse extensions for old repositories"", 2020-07-15). [*] The main reason to use worktree-specific config for the sparse-checkout builtin was to avoid enabling sparse-checkout patterns in one and causing a loss of files in another. If a worktree does not have a sparse-checkout patterns file, then the sparse-checkout logic will not kick in on that worktree. Reported-by: Sean Allred <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Reviewed-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fe18733 commit 7316dc5

File tree

4 files changed

+30
-28
lines changed

4 files changed

+30
-28
lines changed

Documentation/git-sparse-checkout.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,21 @@ COMMANDS
3131
Describe the patterns in the sparse-checkout file.
3232

3333
'set'::
34-
Enable the necessary config settings
35-
(extensions.worktreeConfig, core.sparseCheckout,
36-
core.sparseCheckoutCone) if they are not already enabled, and
37-
write a set of patterns to the sparse-checkout file from the
34+
Enable the necessary sparse-checkout config settings
35+
(`core.sparseCheckout`, `core.sparseCheckoutCone`, and
36+
`index.sparse`) if they are not already set to the desired values,
37+
and write a set of patterns to the sparse-checkout file from the
3838
list of arguments following the 'set' subcommand. Update the
3939
working directory to match the new patterns.
4040
+
41+
To ensure that adjusting the sparse-checkout settings within a worktree
42+
does not alter the sparse-checkout settings in other worktrees, the 'set'
43+
subcommand will upgrade your repository config to use worktree-specific
44+
config if not already present. The sparsity defined by the arguments to
45+
the 'set' subcommand are stored in the worktree-specific sparse-checkout
46+
file. See linkgit:git-worktree[1] and the documentation of
47+
`extensions.worktreeConfig` in linkgit:git-config[1] for more details.
48+
+
4149
When the `--stdin` option is provided, the patterns are read from
4250
standard in as a newline-delimited list instead of from the arguments.
4351
+

builtin/sparse-checkout.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "wt-status.h"
1616
#include "quote.h"
1717
#include "sparse-index.h"
18+
#include "worktree.h"
1819

1920
static const char *empty_base = "";
2021

@@ -359,26 +360,23 @@ enum sparse_checkout_mode {
359360

360361
static int set_config(enum sparse_checkout_mode mode)
361362
{
362-
const char *config_path;
363-
364-
if (upgrade_repository_format(1) < 0)
365-
die(_("unable to upgrade repository format to enable worktreeConfig"));
366-
if (git_config_set_gently("extensions.worktreeConfig", "true")) {
367-
error(_("failed to set extensions.worktreeConfig setting"));
363+
/* Update to use worktree config, if not already. */
364+
if (init_worktree_config(the_repository)) {
365+
error(_("failed to initialize worktree config"));
368366
return 1;
369367
}
370368

371-
config_path = git_path("config.worktree");
372-
git_config_set_in_file_gently(config_path,
373-
"core.sparseCheckout",
374-
mode ? "true" : NULL);
375-
376-
git_config_set_in_file_gently(config_path,
377-
"core.sparseCheckoutCone",
378-
mode == MODE_CONE_PATTERNS ? "true" : NULL);
369+
if (repo_config_set_worktree_gently(the_repository,
370+
"core.sparseCheckout",
371+
mode ? "true" : "false") ||
372+
repo_config_set_worktree_gently(the_repository,
373+
"core.sparseCheckoutCone",
374+
mode == MODE_CONE_PATTERNS ?
375+
"true" : "false"))
376+
return 1;
379377

380378
if (mode == MODE_NO_PATTERNS)
381-
set_sparse_index_config(the_repository, 0);
379+
return set_sparse_index_config(the_repository, 0);
382380

383381
return 0;
384382
}

sparse-index.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,9 @@ static int convert_to_sparse_rec(struct index_state *istate,
9999

100100
int set_sparse_index_config(struct repository *repo, int enable)
101101
{
102-
int res;
103-
char *config_path = repo_git_path(repo, "config.worktree");
104-
res = git_config_set_in_file_gently(config_path,
105-
"index.sparse",
106-
enable ? "true" : NULL);
107-
free(config_path);
108-
102+
int res = repo_config_set_worktree_gently(repo,
103+
"index.sparse",
104+
enable ? "true" : "false");
109105
prepare_repo_settings(repo);
110106
repo->settings.sparse_index = enable;
111107
return res;

t/t1091-sparse-checkout-builtin.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' '
117117
cd bad-patterns &&
118118
git sparse-checkout init &&
119119
git sparse-checkout add dir &&
120-
git config core.sparseCheckoutCone true &&
120+
git config --worktree core.sparseCheckoutCone true &&
121121
test_must_fail git sparse-checkout add dir 2>err &&
122122
grep "existing sparse-checkout patterns do not use cone mode" err
123123
)
@@ -256,7 +256,7 @@ test_expect_success 'sparse-index enabled and disabled' '
256256
test_cmp expect actual &&
257257
258258
git -C repo config --list >config &&
259-
! grep index.sparse config
259+
test_cmp_config -C repo false index.sparse
260260
)
261261
'
262262

0 commit comments

Comments
 (0)