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 11664196ac
("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 <allred.sean@gmail.com>
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
fe18733927
commit
7316dc5f6f
@ -31,13 +31,21 @@ COMMANDS
|
|||||||
Describe the patterns in the sparse-checkout file.
|
Describe the patterns in the sparse-checkout file.
|
||||||
|
|
||||||
'set'::
|
'set'::
|
||||||
Enable the necessary config settings
|
Enable the necessary sparse-checkout config settings
|
||||||
(extensions.worktreeConfig, core.sparseCheckout,
|
(`core.sparseCheckout`, `core.sparseCheckoutCone`, and
|
||||||
core.sparseCheckoutCone) if they are not already enabled, and
|
`index.sparse`) if they are not already set to the desired values,
|
||||||
write a set of patterns to the sparse-checkout file from the
|
and write a set of patterns to the sparse-checkout file from the
|
||||||
list of arguments following the 'set' subcommand. Update the
|
list of arguments following the 'set' subcommand. Update the
|
||||||
working directory to match the new patterns.
|
working directory to match the new patterns.
|
||||||
+
|
+
|
||||||
|
To ensure that adjusting the sparse-checkout settings within a worktree
|
||||||
|
does not alter the sparse-checkout settings in other worktrees, the 'set'
|
||||||
|
subcommand will upgrade your repository config to use worktree-specific
|
||||||
|
config if not already present. The sparsity defined by the arguments to
|
||||||
|
the 'set' subcommand are stored in the worktree-specific sparse-checkout
|
||||||
|
file. See linkgit:git-worktree[1] and the documentation of
|
||||||
|
`extensions.worktreeConfig` in linkgit:git-config[1] for more details.
|
||||||
|
+
|
||||||
When the `--stdin` option is provided, the patterns are read from
|
When the `--stdin` option is provided, the patterns are read from
|
||||||
standard in as a newline-delimited list instead of from the arguments.
|
standard in as a newline-delimited list instead of from the arguments.
|
||||||
+
|
+
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "wt-status.h"
|
#include "wt-status.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
#include "sparse-index.h"
|
#include "sparse-index.h"
|
||||||
|
#include "worktree.h"
|
||||||
|
|
||||||
static const char *empty_base = "";
|
static const char *empty_base = "";
|
||||||
|
|
||||||
@ -359,26 +360,23 @@ enum sparse_checkout_mode {
|
|||||||
|
|
||||||
static int set_config(enum sparse_checkout_mode mode)
|
static int set_config(enum sparse_checkout_mode mode)
|
||||||
{
|
{
|
||||||
const char *config_path;
|
/* Update to use worktree config, if not already. */
|
||||||
|
if (init_worktree_config(the_repository)) {
|
||||||
if (upgrade_repository_format(1) < 0)
|
error(_("failed to initialize worktree config"));
|
||||||
die(_("unable to upgrade repository format to enable worktreeConfig"));
|
|
||||||
if (git_config_set_gently("extensions.worktreeConfig", "true")) {
|
|
||||||
error(_("failed to set extensions.worktreeConfig setting"));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
config_path = git_path("config.worktree");
|
if (repo_config_set_worktree_gently(the_repository,
|
||||||
git_config_set_in_file_gently(config_path,
|
|
||||||
"core.sparseCheckout",
|
"core.sparseCheckout",
|
||||||
mode ? "true" : NULL);
|
mode ? "true" : "false") ||
|
||||||
|
repo_config_set_worktree_gently(the_repository,
|
||||||
git_config_set_in_file_gently(config_path,
|
|
||||||
"core.sparseCheckoutCone",
|
"core.sparseCheckoutCone",
|
||||||
mode == MODE_CONE_PATTERNS ? "true" : NULL);
|
mode == MODE_CONE_PATTERNS ?
|
||||||
|
"true" : "false"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (mode == MODE_NO_PATTERNS)
|
if (mode == MODE_NO_PATTERNS)
|
||||||
set_sparse_index_config(the_repository, 0);
|
return set_sparse_index_config(the_repository, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -99,13 +99,9 @@ static int convert_to_sparse_rec(struct index_state *istate,
|
|||||||
|
|
||||||
int set_sparse_index_config(struct repository *repo, int enable)
|
int set_sparse_index_config(struct repository *repo, int enable)
|
||||||
{
|
{
|
||||||
int res;
|
int res = repo_config_set_worktree_gently(repo,
|
||||||
char *config_path = repo_git_path(repo, "config.worktree");
|
|
||||||
res = git_config_set_in_file_gently(config_path,
|
|
||||||
"index.sparse",
|
"index.sparse",
|
||||||
enable ? "true" : NULL);
|
enable ? "true" : "false");
|
||||||
free(config_path);
|
|
||||||
|
|
||||||
prepare_repo_settings(repo);
|
prepare_repo_settings(repo);
|
||||||
repo->settings.sparse_index = enable;
|
repo->settings.sparse_index = enable;
|
||||||
return res;
|
return res;
|
||||||
|
@ -117,7 +117,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' '
|
|||||||
cd bad-patterns &&
|
cd bad-patterns &&
|
||||||
git sparse-checkout init &&
|
git sparse-checkout init &&
|
||||||
git sparse-checkout add dir &&
|
git sparse-checkout add dir &&
|
||||||
git config core.sparseCheckoutCone true &&
|
git config --worktree core.sparseCheckoutCone true &&
|
||||||
test_must_fail git sparse-checkout add dir 2>err &&
|
test_must_fail git sparse-checkout add dir 2>err &&
|
||||||
grep "existing sparse-checkout patterns do not use cone mode" err
|
grep "existing sparse-checkout patterns do not use cone mode" err
|
||||||
)
|
)
|
||||||
@ -256,7 +256,7 @@ test_expect_success 'sparse-index enabled and disabled' '
|
|||||||
test_cmp expect actual &&
|
test_cmp expect actual &&
|
||||||
|
|
||||||
git -C repo config --list >config &&
|
git -C repo config --list >config &&
|
||||||
! grep index.sparse config
|
test_cmp_config -C repo false index.sparse
|
||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user