[PATCH 1/2] Allow passing of configuration parameters in the command line

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The values passed this way will override whatever is defined
in the config files.

Signed-off-by: Alex Riesen <raa.lkml@xxxxxxxxx>
---

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
> <brandon.casey.ctr@xxxxxxxxxxxxxxx> wrote:
> > On 03/25/2010 10:11 AM, Nguyen Thai Ngoc Duy wrote:
> >> 2010/3/25 Junio C Hamano <gitster@xxxxxxxxx>:
> >>> * ar/config-from-command-line (2010-03-19) 1 commit
> >>>  - Allow passing of configuration parameters in the command line
> >> This 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.

> > 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).

> > 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

--
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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]