Commit 6a15f657e749dc251049b0152e180264482b11fa

Patrick Steinhardt 2018-02-09T13:02:26

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.

diff --git a/src/config_file.c b/src/config_file.c
index 4909ce1..6c65208 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -30,8 +30,7 @@ typedef struct config_entry_list {
 
 typedef struct git_config_file_iter {
 	git_config_iterator parent;
-	git_strmap_iter iter;
-	config_entry_list* next_var;
+	config_entry_list *head;
 } git_config_file_iter;
 
 /* Max depth for [include] directives */
@@ -378,24 +377,12 @@ static int config_iterator_next(
 	git_config_iterator *iter)
 {
 	git_config_file_iter *it = (git_config_file_iter *) iter;
-	diskfile_header *h = (diskfile_header *) it->parent.backend;
-	git_strmap *entry_map = h->entries->map;
-	int err = 0;
-	config_entry_list * var;
 
-	if (it->next_var == NULL) {
-		err = git_strmap_next((void**) &var, &(it->iter), entry_map);
-	} else {
-		var = it->next_var;
-	}
-
-	if (err < 0) {
-		it->next_var = NULL;
-		return err;
-	}
+	if (!it->head)
+		return GIT_ITEROVER;
 
-	*entry = var->entry;
-	it->next_var = var->next;
+	*entry = it->head->entry;
+	it->head = it->head->next;
 
 	return 0;
 }
@@ -421,15 +408,11 @@ static int config_iterator_new(
 
 	h = (diskfile_header *)snapshot;
 
-	/* strmap_begin() is currently a macro returning 0 */
-	GIT_UNUSED(h);
-
 	it->parent.backend = snapshot;
-	it->iter = git_strmap_begin(h->values);
-	it->next_var = NULL;
-
+	it->head = h->entries->list;
 	it->parent.next = config_iterator_next;
 	it->parent.free = config_iterator_free;
+
 	*iter = (git_config_iterator *) it;
 
 	return 0;
diff --git a/tests/config/read.c b/tests/config/read.c
index a34455a..ebcd2eb 100644
--- a/tests/config/read.c
+++ b/tests/config/read.c
@@ -306,6 +306,15 @@ void test_config_read__foreach(void)
 
 void test_config_read__iterator(void)
 {
+	const char *keys[] = {
+		"core.dummy2",
+		"core.verylong",
+		"core.dummy",
+		"remote.ab.url",
+		"remote.abba.url",
+		"core.dummy2",
+		"core.global"
+	};
 	git_config *cfg;
 	git_config_iterator *iter;
 	git_config_entry *entry;
@@ -321,6 +330,7 @@ void test_config_read__iterator(void)
 	cl_git_pass(git_config_iterator_new(&iter, cfg));
 
 	while ((ret = git_config_next(&entry, iter)) == 0) {
+		cl_assert_equal_s(entry->name, keys[count]);
 		count++;
 	}