Commit 40fe5fbea8f2e64dee1c2327c774cca0004f18f8

Carlos Martín Nieto 2011-09-22T22:50:36

Make repo config loading automatic or completely explicit git_repository_config wants to take the global and system paths again so that one can be explicit if needed. The git_repository_config_autoload function is provided for the cases when it's good enough for the library to guess where those files are located. Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>

diff --git a/include/git2/repository.h b/include/git2/repository.h
index d12cfbe..b1fb5db 100644
--- a/include/git2/repository.h
+++ b/include/git2/repository.h
@@ -284,14 +284,11 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
 /**
  * Retrieve the relevant configuration for a repository
  *
- * By default he returned `git_config` instance contains the two most
- * common configuration files, the `config' file that may be found
- * inside the repository, and the `$HOME/.gitconfig' "global"
- * configuration file.
- *
- * If the `system_config_path` variable is not NULL, the given config
- * file will be also included in the configuration set. On most UNIX
- * systems, this file may be found on `$PREFIX/etc/gitconfig`.
+ * If either the `global_config_path` or `system_config_path`
+ * variables are not NULL, the given config files will be also
+ * included in the configuration set. The global configuration file is
+ * located in $HOME/.gitconfig. On most UNIX systems, the system
+ * config file file may be found on `$sysconfdir/gitconfig`.
  *
  * The resulting `git_config` instance will query the files in the following
  * order:
@@ -300,20 +297,37 @@ GIT_EXTERN(int) git_repository_is_bare(git_repository *repo);
  *	- Global configuration file
  *	- System configuration file
  *
- * The method will fail if any of the passed system config file found
- * or accessed.
+ * The method will fail if any of the given config files can't be
+ * found or accessed.
  *
  * The returned `git_config` instance is owned by the caller and must
  * be manually free'd once it's no longer on use.
  *
  * @param out the repository's configuration
  * @param repo the repository for which to get the config
+ * @param system_config_path Path to the global config file
  * @param system_config_path Path to the system-wide config file
  */
+
 GIT_EXTERN(int) git_repository_config(git_config **out,
 	git_repository *repo,
+	const char *global_config_path,
 	const char *system_config_path);
 
+/**
+ * Automatically load the configuration files
+ *
+ * A wrapper around `git_repository_config` that tries to guess where
+ * the global and system config files are located. No error is
+ * reported if either of these files
+ *
+ * @param out the repository's configuration
+ * @param repo the repository for which to get the config
+ */
+int git_repository_config_autoload(
+		git_config **out,
+		git_repository *repo);
+
 /** @} */
 GIT_END_DECL
 #endif
