Commit 550cd2d776e6b14ab7bb48c98c8d28969cdcf1cb

Vicent Martí 2013-07-09T16:54:34

Merge pull request #1716 from arrbee/fix-config-get-multivar Fix git_config_get_multivar with interleaved missing entries

diff --git a/src/config.c b/src/config.c
index 068c402..2a05854 100644
--- a/src/config.c
+++ b/src/config.c
@@ -534,7 +534,7 @@ int git_config_get_multivar(
 {
 	file_internal *internal;
 	git_config_backend *file;
-	int ret = GIT_ENOTFOUND;
+	int ret = GIT_ENOTFOUND, err;
 	size_t i;
 
 	/*
@@ -547,9 +547,10 @@ int git_config_get_multivar(
 			continue;
 		file = internal->file;
 
-		ret = file->get_multivar(file, name, regexp, cb, payload);
-		if (ret < 0 && ret != GIT_ENOTFOUND)
-			return ret;
+		if (!(err = file->get_multivar(file, name, regexp, cb, payload)))
+			ret = 0;
+		else if (err != GIT_ENOTFOUND)
+			return err;
 	}
 
 	return (ret == GIT_ENOTFOUND) ? config_error_notfound(name) : 0;
diff --git a/tests-clar/config/multivar.c b/tests-clar/config/multivar.c
index 0bda6bc..efc4315 100644
--- a/tests-clar/config/multivar.c
+++ b/tests-clar/config/multivar.c
@@ -1,6 +1,6 @@
 #include "clar_libgit2.h"
 
-static const char *_name = "remote.fancy.url";
+static const char *_name = "remote.ab.url";
 
 void test_config_multivar__initialize(void)
 {
@@ -46,20 +46,60 @@ static int cb(const git_config_entry *entry, void *data)
 	return 0;
 }
 
+static void check_get_multivar(
+	git_config *cfg, int expected, int expected_patterned)
+{
+	int n = 0;
+
+	if (expected > 0) {
+		cl_git_pass(git_config_get_multivar(cfg, _name, NULL, cb, &n));
+		cl_assert_equal_i(expected, n);
+	} else {
+		cl_assert_equal_i(GIT_ENOTFOUND,
+			git_config_get_multivar(cfg, _name, NULL, cb, &n));
+	}
+
+	n = 0;
+
+	if (expected_patterned > 0) {
+		cl_git_pass(git_config_get_multivar(cfg, _name, "example", cb, &n));
+		cl_assert_equal_i(expected_patterned, n);
+	} else {
+		cl_assert_equal_i(GIT_ENOTFOUND,
+			git_config_get_multivar(cfg, _name, "example", cb, &n));
+	}
+}
+
 void test_config_multivar__get(void)
 {
 	git_config *cfg;
-	int n;
 
 	cl_git_pass(git_config_open_ondisk(&cfg, "config/config11"));
+	check_get_multivar(cfg, 2, 1);
 
-	n = 0;
-	cl_git_pass(git_config_get_multivar(cfg, _name, NULL, cb, &n));
-	cl_assert(n == 2);
+	/* add another that has the _name entry */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config9", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar(cfg, 3, 2);
 
-	n = 0;
-	cl_git_pass(git_config_get_multivar(cfg, _name, "example", cb, &n));
-	cl_assert(n == 1);
+	/* add another that does not have the _name entry */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config0", GIT_CONFIG_LEVEL_GLOBAL, 1));
+	check_get_multivar(cfg, 3, 2);
+
+	/* add another that does not have the _name entry at the end */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config1", GIT_CONFIG_LEVEL_APP, 1));
+	check_get_multivar(cfg, 3, 2);
+
+	/* drop original file */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config2", GIT_CONFIG_LEVEL_LOCAL, 1));
+	check_get_multivar(cfg, 1, 1);
+
+	/* drop other file with match */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config3", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar(cfg, 0, 0);
+
+	/* reload original file (add different place in order) */
+	cl_git_pass(git_config_add_file_ondisk(cfg, "config/config11", GIT_CONFIG_LEVEL_SYSTEM, 1));
+	check_get_multivar(cfg, 2, 1);
 
 	git_config_free(cfg);
 }
diff --git a/tests-clar/resources/config/config11 b/tests-clar/resources/config/config11
index 7331862..1d8a744 100644
--- a/tests-clar/resources/config/config11
+++ b/tests-clar/resources/config/config11
@@ -1,4 +1,4 @@
-[remote "fancy"]
+[remote "ab"]
     url = git://github.com/libgit2/libgit2
     url = git://git.example.com/libgit2