Skip to content

Commit 6a15f65

Browse files
committed
config_file: iterate over keys in the order they were added
Currently, all configuration entries were only held in a string map, making iteration order mostly based on the hash of each entry's key. Now that we have extended the `diskfile_entries` structure by a list of config entries, we can effectively iterate through entries in the order they were added, though.
1 parent 3a82475 commit 6a15f65

File tree

2 files changed

+17
-24
lines changed

2 files changed

+17
-24
lines changed

src/config_file.c

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ typedef struct config_entry_list {
3030

3131
typedef struct git_config_file_iter {
3232
git_config_iterator parent;
33-
git_strmap_iter iter;
34-
config_entry_list* next_var;
33+
config_entry_list *head;
3534
} git_config_file_iter;
3635

3736
/* Max depth for [include] directives */
@@ -378,24 +377,12 @@ static int config_iterator_next(
378377
git_config_iterator *iter)
379378
{
380379
git_config_file_iter *it = (git_config_file_iter *) iter;
381-
diskfile_header *h = (diskfile_header *) it->parent.backend;
382-
git_strmap *entry_map = h->entries->map;
383-
int err = 0;
384-
config_entry_list * var;
385380

386-
if (it->next_var == NULL) {
387-
err = git_strmap_next((void**) &var, &(it->iter), entry_map);
388-
} else {
389-
var = it->next_var;
390-
}
391-
392-
if (err < 0) {
393-
it->next_var = NULL;
394-
return err;
395-
}
381+
if (!it->head)
382+
return GIT_ITEROVER;
396383

397-
*entry = var->entry;
398-
it->next_var = var->next;
384+
*entry = it->head->entry;
385+
it->head = it->head->next;
399386

400387
return 0;
401388
}
@@ -421,15 +408,11 @@ static int config_iterator_new(
421408

422409
h = (diskfile_header *)snapshot;
423410

424-
/* strmap_begin() is currently a macro returning 0 */
425-
GIT_UNUSED(h);
426-
427411
it->parent.backend = snapshot;
428-
it->iter = git_strmap_begin(h->values);
429-
it->next_var = NULL;
430-
412+
it->head = h->entries->list;
431413
it->parent.next = config_iterator_next;
432414
it->parent.free = config_iterator_free;
415+
433416
*iter = (git_config_iterator *) it;
434417

435418
return 0;

tests/config/read.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,15 @@ void test_config_read__foreach(void)
306306

307307
void test_config_read__iterator(void)
308308
{
309+
const char *keys[] = {
310+
"core.dummy2",
311+
"core.verylong",
312+
"core.dummy",
313+
"remote.ab.url",
314+
"remote.abba.url",
315+
"core.dummy2",
316+
"core.global"
317+
};
309318
git_config *cfg;
310319
git_config_iterator *iter;
311320
git_config_entry *entry;
@@ -321,6 +330,7 @@ void test_config_read__iterator(void)
321330
cl_git_pass(git_config_iterator_new(&iter, cfg));
322331

323332
while ((ret = git_config_next(&entry, iter)) == 0) {
333+
cl_assert_equal_s(entry->name, keys[count]);
324334
count++;
325335
}
326336

0 commit comments

Comments
 (0)