]> git.ipfire.org Git - thirdparty/git.git/blobdiff - config.c
git-svn: find-rev and rebase for SVN::Mirror repositories
[thirdparty/git.git] / config.c
index 5195de10c9289a25053756ce799e654d5e01483e..2862cc45cbb1752153bb6050b4e6bd53f6660724 100644 (file)
--- a/config.c
+++ b/config.c
@@ -16,6 +16,8 @@ static int config_linenr;
 static int config_file_eof;
 static int zlib_compression_seen;
 
+const char *config_exclusive_filename = NULL;
+
 static int get_next_char(void)
 {
        int c;
@@ -111,7 +113,7 @@ static inline int iskeychar(int c)
        return isalnum(c) || c == '-';
 }
 
-static int get_value(config_fn_t fn, char *name, unsigned int len)
+static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
 {
        int c;
        char *value;
@@ -139,7 +141,7 @@ static int get_value(config_fn_t fn, char *name, unsigned int len)
                if (!value)
                        return -1;
        }
-       return fn(name, value);
+       return fn(name, value, data);
 }
 
 static int get_extended_base_var(char *name, int baselen, int c)
@@ -197,7 +199,7 @@ static int get_base_var(char *name)
        }
 }
 
-static int git_parse_file(config_fn_t fn)
+static int git_parse_file(config_fn_t fn, void *data)
 {
        int comment = 0;
        int baselen = 0;
@@ -228,7 +230,7 @@ static int git_parse_file(config_fn_t fn)
                if (!isalpha(c))
                        break;
                var[baselen] = tolower(c);
-               if (get_value(fn, var, baselen+1) < 0)
+               if (get_value(fn, data, var, baselen+1) < 0)
                        break;
        }
        die("bad config file line %d in %s", config_linenr, config_file_name);
@@ -332,7 +334,7 @@ int git_config_string(const char **dest, const char *var, const char *value)
        return 0;
 }
 
-int git_default_config(const char *var, const char *value)
+static int git_default_core_config(const char *var, const char *value)
 {
        /* This needs a better name */
        if (!strcmp(var, "core.filemode")) {
@@ -444,6 +446,33 @@ int git_default_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.pager"))
+               return git_config_string(&pager_program, var, value);
+
+       if (!strcmp(var, "core.editor"))
+               return git_config_string(&editor_program, var, value);
+
+       if (!strcmp(var, "core.excludesfile"))
+               return git_config_string(&excludes_file, var, value);
+
+       if (!strcmp(var, "core.whitespace")) {
+               if (!value)
+                       return config_error_nonbool(var);
+               whitespace_rule_cfg = parse_whitespace_rule(value);
+               return 0;
+       }
+
+       if (!strcmp(var, "core.fsyncobjectfiles")) {
+               fsync_object_files = git_config_bool(var, value);
+               return 0;
+       }
+
+       /* Add other config variables here and to Documentation/config.txt. */
+       return 0;
+}
+
+static int git_default_user_config(const char *var, const char *value)
+{
        if (!strcmp(var, "user.name")) {
                if (!value)
                        return config_error_nonbool(var);
@@ -462,32 +491,24 @@ int git_default_config(const char *var, const char *value)
                return 0;
        }
 
+       /* Add other config variables here and to Documentation/config.txt. */
+       return 0;
+}
+
+static int git_default_i18n_config(const char *var, const char *value)
+{
        if (!strcmp(var, "i18n.commitencoding"))
                return git_config_string(&git_commit_encoding, var, value);
 
        if (!strcmp(var, "i18n.logoutputencoding"))
                return git_config_string(&git_log_output_encoding, var, value);
 
-       if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
-               pager_use_color = git_config_bool(var,value);
-               return 0;
-       }
-
-       if (!strcmp(var, "core.pager"))
-               return git_config_string(&pager_program, var, value);
-
-       if (!strcmp(var, "core.editor"))
-               return git_config_string(&editor_program, var, value);
-
-       if (!strcmp(var, "core.excludesfile"))
-               return git_config_string(&excludes_file, var, value);
+       /* Add other config variables here and to Documentation/config.txt. */
+       return 0;
+}
 
