Skip to content

Commit 2766b92

Browse files
committed
config_file: refresh when creating an iterator
When creating a new iterator for a config file backend, then we should always make sure that we're up to date by calling `config_refresh`. Otherwise, we might not notice when another process has modified the configuration file and thus will represent outdated values. Add two tests to config::stress that verify that we get up-to-date values when reading configuration entries via `git_config_iterator`.
1 parent 9fac8b7 commit 2766b92

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

src/config_file.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,12 @@ static int config_iterator_new(
270270
struct git_config_backend *backend)
271271
{
272272
diskfile_header *bh = GIT_CONTAINER_OF(backend, diskfile_header, parent);
273-
git_config_entries *entries;
273+
git_config_entries *entries = NULL;
274274
int error;
275275

276-
if ((error = git_config_entries_dup(&entries, bh->entries)) < 0)
277-
return error;
278-
279-
if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
276+
if ((error = config_refresh(backend)) < 0 ||
277+
(error = git_config_entries_dup(&entries, bh->entries)) < 0 ||
278+
(error = git_config_entries_iterator_new(iter, entries)) < 0)
280279
goto out;
281280

282281
out:

tests/config/stress.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,48 @@ void test_config_stress__quick_write(void)
131131
git_config_free(config_r);
132132
git_config_free(config_w);
133133
}
134+
135+
static int foreach_cb(const git_config_entry *entry, void *payload)
136+
{
137+
if (!strcmp(entry->name, "key.value")) {
138+
*(char **)payload = git__strdup(entry->value);
139+
return 0;
140+
}
141+
return -1;
142+
}
143+
144+
void test_config_stress__foreach_refreshes(void)
145+
{
146+
git_config *config_w, *config_r;
147+
char *value = NULL;
148+
149+
cl_git_pass(git_config_open_ondisk(&config_w, "./cfg"));
150+
cl_git_pass(git_config_open_ondisk(&config_r, "./cfg"));
151+
152+
cl_git_pass(git_config_set_string(config_w, "key.value", "1"));
153+
cl_git_pass(git_config_foreach_match(config_r, "key.value", foreach_cb, &value));
154+
155+
cl_assert_equal_s(value, "1");
156+
157+
git_config_free(config_r);
158+
git_config_free(config_w);
159+
git__free(value);
160+
}
161+
162+
void test_config_stress__foreach_refreshes_snapshot(void)
163+
{
164+
git_config *config, *snapshot;
165+
char *value = NULL;
166+
167+
cl_git_pass(git_config_open_ondisk(&config, "./cfg"));
168+
169+
cl_git_pass(git_config_set_string(config, "key.value", "1"));
170+
cl_git_pass(git_config_snapshot(&snapshot, config));
171+
cl_git_pass(git_config_foreach_match(snapshot, "key.value", foreach_cb, &value));
172+
173+
cl_assert_equal_s(value, "1");
174+
175+
git_config_free(snapshot);
176+
git_config_free(config);
177+
git__free(value);
178+
}

0 commit comments

Comments
 (0)