Skip to content

Commit 97cd165

Browse files
authored
Merge pull request libgit2#5926 from Batchyx/batchyx/config-refresh-twice
config: fix included configs not refreshed more than once
2 parents 95a2966 + 4bf136b commit 97cd165

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

src/config_file.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,23 +164,27 @@ static int config_file_is_modified(int *modified, config_file *file)
164164
return error;
165165
}
166166

167+
static void config_file_clear_includes(config_file_backend* cfg)
168+
{
169+
config_file *include;
170+
uint32_t i;
171+
172+
git_array_foreach(cfg->file.includes, i, include)
173+
config_file_clear(include);
174+
git_array_clear(cfg->file.includes);
175+
}
176+
167177
static int config_file_set_entries(git_config_backend *cfg, git_config_entries *entries)
168178
{
169179
config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
170180
git_config_entries *old = NULL;
171-
config_file *include;
172181
int error;
173-
uint32_t i;
174182

175183
if (b->parent.readonly) {
176184
git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
177185
return -1;
178186
}
179187

180-
git_array_foreach(b->file.includes, i, include)
181-
config_file_clear(include);
182-
git_array_clear(b->file.includes);
183-
184188
if ((error = git_mutex_lock(&b->values_mutex)) < 0) {
185189
git_error_set(GIT_ERROR_OS, "failed to lock config backend");
186190
goto out;
@@ -202,6 +206,8 @@ static int config_file_refresh_from_buffer(git_config_backend *cfg, const char *
202206
git_config_entries *entries = NULL;
203207
int error;
204208

209+
config_file_clear_includes(b);
210+
205211
if ((error = git_config_entries_new(&entries)) < 0 ||
206212
(error = config_file_read_buffer(entries, b->repo, &b->file,
207213
b->level, 0, buf, buflen)) < 0 ||
@@ -229,6 +235,8 @@ static int config_file_refresh(git_config_backend *cfg)
229235
if (!modified)
230236
return 0;
231237

238+
config_file_clear_includes(b);
239+
232240
if ((error = git_config_entries_new(&entries)) < 0 ||
233241
(error = config_file_read(entries, b->repo, &b->file, b->level, 0)) < 0 ||
234242
(error = config_file_set_entries(cfg, entries)) < 0)

tests/config/include.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,30 @@ void test_config_include__rewriting_include_refreshes_values(void)
178178
cl_git_pass(p_unlink("second"));
179179
}
180180

181+
void test_config_include__rewriting_include_twice_refreshes_values(void)
182+
{
183+
cl_git_mkfile("top-level", "[include]\npath = included");
184+
cl_git_mkfile("included", "[foo]\nbar = first-value");
185+
186+
cl_git_pass(git_config_open_ondisk(&cfg, "top-level"));
187+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.bar"));
188+
189+
git_buf_clear(&buf);
190+
cl_git_mkfile("included", "[foo]\nother = value2");
191+
cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.bar"));
192+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.other"));
193+
cl_assert_equal_s(buf.ptr, "value2");
194+
195+
git_buf_clear(&buf);
196+
cl_git_mkfile("included", "[foo]\nanother = bar");
197+
cl_git_fail(git_config_get_string_buf(&buf, cfg, "foo.other"));
198+
cl_git_pass(git_config_get_string_buf(&buf, cfg, "foo.another"));
199+
cl_assert_equal_s(buf.ptr, "bar");
200+
201+
cl_git_pass(p_unlink("top-level"));
202+
cl_git_pass(p_unlink("included"));
203+
}
204+
181205
void test_config_include__included_variables_cannot_be_deleted(void)
182206
{
183207
cl_git_mkfile("top-level", "[include]\npath = included\n");

0 commit comments

Comments
 (0)