-       if (!strcmp(var, "core.whitespace")) {
-               if (!value)
-                       return config_error_nonbool(var);
-               whitespace_rule_cfg = parse_whitespace_rule(value);
-               return 0;
-       }
+static int git_default_branch_config(const char *var, const char *value)
+{
        if (!strcmp(var, "branch.autosetupmerge")) {
                if (value && !strcasecmp(value, "always")) {
                        git_branch_track = BRANCH_TRACK_ALWAYS;
@@ -516,7 +537,30 @@ int git_default_config(const char *var, const char *value)
        return 0;
 }
 
-int git_config_from_file(config_fn_t fn, const char *filename)
+int git_default_config(const char *var, const char *value, void *dummy)
+{
+       if (!prefixcmp(var, "core."))
+               return git_default_core_config(var, value);
+
+       if (!prefixcmp(var, "user."))
+               return git_default_user_config(var, value);
+
+       if (!prefixcmp(var, "i18n."))
+               return git_default_i18n_config(var, value);
+
+       if (!prefixcmp(var, "branch."))
+               return git_default_branch_config(var, value);
+
+       if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
+               pager_use_color = git_config_bool(var,value);
+               return 0;
+       }
+
+       /* Add other config variables here and to Documentation/config.txt. */
+       return 0;
+}
+
+int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 {
        int ret;
        FILE *f = fopen(filename, "r");
@@ -527,7 +571,7 @@ int git_config_from_file(config_fn_t fn, const char *filename)
                config_file_name = filename;
                config_linenr = 1;
                config_file_eof = 0;
-               ret = git_parse_file(fn);
+               ret = git_parse_file(fn, data);
                fclose(f);
                config_file_name = NULL;
        }
@@ -549,7 +593,7 @@ const char *git_etc_gitconfig(void)
        return system_wide;
 }
 
-int git_env_bool(const char *k, int def)
+static int git_env_bool(const char *k, int def)
 {
        const char *v = getenv(k);
        return v ? git_config_bool(k, v) : def;
@@ -565,34 +609,32 @@ int git_config_global(void)
        return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
 }
 
-int git_config(config_fn_t fn)
+int git_config(config_fn_t fn, void *data)
 {
        int ret = 0;
        char *repo_config = NULL;
-       const char *home = NULL, *filename;
+       const char *home = NULL;
 
        /* $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(CONFIG_ENVIRONMENT);
-       if (!filename) {
-               if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
-                       ret += git_config_from_file(fn, git_etc_gitconfig());
-               home = getenv("HOME");
-               filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
-               if (!filename)
-                       filename = repo_config = xstrdup(git_path("config"));
-       }
+       if (config_exclusive_filename)
+               return git_config_from_file(fn, config_exclusive_filename, data);
+       if (git_config_system() && !access(git_etc_gitconfig(), R_OK))
+               ret += git_config_from_file(fn, git_etc_gitconfig(),
+                                           data);
 
+       home = getenv("HOME");
        if (git_config_global() && home) {
                char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
                if (!access(user_config, R_OK))
-                       ret = git_config_from_file(fn, user_config);
+                       ret += git_config_from_file(fn, user_config, data);
                free(user_config);
        }
 
-       ret += git_config_from_file(fn, filename);
+       repo_config = xstrdup(git_path("config"));
+       ret += git_config_from_file(fn, repo_config, data);
        free(repo_config);
        return ret;
 }
@@ -622,7 +664,7 @@ static int matches(const char* key, const char* value)
                  !regexec(store.value_regex, value, 0, NULL, 0)));
 }
 
-static int store_aux(const char* key, const char* value)
+static int store_aux(const char* key, const char* value, void *cb)
 {
        const char *ep;
        size_t section_len;
@@ -830,13 +872,10 @@ int git_config_set_multivar(const char* key, const char* value,
        struct lock_file *lock = NULL;
        const char* last_dot = strrchr(key, '.');
 
-       config_filename = getenv(CONFIG_ENVIRONMENT);
-       if (!config_filename) {
-               config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
-               if (!config_filename)
-                       config_filename  = git_path("config");
-       }
-       config_filename = xstrdup(config_filename);
+       if (config_exclusive_filename)
+               config_filename = xstrdup(config_exclusive_filename);
+       else
+               config_filename = xstrdup(git_path("config"));
 
        /*
         * Since "key" actually contains the section name and the real
@@ -951,7 +990,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_from_file(store_aux, config_filename)) {
+               if (git_config_from_file(store_aux, config_filename, NULL)) {
                        error("invalid config file %s", config_filename);
                        free(store.key);
                        if (store.value_regex != NULL) {
@@ -1093,13 +1132,10 @@ int git_config_rename_section(const char *old_name, const char *new_name)
        int out_fd;
        char buf[1024];
 
-       config_filename = getenv(CONFIG_ENVIRONMENT);
-       if (!config_filename) {
-               config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
-               if (!config_filename)
-                       config_filename  = git_path("config");
-       }
-       config_filename = xstrdup(config_filename);
+       if (config_exclusive_filename)
+               config_filename = xstrdup(config_exclusive_filename);
+       else
+               config_filename = xstrdup(git_path("config"));
        out_fd = hold_lock_file_for_update(lock, config_filename, 0);
        if (out_fd < 0) {
                ret = error("could not lock config file %s", config_filename);