Code

Read configuration also from $HOME/.gitconfig
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>
Mon, 19 Jun 2006 23:48:03 +0000 (01:48 +0200)
committerJunio C Hamano <junkio@cox.net>
Tue, 20 Jun 2006 00:53:13 +0000 (17:53 -0700)
This patch is based on Pasky's, with three notable differences:

- I did not yet update the documentation
- I named it .gitconfig, not .gitrc
- git-repo-config does not barf when a unique key is overridden locally

The last means that if you have something like

[alias]
l = log --stat -M

in ~/.gitconfig, and

[alias]
l = log --stat -M next..

in $GIT_DIR/config, then

git-repo-config alias.l

returns only one value, namely the value from $GIT_DIR/config.

If you set the environment variable GIT_CONFIG, $HOME/.gitconfig is not
read, and neither $GIT_DIR/config, but $GIT_CONFIG instead.

If you set GIT_CONFIG_LOCAL instead, it is interpreted instead of
$GIT_DIR/config, but $HOME/.gitconfig is still read.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
config.c
repo-config.c

index 37862d429f473d974a53d55315a23683d25aa3cb..d064f429cb4369ac08f7ad267b0b182112462b16 100644 (file)
--- a/config.c
+++ b/config.c
@@ -317,17 +317,33 @@ int git_config_from_file(config_fn_t fn, const char *filename)
 
 int git_config(config_fn_t fn)
 {
-       const char *filename = git_path("config");
-       /* Forward-compatibility cue: $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. */
-       if (getenv("GIT_CONFIG")) {
-               filename = getenv("GIT_CONFIG");
-       } else if (getenv("GIT_CONFIG_LOCAL")) {
+       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"));
        }
-       return git_config_from_file(fn, filename);
+
+       if (home) {
+               char *user_config = strdup(mkpath("%s/.gitconfig", home));
+               if (access(user_config, R_OK) > 0)
+                       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;
 }
 
 /*
index 08fc4cc57d064248247c912014e4eba32490f0ff..03f108fe2f8a624075e7e7db4177df13dc38372f 100644 (file)
@@ -64,7 +64,22 @@ static int show_config(const char* key_, const char* value_)
 
 static int get_value(const char* key_, const char* regex_)
 {
+       int ret = -1;
        char *tl;
+       char *global = NULL, *repo_config = NULL;
+       const char *local;
+
+       local = getenv("GIT_CONFIG");
+       if (!local) {
+               const char *home = getenv("HOME");
+               local = getenv("GIT_CONFIG_LOCAL");
+               if (!local)
+                       local = repo_config;
+               else
+                       local = repo_config = strdup(git_path("config"));
+               if (home)
+                       global = strdup(mkpath("%s/.gitconfig", home));
+       }
 
        key = strdup(key_);
        for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
@@ -76,7 +91,7 @@ static int get_value(const char* key_, const char* regex_)
                key_regexp = (regex_t*)malloc(sizeof(regex_t));
                if (regcomp(key_regexp, key, REG_EXTENDED)) {
                        fprintf(stderr, "Invalid key pattern: %s\n", key_);
-                       return -1;
+                       goto free_strings;
                }
        }
 
@@ -89,11 +104,16 @@ static int get_value(const char* key_, const char* regex_)
                regexp = (regex_t*)malloc(sizeof(regex_t));
                if (regcomp(regexp, regex_, REG_EXTENDED)) {
                        fprintf(stderr, "Invalid pattern: %s\n", regex_);
-                       return -1;
+                       goto free_strings;
                }
        }
 
-       git_config(show_config);
+       if (do_all && global)
+               git_config_from_file(show_config, global);
+       git_config_from_file(show_config, local);
+       if (!do_all && !seen && global)
+               git_config_from_file(show_config, global);
+
        free(key);
        if (regexp) {
                regfree(regexp);
@@ -101,9 +121,16 @@ static int get_value(const char* key_, const char* regex_)
        }
 
        if (do_all)
-               return !seen;
-
-       return (seen == 1) ? 0 : 1;
+               ret = !seen;
+       else
+               ret =  (seen == 1) ? 0 : 1;
+
+free_strings:
+       if (repo_config)
+               free(repo_config);
+       if (global)
+               free(global);
+       return ret;
 }
 
 int main(int argc, const char **argv)