Skip to content

Commit

Permalink
Merge branch 'ds/sparse-checkout-requires-per-worktree-config' into seen
Browse files Browse the repository at this point in the history
* ds/sparse-checkout-requires-per-worktree-config:
  sparse-checkout: use repo_config_set_worktree_gently()
  config: add repo_config_set_worktree_gently()
  worktree: add upgrade_to_worktree_config()
  config: make some helpers repo-aware
  setup: use a repository when upgrading format
  • Loading branch information
gitster committed Dec 22, 2021
2 parents 2f3f9fc + af51c8c commit 3dcb349
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 33 deletions.
25 changes: 8 additions & 17 deletions builtin/sparse-checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,26 +359,17 @@ enum sparse_checkout_mode {

static int set_config(enum sparse_checkout_mode mode)
{
const char *config_path;

if (upgrade_repository_format(1) < 0)
die(_("unable to upgrade repository format to enable worktreeConfig"));
if (git_config_set_gently("extensions.worktreeConfig", "true")) {
error(_("failed to set extensions.worktreeConfig setting"));
if (repo_config_set_worktree_gently(the_repository,
"core.sparseCheckout",
mode ? "true" : "false") ||
repo_config_set_worktree_gently(the_repository,
"core.sparseCheckoutCone",
mode == MODE_CONE_PATTERNS ?
"true" : "false"))
return 1;
}

config_path = git_path("config.worktree");
git_config_set_in_file_gently(config_path,
"core.sparseCheckout",
mode ? "true" : NULL);

git_config_set_in_file_gently(config_path,
"core.sparseCheckoutCone",
mode == MODE_CONE_PATTERNS ? "true" : NULL);

if (mode == MODE_NO_PATTERNS)
set_sparse_index_config(the_repository, 0);
return set_sparse_index_config(the_repository, 0);

return 0;
}
Expand Down
39 changes: 36 additions & 3 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "dir.h"
#include "color.h"
#include "refs.h"
#include "worktree.h"

struct config_source {
struct config_source *prev;
Expand Down Expand Up @@ -2986,9 +2987,23 @@ int git_config_set_gently(const char *key, const char *value)
return git_config_set_multivar_gently(key, value, NULL, 0);
}

int repo_config_set_worktree_gently(struct repository *r,
const char *key, const char *value)
{
return upgrade_to_worktree_config(r) ||
git_config_set_multivar_in_file_gently(
repo_git_path(r, "config.worktree"),
key, value, NULL, 0);
}

void git_config_set(const char *key, const char *value)
{
git_config_set_multivar(key, value, NULL, 0);
repo_config_set(the_repository, key, value);
}

void repo_config_set(struct repository *r, const char *key, const char *value)
{
repo_config_set_multivar(r, key, value, NULL, 0);

trace2_cmd_set_config(key, value);
}
Expand Down Expand Up @@ -3283,14 +3298,32 @@ void git_config_set_multivar_in_file(const char *config_filename,
int git_config_set_multivar_gently(const char *key, const char *value,
const char *value_pattern, unsigned flags)
{
return git_config_set_multivar_in_file_gently(NULL, key, value, value_pattern,
return repo_config_set_multivar_gently(the_repository, key, value,
value_pattern, flags);
}

int repo_config_set_multivar_gently(struct repository *r, const char *key,
const char *value,
const char *value_pattern, unsigned flags)
{
return git_config_set_multivar_in_file_gently(repo_git_path(r, "config"),
key, value, value_pattern,
flags);
}

void git_config_set_multivar(const char *key, const char *value,
const char *value_pattern, unsigned flags)
{
git_config_set_multivar_in_file(NULL, key, value, value_pattern,
repo_config_set_multivar(the_repository, key, value,
value_pattern, flags);
}

void repo_config_set_multivar(struct repository *r, const char *key,
const char *value, const char *value_pattern,
unsigned flags)
{
git_config_set_multivar_in_file(repo_git_path(r, "config"),
key, value, value_pattern,
flags);
}

Expand Down
14 changes: 14 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,23 @@ void git_config_set_in_file(const char *, const char *, const char *);

int git_config_set_gently(const char *, const char *);

/**
* Write a config value into the config.worktree file for the current
* worktree. This will initialize extensions.worktreeConfig if necessary,
* which might trigger some changes to the root repository's config file.
*/
int repo_config_set_worktree_gently(struct repository *, const char *, const char *);

/**
* write config values to `.git/config`, takes a key/value pair as parameter.
*/
void git_config_set(const char *, const char *);

/**
* write config values to `.git/config`, takes a key/value pair as parameter.
*/
void repo_config_set(struct repository *, const char *, const char *);

int git_config_parse_key(const char *, char **, size_t *);

/*
Expand All @@ -294,6 +306,8 @@ int git_config_parse_key(const char *, char **, size_t *);

int git_config_set_multivar_gently(const char *, const char *, const char *, unsigned);
void git_config_set_multivar(const char *, const char *, const char *, unsigned);
int repo_config_set_multivar_gently(struct repository *, const char *, const char *, const char *, unsigned);
void repo_config_set_multivar(struct repository *, const char *, const char *, const char *, unsigned);
int git_config_set_multivar_in_file_gently(const char *, const char *, const char *, const char *, unsigned);

/**
Expand Down
2 changes: 1 addition & 1 deletion list-objects-filter-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ void partial_clone_register(
*/
return;
} else {
if (upgrade_repository_format(1) < 0)
if (upgrade_repository_format(the_repository, 1) < 0)
die(_("unable to upgrade repository format to support partial clone"));

/* Add promisor config for the remote */
Expand Down
2 changes: 1 addition & 1 deletion repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,6 @@ void prepare_repo_settings(struct repository *r);
* Return 1 if upgrade repository format to target_version succeeded,
* 0 if no upgrade is necessary, and -1 when upgrade is not possible.
*/
int upgrade_repository_format(int target_version);
int upgrade_repository_format(struct repository *, int target_version);

#endif /* REPOSITORY_H */
6 changes: 3 additions & 3 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -659,14 +659,14 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
return 0;
}

int upgrade_repository_format(int target_version)
int upgrade_repository_format(struct repository *r, int target_version)
{
struct strbuf sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
struct strbuf repo_version = STRBUF_INIT;
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;

strbuf_git_common_path(&sb, the_repository, "config");
strbuf_git_common_path(&sb, r, "config");
read_repository_format(&repo_fmt, sb.buf);
strbuf_release(&sb);

Expand All @@ -685,7 +685,7 @@ int upgrade_repository_format(int target_version)
repo_fmt.unknown_extensions.items[0].string);

strbuf_addf(&repo_version, "%d", target_version);
git_config_set("core.repositoryformatversion", repo_version.buf);
repo_config_set(r, "core.repositoryformatversion", repo_version.buf);
strbuf_release(&repo_version);
return 1;
}
Expand Down
10 changes: 3 additions & 7 deletions sparse-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 res;
char *config_path = repo_git_path(repo, "config.worktree");
res = git_config_set_in_file_gently(config_path,
"index.sparse",
enable ? "true" : NULL);
free(config_path);

int res = repo_config_set_worktree_gently(repo,
"index.sparse",
enable ? "true" : "false");
prepare_repo_settings(repo);
repo->settings.sparse_index = enable;
return res;
Expand Down
16 changes: 15 additions & 1 deletion t/t1091-sparse-checkout-builtin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ test_expect_success 'git sparse-checkout init' '
check_files repo a
'

test_expect_success 'init in a worktree of a bare repo' '
test_when_finished rm -rf bare worktree &&
git clone --bare repo bare &&
git -C bare worktree add ../worktree &&
(
cd worktree &&
git sparse-checkout init &&
test_must_fail git config core.bare &&
git sparse-checkout set /*
) &&
git -C bare config --list --show-origin >actual &&
grep "file:config.worktree core.bare=true" actual
'

test_expect_success 'git sparse-checkout list after init' '
git -C repo sparse-checkout list >actual &&
cat >expect <<-\EOF &&
Expand Down Expand Up @@ -241,7 +255,7 @@ test_expect_success 'sparse-index enabled and disabled' '
test-tool -C repo read-cache --table >cache &&
! grep " tree " cache &&
git -C repo config --list >config &&
! grep index.sparse config
test_cmp_config -C repo false index.sparse
)
'

Expand Down
47 changes: 47 additions & 0 deletions worktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "worktree.h"
#include "dir.h"
#include "wt-status.h"
#include "config.h"

void free_worktrees(struct worktree **worktrees)
{
Expand Down Expand Up @@ -826,3 +827,49 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
*wtpath = path;
return 0;
}

int upgrade_to_worktree_config(struct repository *r)
{
int res;
int bare = 0;
struct config_set cs = { 0 };
char *base_config_file = xstrfmt("%s/config", r->commondir);
char *base_worktree_file = xstrfmt("%s/config.worktree", r->commondir);

git_configset_init(&cs);
git_configset_add_file(&cs, base_config_file);

/*
* If the base repository is bare, then we need to move core.bare=true
* out of the base config file and into the base repository's
* config.worktree file.
*/
if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare) {
if ((res = git_config_set_in_file_gently(base_worktree_file,
"core.bare", "true"))) {
error(_("unable to set core.bare=true in '%s'"), base_worktree_file);
goto cleanup;
}

if ((res = git_config_set_in_file_gently(base_config_file,
"core.bare", NULL))) {
error(_("unable to unset core.bare=true in '%s'"), base_config_file);
goto cleanup;
}
}
if (upgrade_repository_format(r, 1) < 0) {
res = error(_("unable to upgrade repository format to enable worktreeConfig"));
goto cleanup;
}
if ((res = git_config_set_gently("extensions.worktreeConfig", "true"))) {
error(_("failed to set extensions.worktreeConfig setting"));
goto cleanup;
}

cleanup:
git_configset_clear(&cs);
free(base_config_file);
free(base_worktree_file);
trace2_printf("returning %d", res);
return res;
}
12 changes: 12 additions & 0 deletions worktree.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,16 @@ void strbuf_worktree_ref(const struct worktree *wt,
struct strbuf *sb,
const char *refname);

/**
* Upgrade the config of the current repository and its base (if different
* from this repository) to use worktree-config. This might adjust config
* in both repositories, including:
*
* 1. Upgrading the repository format version to 1.
* 2. Adding extensions.worktreeConfig to the base config file.
* 3. Moving core.bare=true from the base config file to the base
* repository's config.worktree file.
*/
int upgrade_to_worktree_config(struct repository *r);

#endif

0 comments on commit 3dcb349

Please sign in to comment.