From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Eli Barzilay" <eli@barzilay.org>,
"Heiko Voigt" <hvoigt@hvoigt.net>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH/RFC] Hacky version of a glob() driven config include
Date: Thu, 6 May 2010 21:14:00 +0000 [thread overview]
Message-ID: <1273180440-8641-1-git-send-email-avarab@gmail.com> (raw)
In-Reply-To: <u2i51dd1af81004060115t5f837840z5adcf83622fa8882@mail.gmail.com>
This is not ready for inclusion in anything. Commiting for RFC on
whether this way of doing it is sane in theory.
Known bugs:
* Breaks the model of being able to *set* config values. That
doesn't work for the included files. Maybe not a bug.
* Errors in the git_config_from_file() call in glob_include_config()
aren't passed upwards.
* It relies on the GNU GLOB_TILDE extension with no
alternative. That can be done by calling getenv("HOME") and
s/~/$home/.
* The whole bit with saving/restoring global state for config
inclusion is evil, but then again so is the global state.
* We don't check for recursion. But Git gives up eventually after
after spewing a *lot* of duplicate entry errors. Not sure how to
do this sanely w/symlinks.
Not-signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
> On Sun, Apr 4, 2010 at 07:50, Eli Barzilay <eli@barzilay.org> wrote:
> > Isn't it better to have a way to include files instead?
>
> Probably yes. Programs like Apache HTTPD, rsyslog and others just use
> ${foo}conf.d by convention by supporting config inclusion.
Here's an evil implementation of this. I know the code is horrid &
buggy (see above). But is the general idea sane. I thought it would be
better to submit this for comments before I went further with it.
config.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
t/t1300-repo-config.sh | 43 +++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 1 deletions(-)
diff --git a/config.c b/config.c
index 6963fbe..e7581b4 100644
--- a/config.c
+++ b/config.c
@@ -7,6 +7,7 @@
*/
#include "cache.h"
#include "exec_cmd.h"
+#include <glob.h>
#define MAXNAME (256)
@@ -111,6 +112,52 @@ static inline int iskeychar(int c)
return isalnum(c) || c == '-';
}
+static void glob_include_config(config_fn_t fn, void *data, char *pattern)
+{
+ glob_t globber;
+ int glob_ret;
+ int conf_ret;
+ size_t i = 0;
+ char *cfile = NULL;
+ FILE *saved_config_file;
+ char *saved_config_file_name;
+ int saved_config_linenr;
+ int saved_config_file_eof;
+#ifdef GLOB_TILDE
+ int glob_flags = GLOB_TILDE;
+#else
+ /* XXX: Non-GNU support for ~ expansion */
+ int glob_flags = 0;
+#endif
+
+ glob_ret = glob(pattern, glob_flags, NULL, &globber);
+
+ if (glob_ret == GLOB_NOSPACE || glob_ret == GLOB_ABORTED) {
+ globfree(&globber);
+ die("Unable to include config with pattern %s", pattern);
+ }
+
+ for (i = 0; i < globber.gl_pathc; i++) {
+ cfile = globber.gl_pathv[i];
+
+ /* Save away global state for including another file */
+ saved_config_file = config_file;
+ saved_config_file_name = config_file_name;
+ saved_config_linenr = config_linenr;
+ saved_config_file_eof = config_file_eof;
+
+ conf_ret = git_config_from_file(fn, cfile, data);
+
+ /* Restore it again */
+ config_file = saved_config_file;
+ config_file_name = saved_config_file_name;
+ config_linenr = saved_config_linenr;
+ config_file_eof = saved_config_file_eof;
+ }
+
+ globfree(&globber);
+}
+
static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
{
int c;
@@ -139,7 +186,13 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
if (!value)
return -1;
}
- return fn(name, value, data);
+
+ if (!strcmp(name, "voodoo.include")) {
+ glob_include_config(fn, data, value);
+ return 0;
+ } else {
+ return fn(name, value, data);
+ }
}
static int get_extended_base_var(char *name, int baselen, int c)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index f11f98c..4df6658 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -824,4 +824,47 @@ test_expect_success 'check split_cmdline return' "
test_must_fail git merge master
"
+cat > .git/config << EOF
+[some]
+ variable = blah
+[voodoo]
+ include = .git/more_config_*
+EOF
+
+cat > .git/more_config_1 << EOF
+[another]
+ variable = blah blah
+EOF
+
+cat > .git/more_config_2 << EOF
+[evenmore]
+ variable = blah bluh
+EOF
+
+test_expect_success 'The voodoo include variable is hidden from us' \
+ 'test_must_fail git config --get voodoo.include'
+test_expect_success 'get some included variable' \
+ 'git config --get some.variable'
+test_expect_success 'get another included variable' \
+ 'git config --get another.variable'
+test_expect_success 'get evenmore included variable' \
+ 'git config --get evenmore.variable'
+
+rm .git/more_config*
+
+cat > .git/config << EOF
+[voodoo]
+ include = .git/more_config_*
+EOF
+
+cat > .git/more_config_1 << EOF
+[foo]
+ bar = zar
+[voodoo]
+ include = .git/more_config_*
+EOF
+
+test_expect_success 'circular config inclusion' \
+ 'test_must_fail git config --get foo.bar'
+
test_done
--
1.7.1.dirty
next prev parent reply other threads:[~2010-05-06 21:14 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-01 21:20 Is there interest in reading ~/.gitconfig.d/* and /etc/gitconfig.d/*? Ævar Arnfjörð Bjarmason
2010-04-01 22:03 ` Heiko Voigt
2010-04-04 7:24 ` Peter Krefting
2010-04-04 7:59 ` Eli Barzilay
[not found] ` <19384.17579.205005.86711@winooski.ccs.neu.edu>
2010-04-06 8:15 ` Ævar Arnfjörð Bjarmason
2010-04-06 9:02 ` Jakub Narebski
2010-05-06 21:14 ` Ævar Arnfjörð Bjarmason [this message]
2010-05-07 6:00 ` [PATCH/RFC] Hacky version of a glob() driven config include Bert Wesarg
2010-05-07 16:56 ` Ævar Arnfjörð Bjarmason
2010-05-07 18:29 ` Bert Wesarg
2010-05-07 18:58 ` Ævar Arnfjörð Bjarmason
2010-05-07 19:02 ` Jacob Helwig
2010-05-07 19:52 ` Bert Wesarg
2010-05-07 20:11 ` [PATCH/RFC v2] " Ævar Arnfjörð Bjarmason
2010-05-07 20:46 ` [PATCH/RFC] " Jakub Narebski
2010-05-07 22:15 ` Ævar Arnfjörð Bjarmason
2010-05-07 23:43 ` Jakub Narebski
2010-05-08 2:30 ` Ping Yin
2010-05-08 8:18 ` Jakub Narebski
2010-05-08 9:03 ` Ping Yin
2010-05-08 5:06 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1273180440-8641-1-git-send-email-avarab@gmail.com \
--to=avarab@gmail.com \
--cc=eli@barzilay.org \
--cc=git@vger.kernel.org \
--cc=hvoigt@hvoigt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).