Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4b1113

Browse files
committed
config: skip worktree config in get_backend_for_use
It would seem that `get_backend_for_use` is primarily used when writing config data -- either to set keys or delete them (based on the possible values of `backend_use`). When git-config(1) is used for side-effects, it will modify only the local (repository-level) configuration unless explicitly overridden. From git-config(1): --local For writing options: write to the repository .git/config file. This is the default behavior. `get_backend_for_use` does not have the ability to specify a config level and typically is expected (it seems) to 'do the right thing'. Taking its cue from git-config(1), don't update worktree-specific config unless it's the only option. If that functionality is needed by consumers, I assume they would find the appropriate backend with `git_config_open_level` and feed that `git_config` object through to the `git_config_set_*` functions (as demonstrated in the provided test).
1 parent 42e7e68 commit f4b1113

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/libgit2/config.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -593,12 +593,14 @@ static int get_backend_for_use(git_config_backend **out,
593593
git_config *cfg, const char *name, backend_use use)
594594
{
595595
size_t i;
596+
size_t len;
596597
backend_internal *backend;
597598
int error = 0;
598599

599600
*out = NULL;
600601

601-
if (git_vector_length(&cfg->backends) == 0) {
602+
len = git_vector_length(&cfg->backends);
603+
if (len == 0) {
602604
git_error_set(GIT_ERROR_CONFIG,
603605
"cannot %s value for '%s' when no config backends exist",
604606
uses[use], name);
@@ -609,6 +611,15 @@ static int get_backend_for_use(git_config_backend **out,
609611
if (backend->backend->readonly)
610612
continue;
611613

614+
/* git-config doesn't update worktree-level config
615+
unless specifically requested; follow suit. If you
616+
specifically want to update that level, open the
617+
single config level with git_config_open_level and
618+
provide that as the config. In this case, there
619+
will only be one backend in the config. */
620+
if (len > 1 && backend->level == GIT_CONFIG_LEVEL_WORKTREE)
621+
continue;
622+
612623
*out = backend->backend;
613624
goto cleanup;
614625
}

tests/libgit2/worktree/config.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void test_worktree_config__open(void)
2727
git_config_free(cfg);
2828
}
2929

30-
void test_worktree_config__set(void)
30+
void test_worktree_config__set_level_local(void)
3131
{
3232
git_config *cfg;
3333
int32_t val;
@@ -45,3 +45,31 @@ void test_worktree_config__set(void)
4545
cl_assert_equal_i(val, 5);
4646
git_config_free(cfg);
4747
}
48+
49+
void test_worktree_config__set_level_worktree(void)
50+
{
51+
git_config *cfg;
52+
git_config *wtcfg;
53+
int32_t val;
54+
55+
cl_git_pass(git_repository_config(&cfg, fixture.repo));
56+
cl_git_pass(git_config_open_level(&wtcfg, cfg, GIT_CONFIG_LEVEL_WORKTREE));
57+
cl_git_pass(git_config_set_int32(wtcfg, "worktree.specific", 42));
58+
59+
cl_git_pass(git_config_get_int32(&val, cfg, "worktree.specific"));
60+
cl_assert_equal_i(val, 42);
61+
62+
/* reopen to verify config has been set */
63+
git_config_free(cfg);
64+
cl_git_pass(git_repository_config(&cfg, fixture.repo));
65+
cl_git_pass(git_config_get_int32(&val, cfg, "worktree.specific"));
66+
cl_assert_equal_i(val, 42);
67+
68+
cl_assert(git_config_delete_entry(cfg, "worktree.specific") == GIT_ENOTFOUND);
69+
70+
cl_git_pass(git_config_delete_entry(wtcfg, "worktree.specific"));
71+
cl_assert(git_config_get_int32(&val, cfg, "worktree.specific") == GIT_ENOTFOUND);
72+
73+
git_config_free(cfg);
74+
git_config_free(wtcfg);
75+
}

0 commit comments

Comments
 (0)