mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-20 18:33:35 +00:00
repo: unconditionally create a global config backend
When a repository is initialised, we need to probe to see if there is a global config to load. If this is not the case, the user isn't able to write to the global config without creating the backend and adding it themselves, which is inconvenient and overly complex. Unconditionally create and add a backend for the global config file regardless of whether it exists as a convenience for users. To enable this, we allow creating backends to files that do not exist yet, changing the semantics somewhat, and making some tests invalid.
This commit is contained in:
parent
3405f78754
commit
a4b75dcf56
41
src/config.c
41
src/config.c
@ -91,13 +91,15 @@ int git_config_add_file_ondisk(
|
||||
int force)
|
||||
{
|
||||
git_config_backend *file = NULL;
|
||||
struct stat st;
|
||||
int res;
|
||||
|
||||
assert(cfg && path);
|
||||
|
||||
if (!git_path_isfile(path)) {
|
||||
giterr_set(GITERR_CONFIG, "Cannot find config file '%s'", path);
|
||||
return GIT_ENOTFOUND;
|
||||
res = p_stat(path, &st);
|
||||
if (res < 0 && errno != ENOENT) {
|
||||
giterr_set(GITERR_CONFIG, "Error stat'ing config file '%s'", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (git_config_file__ondisk(&file, path) < 0)
|
||||
@ -381,7 +383,6 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
|
||||
|
||||
internal = git_vector_get(&cfg->files, 0);
|
||||
if (!internal)
|
||||
/* Should we auto-vivify .git/config? Tricky from this location */
|
||||
return config_error_nofiles(name);
|
||||
file = internal->file;
|
||||
|
||||
@ -598,6 +599,33 @@ int git_config_find_system(char *system_config_path, size_t length)
|
||||
system_config_path, length, git_config_find_system_r);
|
||||
}
|
||||
|
||||
int git_config__global_location(git_buf *buf)
|
||||
{
|
||||
const git_buf *paths;
|
||||
const char *sep, *start;
|
||||
size_t len;
|
||||
|
||||
if (git_futils_dirs_get(&paths, GIT_FUTILS_DIR_GLOBAL) < 0)
|
||||
return -1;
|
||||
|
||||
/* no paths, so give up */
|
||||
if (git_buf_len(paths) == 0)
|
||||
return -1;
|
||||
|
||||
start = git_buf_cstr(paths);
|
||||
sep = strchr(start, GIT_PATH_LIST_SEPARATOR);
|
||||
|
||||
if (sep)
|
||||
len = sep - start;
|
||||
else
|
||||
len = paths->size;
|
||||
|
||||
if (git_buf_set(buf, start, len) < 0)
|
||||
return -1;
|
||||
|
||||
return git_buf_joinpath(buf, buf->ptr, GIT_CONFIG_FILENAME_GLOBAL);
|
||||
}
|
||||
|
||||
int git_config_open_default(git_config **out)
|
||||
{
|
||||
int error;
|
||||
@ -606,9 +634,12 @@ int git_config_open_default(git_config **out)
|
||||
|
||||
error = git_config_new(&cfg);
|
||||
|
||||
if (!error && !git_config_find_global_r(&buf))
|
||||
if (!error && (!git_config_find_global_r(&buf) ||
|
||||
!git_config__global_location(&buf))) {
|
||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||
GIT_CONFIG_LEVEL_GLOBAL, 0);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!error && !git_config_find_xdg_r(&buf))
|
||||
error = git_config_add_file_ondisk(cfg, buf.ptr,
|
||||
|
@ -28,6 +28,9 @@ extern int git_config_find_global_r(git_buf *global_config_path);
|
||||
extern int git_config_find_xdg_r(git_buf *system_config_path);
|
||||
extern int git_config_find_system_r(git_buf *system_config_path);
|
||||
|
||||
|
||||
extern int git_config__global_location(git_buf *buf);
|
||||
|
||||
extern int git_config_rename_section(
|
||||
git_repository *repo,
|
||||
const char *old_section_name, /* eg "branch.dummy" */
|
||||
|
@ -594,6 +594,10 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
|
||||
git_config_find_xdg_r(&xdg_buf);
|
||||
git_config_find_system_r(&system_buf);
|
||||
|
||||
/* If there is no global file, open a backend for it anyway */
|
||||
if (git_buf_len(&global_buf) == 0)
|
||||
git_config__global_location(&global_buf);
|
||||
|
||||
error = load_config(
|
||||
&config, repo,
|
||||
path_unless_empty(&global_buf),
|
||||
|
@ -449,10 +449,3 @@ void test_config_read__can_load_and_parse_an_empty_config_file(void)
|
||||
|
||||
git_config_free(cfg);
|
||||
}
|
||||
|
||||
void test_config_read__cannot_load_a_non_existing_config_file(void)
|
||||
{
|
||||
git_config *cfg;
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_config_open_ondisk(&cfg, "./no.config"));
|
||||
}
|
||||
|
75
tests-clar/repo/config.c
Normal file
75
tests-clar/repo/config.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "fileops.h"
|
||||
#include <ctype.h>
|
||||
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
void test_repo_config__initialize(void)
|
||||
{
|
||||
cl_fixture_sandbox("empty_standard_repo");
|
||||
cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git"));
|
||||
|
||||
git_buf_clear(&path);
|
||||
|
||||
cl_must_pass(p_mkdir("alternate", 0777));
|
||||
cl_git_pass(git_path_prettify(&path, "alternate", NULL));
|
||||
|
||||
}
|
||||
|
||||
void test_repo_config__cleanup(void)
|
||||
{
|
||||
cl_git_pass(git_futils_rmdir_r(path.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
|
||||
|
||||
git_buf_free(&path);
|
||||
cl_fixture_cleanup("empty_standard_repo");
|
||||
}
|
||||
|
||||
void test_repo_config__open_missing_global(void)
|
||||
{
|
||||
git_repository *repo;
|
||||
git_config *config, *global;
|
||||
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
|
||||
|
||||
cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
|
||||
cl_git_pass(git_repository_config(&config, repo));
|
||||
cl_git_pass(git_config_open_level(&global, config, GIT_CONFIG_LEVEL_GLOBAL));
|
||||
|
||||
cl_git_pass(git_config_set_string(global, "test.set", "42"));
|
||||
|
||||
git_config_free(global);
|
||||
git_config_free(config);
|
||||
git_repository_free(repo);
|
||||
}
|
||||
|
||||
void test_repo_config__open_missing_global_with_separators(void)
|
||||
{
|
||||
git_repository *repo;
|
||||
git_config *config, *global;
|
||||
|
||||
cl_git_pass(git_buf_printf(&path, "%c%s", GIT_PATH_LIST_SEPARATOR, "dummy"));
|
||||
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, path.ptr));
|
||||
cl_git_pass(git_libgit2_opts(
|
||||
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, path.ptr));
|
||||
|
||||
git_buf_free(&path);
|
||||
|
||||
cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
|
||||
cl_git_pass(git_repository_config(&config, repo));
|
||||
cl_git_pass(git_config_open_level(&global, config, GIT_CONFIG_LEVEL_GLOBAL));
|
||||
|
||||
cl_git_pass(git_config_set_string(global, "test.set", "42"));
|
||||
|
||||
git_config_free(global);
|
||||
git_config_free(config);
|
||||
git_repository_free(repo);
|
||||
}
|
@ -309,7 +309,7 @@ void test_repo_open__no_config(void)
|
||||
cl_git_pass(git_repository_open(&repo, "empty_standard_repo"));
|
||||
cl_git_pass(git_repository_config(&config, repo));
|
||||
|
||||
cl_git_fail(git_config_set_string(config, "test.set", "42"));
|
||||
cl_git_pass(git_config_set_string(config, "test.set", "42"));
|
||||
|
||||
git_config_free(config);
|
||||
git_repository_free(repo);
|
||||
|
Loading…
Reference in New Issue
Block a user