Skip to content

Commit e3adc99

Browse files
authored
Merge pull request libgit2#5181 from pks-t/pks/config-iterator-refresh
config_file: refresh when creating an iterator
2 parents 82b1d1d + a213fec commit e3adc99

File tree

3 files changed

+110
-21
lines changed

3 files changed

+110
-21
lines changed

src/config_file.c

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ static void config_file_clear(diskfile *file)
121121

122122
static int config_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
123123
{
124+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
124125
int res;
125-
diskfile_backend *b = (diskfile_backend *)cfg;
126126

127127
b->header.level = level;
128128
b->header.repo = repo;
@@ -179,7 +179,7 @@ static int config_is_modified(int *modified, diskfile *file)
179179

180180
static int config_set_entries(git_config_backend *cfg, git_config_entries *entries)
181181
{
182-
diskfile_backend *b = (diskfile_backend *)cfg;
182+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
183183
git_config_entries *old = NULL;
184184
diskfile *include;
185185
int error;
@@ -231,8 +231,10 @@ static int config_refresh(git_config_backend *cfg)
231231
git_config_entries *entries = NULL;
232232
int error, modified;
233233

234-
error = config_is_modified(&modified, &b->file);
235-
if (error < 0 && error != GIT_ENOTFOUND)
234+
if (cfg->readonly)
235+
return 0;
236+
237+
if ((error = config_is_modified(&modified, &b->file)) < 0 && error != GIT_ENOTFOUND)
236238
goto out;
237239

238240
if (!modified)
@@ -252,7 +254,7 @@ static int config_refresh(git_config_backend *cfg)
252254

253255
static void backend_free(git_config_backend *_backend)
254256
{
255-
diskfile_backend *backend = (diskfile_backend *)_backend;
257+
diskfile_backend *backend = GIT_CONTAINER_OF(_backend, diskfile_backend, header.parent);
256258

257259
if (backend == NULL)
258260
return;
@@ -268,13 +270,12 @@ static int config_iterator_new(
268270
struct git_config_backend *backend)
269271
{
270272
diskfile_header *bh = GIT_CONTAINER_OF(backend, diskfile_header, parent);
271-
git_config_entries *entries;
273+
git_config_entries *entries = NULL;
272274
int error;
273275

274-
if ((error = git_config_entries_dup(&entries, bh->entries)) < 0)
275-
return error;
276-
277-
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)
278279
goto out;
279280

280281
out:
@@ -285,7 +286,7 @@ static int config_iterator_new(
285286

286287
static int config_set(git_config_backend *cfg, const char *name, const char *value)
287288
{
288-
diskfile_backend *b = (diskfile_backend *)cfg;
289+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
289290
git_config_entries *entries;
290291
git_config_entry *existing;
291292
char *key, *esc_value = NULL;
@@ -337,7 +338,7 @@ static void free_diskfile_entry(git_config_entry *entry)
337338
*/
338339
static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
339340
{
340-
diskfile_header *h = (diskfile_header *)cfg;
341+
diskfile_header *h = GIT_CONTAINER_OF(cfg, diskfile_header, parent);
341342
git_config_entries *entries = NULL;
342343
git_config_entry *entry;
343344
int error = 0;
@@ -363,7 +364,7 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry
363364
static int config_set_multivar(
364365
git_config_backend *cfg, const char *name, const char *regexp, const char *value)
365366
{
366-
diskfile_backend *b = (diskfile_backend *)cfg;
367+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
367368
char *key;
368369
p_regex_t preg;
369370
int result;
@@ -393,7 +394,7 @@ static int config_set_multivar(
393394

394395
static int config_delete(git_config_backend *cfg, const char *name)
395396
{
396-
diskfile_backend *b = (diskfile_backend *)cfg;
397+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
397398
git_config_entries *entries = NULL;
398399
git_config_entry *entry;
399400
char *key = NULL;
@@ -423,7 +424,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
423424

424425
static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
425426
{
426-
diskfile_backend *b = (diskfile_backend *)cfg;
427+
diskfile_backend *b = GIT_CONTAINER_OF(cfg, diskfile_backend, header.parent);
427428
git_config_entries *entries = NULL;
428429
git_config_entry *entry = NULL;
429430
p_regex_t preg = { 0 };
@@ -462,7 +463,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
462463

463464
static int config_lock(git_config_backend *_cfg)
464465
{
465-
diskfile_backend *cfg = (diskfile_backend *) _cfg;
466+
diskfile_backend *cfg = GIT_CONTAINER_OF(_cfg, diskfile_backend, header.parent);
466467
int error;
467468

468469
if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file.path, 0, GIT_CONFIG_FILE_MODE)) < 0)
@@ -481,7 +482,7 @@ static int config_lock(git_config_backend *_cfg)
481482

482483
static int config_unlock(git_config_backend *_cfg, int success)
483484
{
484-
diskfile_backend *cfg = (diskfile_backend *) _cfg;
485+
diskfile_backend *cfg = GIT_CONTAINER_OF(_cfg, diskfile_backend, header.parent);
485486
int error = 0;
486487

487488
if (success) {
@@ -581,7 +582,7 @@ static int config_unlock_readonly(git_config_backend *_cfg, int success)
581582

582583
static void backend_readonly_free(git_config_backend *_backend)
583584
{
584-
diskfile_backend *backend = (diskfile_backend *)_backend;
585+
diskfile_backend *backend = GIT_CONTAINER_OF(_backend, diskfile_backend, header.parent);
585586

586587
if (backend == NULL)
587588
return;
@@ -593,7 +594,7 @@ static void backend_readonly_free(git_config_backend *_backend)
593594

594595
static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
595596
{
596-
diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
597+
diskfile_readonly_backend *b = GIT_CONTAINER_OF(cfg, diskfile_readonly_backend, header.parent);
597598
diskfile_backend *src = b->snapshot_from;
598599
diskfile_header *src_header = &src->header;
599600
git_config_entries *entries;
@@ -623,7 +624,7 @@ static int config_snapshot(git_config_backend **out, git_config_backend *in)
623624
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
624625
git_mutex_init(&backend->header.values_mutex);
625626

626-
backend->snapshot_from = (diskfile_backend *) in;
627+
backend->snapshot_from = GIT_CONTAINER_OF(in, diskfile_backend, header.parent);
627628

628629
backend->header.parent.readonly = 1;
629630
backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
@@ -638,7 +639,7 @@ static int config_snapshot(git_config_backend **out, git_config_backend *in)
638639
backend->header.parent.unlock = config_unlock_readonly;
639640
backend->header.parent.free = backend_readonly_free;
640641

641-
*out = (git_config_backend *)backend;
642+
*out = &backend->header.parent;
642643

643644
return 0;
644645
}

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+
}

tests/remote/list.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "clar_libgit2.h"
2+
#include "config/config_helpers.h"
3+
4+
static git_repository *_repo;
5+
6+
#define TEST_URL "http://github.com/libgit2/libgit2.git"
7+
8+
void test_remote_list__initialize(void)
9+
{
10+
_repo = cl_git_sandbox_init("testrepo");
11+
}
12+
13+
void test_remote_list__cleanup(void)
14+
{
15+
cl_git_sandbox_cleanup();
16+
}
17+
18+
void test_remote_list__always_checks_disk_config(void)
19+
{
20+
git_repository *repo;
21+
git_strarray remotes;
22+
git_remote *remote;
23+
24+
cl_git_pass(git_repository_open(&repo, git_repository_path(_repo)));
25+
26+
cl_git_pass(git_remote_list(&remotes, _repo));
27+
cl_assert_equal_sz(remotes.count, 1);
28+
git_strarray_free(&remotes);
29+
30+
cl_git_pass(git_remote_create(&remote, _repo, "valid-name", TEST_URL));
31+
32+
cl_git_pass(git_remote_list(&remotes, _repo));
33+
cl_assert_equal_sz(remotes.count, 2);
34+
git_strarray_free(&remotes);
35+
36+
cl_git_pass(git_remote_list(&remotes, repo));
37+
cl_assert_equal_sz(remotes.count, 2);
38+
git_strarray_free(&remotes);
39+
40+
git_repository_free(repo);
41+
git_remote_free(remote);
42+
}
43+

0 commit comments

Comments
 (0)