On Mon, Aug 12, 2013 at 09:52:45PM +1000, Andrew Ardill wrote: > On 11 August 2013 02:58, Junio C Hamano <gitster@xxxxxxxxx> wrote: > > Perhaps we need a lighter-weight mechanism > > > > git init --profile=open > > git clone --profile=open git://git.kernel.org/git.git > > This is something I would definitely use. > > All of my work git directories are in a separate folder to my other > git directories, and as such it would be extremely convenient if every > repository under that folder defaulted to the same profile. That may > be asking for too much though! We could do something like the patch below, which allows: $ git config --global include./magic/.path .gitconfig-magic to read ~/.gitconfig-magic only when we are in a repository with a directory component "/magic/". I can see how such a thing might be useful, even though I do not have a use for that much flexibility myself. I find myself doing this trick for things like editor settings, but not for git config. So do not count this necessarily as a vote for doing this; it was a fun exercise for me that others might find useful. Comparing this against a "profile" type of solution: 1. This handles only config, not full templates (so no custom hooks; however, we could provide a level of indirection for hooks inside the config). 2. Unlike a profile that is used during repository init, this is resolved at runtime, so it keeps up to date as you change ~/.gitconfig-magic. --- diff --git a/config.c b/config.c index e13a7b6..a31dc85 100644 --- a/config.c +++ b/config.c @@ -119,10 +119,45 @@ int git_config_include(const char *var, const char *value, void *data) return ret; } +static NORETURN void die_bad_regex(int err, regex_t *re) +{ + char errbuf[1024]; + regerror(err, re, errbuf, sizeof(errbuf)); + if (cf && cf->name) + die("bad regex (at %s:%d): %s", cf->name, cf->linenr, errbuf); + else + die("bad regex: %s", errbuf); +} + +static int match_repo_path(const char *re_str) +{ + regex_t re; + int ret; + const char *repo_path; + + ret = regcomp(&re, re_str, REG_EXTENDED); + if (ret) + die_bad_regex(ret, &re); + + repo_path = absolute_path(get_git_dir()); + ret = regexec(&re, repo_path, 0, NULL, 0); + regfree(&re); + return !ret; +} + +static int match_repo_path_mem(const char *re_buf, int len) +{ + char *re_str = xmemdupz(re_buf, len); + int ret = match_repo_path(re_str); + free(re_str); + return ret; +} + int git_config_include(const char *var, const char *value, void *data) { struct config_include_data *inc = data; - const char *type; + const char *match, *type; + int match_len; int ret; /* @@ -133,8 +168,9 @@ int git_config_include(const char *var, const char *value, void *data) if (ret < 0) return ret; - type = skip_prefix(var, "include."); - if (!type) + if (parse_config_key(var, "include", &match, &match_len, &type)) + return ret; + if (match && !match_repo_path_mem(match, match_len)) return ret; if (!strcmp(type, "path")) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html