diff --git a/src/repository.c b/src/repository.c
index a39ccb6..328bc0d 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -270,6 +270,7 @@ cleanup:
 int git_repository_config(
 		git_config **out,
 		git_repository *repo,
+		const char *global_config_path,
 		const char *system_config_path)
 {
 	char config_path[GIT_PATH_MAX];
@@ -286,9 +287,10 @@ int git_repository_config(
 	if (error < GIT_SUCCESS)
 		goto cleanup;
 
-	error = git_config_find_global(config_path);
-	if (error == GIT_SUCCESS) {
-		error = git_config_add_file_ondisk(*out, config_path, 2);
+	if (global_config_path != NULL) {
+		error = git_config_add_file_ondisk(*out, global_config_path, 2);
+		if (error < GIT_SUCCESS)
+			goto cleanup;
 	}
 
 	if (system_config_path != NULL) {
@@ -305,6 +307,24 @@ cleanup:
 	return error;
 }
 
+int git_repository_config_autoload(
+		git_config **out,
+		git_repository *repo)
+{
+	char global[GIT_PATH_MAX], system[GIT_PATH_MAX];
+	char *global_path, *system_path;
+	int error;
+
+
+	error = git_config_find_global(global);
+	global_path = error < GIT_SUCCESS ? NULL : global;
+
+	error = git_config_find_system(system);
+	system_path = error < GIT_SUCCESS ? NULL : system;
+
+	return git_repository_config(out, repo, global_path, system_path);
+}
+
 static int discover_repository_dirs(git_repository *repo, const char *path)
 {
 	int error;
diff --git a/tests-clay/network/remotes.c b/tests-clay/network/remotes.c
index ae8d89f..a7cc742 100644
--- a/tests-clay/network/remotes.c
+++ b/tests-clay/network/remotes.c
@@ -11,7 +11,7 @@ void test_network_remotes__initialize(void)
 {
 	cl_fixture_sandbox(REPOSITORY_FOLDER);
 	cl_git_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	cl_git_pass(git_repository_config(&cfg, repo, NULL));
+	cl_git_pass(git_repository_config(&cfg, repo, NULL, NULL));
 	cl_git_pass(git_remote_get(&remote, cfg, "test"));
 	refspec = git_remote_fetchspec(remote);
 	cl_assert(refspec != NULL);
diff --git a/tests/t15-config.c b/tests/t15-config.c
index ac2d79c..40c4eb9 100644
--- a/tests/t15-config.c
+++ b/tests/t15-config.c
@@ -30,6 +30,7 @@
 #include "filebuf.h"
 
 #define CONFIG_BASE TEST_RESOURCES "/config"
+#define GLOBAL_CONFIG CONFIG_BASE "/.gitconfig"
 
 /*
  * This one is so we know the code isn't completely broken
@@ -233,40 +234,26 @@ BEGIN_TEST(config10, "a repo's config overrides the global config")
 	git_repository *repo;
 	git_config *cfg;
 	int version;
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", CONFIG_BASE, 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, GLOBAL_CONFIG, NULL));
 	must_pass(git_config_get_int(cfg, "core.repositoryformatversion", &version));
 	must_be_true(version == 0);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_TEST(config11, "fall back to the global config")
 	git_repository *repo;
 	git_config *cfg;
 	int num;
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", CONFIG_BASE, 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, GLOBAL_CONFIG, NULL));
 	must_pass(git_config_get_int(cfg, "core.something", &num));
 	must_be_true(num == 2);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_TEST(config12, "delete a value")
diff --git a/tests/t16-remotes.c b/tests/t16-remotes.c
index af54f29..ac98bdf 100644
--- a/tests/t16-remotes.c
+++ b/tests/t16-remotes.c
@@ -32,13 +32,9 @@ BEGIN_TEST(remotes0, "remote parsing works")
 	git_remote *remote;
 	git_repository *repo;
 	git_config *cfg;
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, NULL, NULL));
 	must_pass(git_remote_get(&remote, cfg, "test"));
 	must_be_true(!strcmp(git_remote_name(remote), "test"));
 	must_be_true(!strcmp(git_remote_url(remote), "git://github.com/libgit2/libgit2"));
@@ -46,9 +42,6 @@ BEGIN_TEST(remotes0, "remote parsing works")
 	git_remote_free(remote);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_TEST(refspec0, "remote with refspec works")
@@ -56,13 +49,9 @@ BEGIN_TEST(refspec0, "remote with refspec works")
 	git_repository *repo;
 	git_config *cfg;
 	const git_refspec *refspec = NULL;
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, NULL, NULL));
 	must_pass(git_remote_get(&remote, cfg, "test"));
 	refspec = git_remote_fetchspec(remote);
 	must_be_true(refspec != NULL);
@@ -71,9 +60,6 @@ BEGIN_TEST(refspec0, "remote with refspec works")
 	git_remote_free(remote);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_TEST(refspec1, "remote fnmatch works as expected")
@@ -81,13 +67,9 @@ BEGIN_TEST(refspec1, "remote fnmatch works as expected")
 	git_repository *repo;
 	git_config *cfg;
 	const git_refspec *refspec = NULL;
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, NULL, NULL));
 	must_pass(git_remote_get(&remote, cfg, "test"));
 	refspec = git_remote_fetchspec(remote);
 	must_be_true(refspec != NULL);
@@ -96,9 +78,6 @@ BEGIN_TEST(refspec1, "remote fnmatch works as expected")
 	git_remote_free(remote);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_TEST(refspec2, "refspec transform")
@@ -107,13 +86,9 @@ BEGIN_TEST(refspec2, "refspec transform")
 	git_config *cfg;
 	const git_refspec *refspec = NULL;
 	char ref[1024] = {0};
-	char *old_home;
-
-	old_home = git__strdup(getenv("HOME"));
-	p_setenv("HOME", "/dev/null", 1);
 
 	must_pass(git_repository_open(&repo, REPOSITORY_FOLDER));
-	must_pass(git_repository_config(&cfg, repo, NULL));
+	must_pass(git_repository_config(&cfg, repo, NULL, NULL));
 	must_pass(git_remote_get(&remote, cfg, "test"));
 	refspec = git_remote_fetchspec(remote);
 	must_be_true(refspec != NULL);
@@ -122,9 +97,6 @@ BEGIN_TEST(refspec2, "refspec transform")
 	git_remote_free(remote);
 	git_config_free(cfg);
 	git_repository_free(repo);
-
-	p_setenv("HOME", old_home, 1);
-	free(old_home);
 END_TEST
 
 BEGIN_SUITE(remotes)