diff --git a/include/git2/repository.h b/include/git2/repository.h index d12cfbec7..b1fb5db83 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 a39ccb63e..328bc0d57 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 ae8d89fbc..a7cc742db 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 ac2d79cfd..40c4eb9d5 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 af54f297d..ac98bdf5e 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)