[PATCH 1/2] Allow passing of configuration parameters in the command line
From: Alex Riesen <hidden>
Date: 2016-06-15 22:48:30
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
The values passed this way will override whatever is defined in the config files. Signed-off-by: Alex Riesen <redacted> --- I replaced strndup with xstrndup, and calloc with xcalloc. A common workaround for broken flexarray support has got a small hint, and that typo got fixed too. A test for CamelCase config key added. This patch replaces the one I sent earlier. Alex Riesen, Fri, Mar 26, 2010 00:11:51 +0100:
On Thu, Mar 25, 2010 at 17:27, Brandon Casey [off-list ref] wrote:quoted
On 03/25/2010 10:11 AM, Nguyen Thai Ngoc Duy wrote:quoted
2010/3/25 Junio C Hamano [off-list ref]:quoted
* ar/config-from-command-line (2010-03-19) 1 commit - Allow passing of configuration parameters in the command lineThis breaks my build on Solaris because it uses strndup, which is not available.A quick glance at ar/config-from.. also detected an unchecked calloc(). Alex, any reason xcalloc wasn't used?Just missed it. Long time away from Git sources.
Done.
quoted
Would the code be simpler if strbufs were used? Then you wouldn't need to duplicate the skip_space and trailing_space functionality provided in the strbuf library, and would just need a new function named strbuf_tolower.But this indeed makes sense. Promise to take a look at it after some sleep.
Done, but... It does make the code more readable, but I don't like strbuf anymore. It has grown ugly. A lot of allocations, reallocations and copying around. It may be efficient, but I found it hard to convince myself that it is. And it should fragment heap a lot (doesn't matter much in this particular case but it may be an issue somewhere. Not all heaps are as robust as glibc's one). This patch is separate, and I didn't strbuf_tolower thing: the only other place in whole project which lowcases a string is in mailmap, and doesn't look like it can profit from conversion to strbuf (just look for tolower in mailmap.c).
quoted
Also, should config_parametes_tail be spelled config_parameters_tail?
Done Documentation/git.txt | 7 +++++ builtin/config.c | 6 +++- cache.h | 2 + config.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ git.c | 9 ++++++ t/t1300-repo-config.sh | 8 +++++ 6 files changed, 102 insertions(+), 1 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 4e00b31..0fc5cfe 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt@@ -12,6 +12,7 @@ SYNOPSIS 'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] + [-c name=value] [--help] COMMAND [ARGS] DESCRIPTION
@@ -220,6 +221,12 @@ displayed. See linkgit:git-help[1] for more information, because `git --help ...` is converted internally into `git help ...`. +-c <name>=<value>:: + Pass a configuration parameter to the command. The value + given will override values from configuration files. + The <name> is expected in the same format as listed by + 'git config' (subkeys separated by dots). + --exec-path:: Path to wherever your core git programs are installed. This can also be controlled by setting the GIT_EXEC_PATH
diff --git a/builtin/config.c b/builtin/config.c
index 4bc46b1..f3d1660 100644
--- a/builtin/config.c
+++ b/builtin/config.c@@ -197,7 +197,11 @@ static int get_value(const char *key_, const char *regex_) git_config_from_file(show_config, system_wide, NULL); if (do_all && global) git_config_from_file(show_config, global, NULL); - git_config_from_file(show_config, local, NULL); + if (do_all) + git_config_from_file(show_config, local, NULL); + git_config_from_parameters(show_config, NULL); + if (!do_all && !seen) + git_config_from_file(show_config, local, NULL); if (!do_all && !seen && global) git_config_from_file(show_config, global, NULL); if (!do_all && !seen && system_wide)
diff --git a/cache.h b/cache.h
index 2928107..f5fa79e 100644
--- a/cache.h
+++ b/cache.h@@ -936,6 +936,8 @@ extern int update_server_info(int); typedef int (*config_fn_t)(const char *, const char *, void *); extern int git_default_config(const char *, const char *, void *); extern int git_config_from_file(config_fn_t fn, const char *, void *); +extern int git_config_parse_parameter(const char *text); +extern int git_config_from_parameters(); extern int git_config(config_fn_t fn, void *); extern int git_parse_ulong(const char *, unsigned long *); extern int git_config_int(const char *, const char *);
diff --git a/config.c b/config.c
index 6963fbe..83ebe0c 100644
--- a/config.c
+++ b/config.c@@ -18,6 +18,62 @@ static int zlib_compression_seen; const char *config_exclusive_filename = NULL; +struct config_item +{ + struct config_item *next; + char *value; + char name[1 /* NUL */]; +}; +static struct config_item *config_parameters; +static struct config_item **config_parameters_tail = &config_parameters; + +static void lowercase(char *p) +{ + for (; *p; ++p) + *p = tolower(*p); +} +static char *skip_space(const char *p) +{ + for (; *p; ++p) + if (!isspace(*p)) + break; + return (char *)p; +} +static char *trailing_space(const char *begin, const char *p) +{ + while (p-- > begin) + if (!isspace(*p)) + break; + return (char *)p + 1; +} + +int git_config_parse_parameter(const char *text) +{ + struct config_item *ct; + const char *name; + const char *val; + name = skip_space(text); + text = val = strchr(name, '='); + if (!text) + text = name + strlen(name); + text = trailing_space(name, text); + if (text <= name) + return -1; + ct = xcalloc(1, sizeof(struct config_item) + (text - name)); + memcpy(ct->name, name, text - name); + lowercase(ct->name); + if (!val) + ct->value = NULL; + else { + val = skip_space(++val /* skip "=" */); + text = trailing_space(val, val + strlen(val)); + ct->value = xstrndup(val, text - val); + } + *config_parameters_tail = ct; + config_parameters_tail = &ct->next; + return 0; +} + static int get_next_char(void) { int c;
@@ -699,6 +755,15 @@ int git_config_global(void) return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0); } +int git_config_from_parameters(config_fn_t fn, void *data) +{ + const struct config_item *ct; + for (ct = config_parameters; ct; ct = ct->next) + if (fn(ct->name, ct->value, data) < 0) + return -1; + return 0; +} + int git_config(config_fn_t fn, void *data) { int ret = 0, found = 0;
@@ -730,6 +795,12 @@ int git_config(config_fn_t fn, void *data) found += 1; } free(repo_config); + + if (config_parameters) { + ret += git_config_from_parameters(fn, data); + found += 1; + } + if (found == 0) return -1; return ret;
diff --git a/git.c b/git.c
index 6bae305..99f0363 100644
--- a/git.c
+++ b/git.c@@ -8,6 +8,7 @@ const char git_usage_string[] = "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]\n" " [-p|--paginate|--no-pager] [--no-replace-objects]\n" " [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]\n" + " [-c name=value\n" " [--help] COMMAND [ARGS]"; const char git_more_info_string[] =
@@ -130,6 +131,14 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0); if (envchanged) *envchanged = 1; + } else if (!strcmp(cmd, "-c")) { + if (*argc < 2) { + fprintf(stderr, "-c expects a configuration string\n" ); + usage(git_usage_string); + } + git_config_parse_parameter((*argv)[1]); + (*argv)++; + (*argc)--; } else { fprintf(stderr, "Unknown option: %s\n", cmd); usage(git_usage_string);
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index f11f98c..64f0508 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh@@ -824,4 +824,12 @@ test_expect_success 'check split_cmdline return' " test_must_fail git merge master " +test_expect_success 'git -c "key=value" support' ' + test "z$(git -c name=value config name)" = zvalue && + test "z$(git -c core.name=value config core.name)" = zvalue && + test "z$(git -c CamelCase=value config camelcase)" = zvalue && + test "z$(git -c flag config --bool flag)" = ztrue && + test_must_fail git -c core.name=value config name +' + test_done
--
1.7.0.3.309.g532f0