X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=config.c;h=3e077d4c6ca4f7162e3a3254e1b3e90db33270ff;hb=061303f0b50a648db8e0af23791fc56181f6bf93;hp=2ae6153e5ee29ca88f52241d1ece79069d8c5875;hpb=52bc0e294c0d5924db0e5e8f25284e467c6d2983;p=git.git diff --git a/config.c b/config.c index 2ae6153e5..3e077d4c6 100644 --- a/config.c +++ b/config.c @@ -280,17 +280,17 @@ int git_default_config(const char *var, const char *value) } if (!strcmp(var, "user.name")) { - strncpy(git_default_name, value, sizeof(git_default_name)); + safe_strncpy(git_default_name, value, sizeof(git_default_name)); return 0; } if (!strcmp(var, "user.email")) { - strncpy(git_default_email, value, sizeof(git_default_email)); + safe_strncpy(git_default_email, value, sizeof(git_default_email)); return 0; } if (!strcmp(var, "i18n.commitencoding")) { - strncpy(git_commit_encoding, value, sizeof(git_commit_encoding)); + safe_strncpy(git_commit_encoding, value, sizeof(git_commit_encoding)); return 0; } @@ -317,7 +317,33 @@ int git_config_from_file(config_fn_t fn, const char *filename) int git_config(config_fn_t fn) { - return git_config_from_file(fn, git_path("config")); + int ret = 0; + char *repo_config = NULL; + const char *home = NULL, *filename; + + /* $GIT_CONFIG makes git read _only_ the given config file, + * $GIT_CONFIG_LOCAL will make it process it in addition to the + * global config file, the same way it would the per-repository + * config file otherwise. */ + filename = getenv("GIT_CONFIG"); + if (!filename) { + home = getenv("HOME"); + filename = getenv("GIT_CONFIG_LOCAL"); + if (!filename) + filename = repo_config = strdup(git_path("config")); + } + + if (home) { + char *user_config = strdup(mkpath("%s/.gitconfig", home)); + if (!access(user_config, R_OK)) + ret = git_config_from_file(fn, user_config); + free(user_config); + } + + ret += git_config_from_file(fn, filename); + if (repo_config) + free(repo_config); + return ret; } /* @@ -490,10 +516,19 @@ int git_config_set_multivar(const char* key, const char* value, int i, dot; int fd = -1, in_fd; int ret; - char* config_filename = strdup(git_path("config")); - char* lock_file = strdup(git_path("config.lock")); + char* config_filename; + char* lock_file; const char* last_dot = strrchr(key, '.'); + config_filename = getenv("GIT_CONFIG"); + if (!config_filename) { + config_filename = getenv("GIT_CONFIG_LOCAL"); + if (!config_filename) + config_filename = git_path("config"); + } + config_filename = strdup(config_filename); + lock_file = strdup(mkpath("%s.lock", config_filename)); + /* * Since "key" actually contains the section name and the real * key name separated by a dot, we have to know where the dot is. @@ -536,7 +571,7 @@ int git_config_set_multivar(const char* key, const char* value, * contents of .git/config will be written into it. */ fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666); - if (fd < 0) { + if (fd < 0 || adjust_shared_perm(lock_file)) { fprintf(stderr, "could not lock config file\n"); free(store.key); ret = -1; @@ -600,7 +635,7 @@ int git_config_set_multivar(const char* key, const char* value, * As a side effect, we make sure to transform only a valid * existing config file. */ - if (git_config(store_aux)) { + if (git_config_from_file(store_aux, config_filename)) { fprintf(stderr, "invalid config file\n"); free(store.key); if (store.value_regex != NULL) {