All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Allow passing of configuration parameters in the command line
@ 2010-03-19 14:42 Alex Riesen
  2010-03-19 19:36 ` Junio C Hamano
  2010-03-20 16:00 ` Junio C Hamano
  0 siblings, 2 replies; 8+ messages in thread
From: Alex Riesen @ 2010-03-19 14:42 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano, Linus Torvalds, Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 6757 bytes --]

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

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

Someone wanted to have this once. I accidentally remembered
that when I wanted to temporarily set some config parameter
(format.suffix?). From looking at code it seemed simple enough,
so I did it.

I have to say that the feature is not very friendly: there are
some values in .git/config which may not like to be changed
(like core.fileMode, ...ignoreCase or ...repositoryFormatVersion).

 Documentation/git.txt  |    7 +++++
 builtin/config.c       |    6 +++-
 cache.h                |    2 +
 config.c               |   71 ++++++++++++++++++++++++++++++++++++++++++++++++
 git.c                  |    9 ++++++
 t/t1300-repo-config.sh |    7 +++++
 6 files changed, 101 insertions(+), 1 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 35c0c79..755fa4d 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
@@ -219,6 +220,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 89f6a40..4a0c75d 100644
--- a/cache.h
+++ b/cache.h
@@ -932,6 +932,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..2376ae9 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];
+};
+static struct config_item *config_parameters;
+static struct config_item **config_parametes_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 = calloc(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 = strndup(val, text - val);
+	}
+	*config_parametes_tail = ct;
+	config_parametes_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..d7c5501 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -824,4 +824,11 @@ 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 flag config --bool flag)" = ztrue &&
+	test_must_fail git -c core.name=value config name
+'
+
 test_done
-- 
1.7.0.2.318.g49250

[-- Attachment #2: 0001-Allow-passing-of-configuration-parameters-in-the-comm.diff --]
[-- Type: application/octet-stream, Size: 6603 bytes --]

From 99febf0858fde149009cff7d031f229eff8a92e1 Mon Sep 17 00:00:00 2001
From: Alex Riesen <raa.lkml@gmail.com>
Date: Fri, 19 Mar 2010 15:19:24 +0100
Subject: [PATCH] Allow passing of configuration parameters in the command line

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

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
 Documentation/git.txt  |    7 +++++
 builtin/config.c       |    6 +++-
 cache.h                |    2 +
 config.c               |   71 ++++++++++++++++++++++++++++++++++++++++++++++++
 git.c                  |    9 ++++++
 t/t1300-repo-config.sh |    7 +++++
 6 files changed, 101 insertions(+), 1 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 35c0c79..755fa4d 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
@@ -219,6 +220,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 89f6a40..4a0c75d 100644
--- a/cache.h
+++ b/cache.h
@@ -932,6 +932,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..2376ae9 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];
+};
+static struct config_item *config_parameters;
+static struct config_item **config_parametes_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 = calloc(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 = strndup(val, text - val);
+	}
+	*config_parametes_tail = ct;
+	config_parametes_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..d7c5501 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -824,4 +824,11 @@ 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 flag config --bool flag)" = ztrue &&
+	test_must_fail git -c core.name=value config name
+'
+
 test_done
-- 
1.7.0.2.318.g49250


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command line
  2010-03-19 14:42 [PATCH] Allow passing of configuration parameters in the command line Alex Riesen
@ 2010-03-19 19:36 ` Junio C Hamano
  2010-03-20  9:09   ` Nguyen Thai Ngoc Duy
  2010-03-20 16:00 ` Junio C Hamano
  1 sibling, 1 reply; 8+ messages in thread
From: Junio C Hamano @ 2010-03-19 19:36 UTC (permalink / raw)
  To: Alex Riesen
  Cc: Git Mailing List, Linus Torvalds, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy

Alex Riesen <raa.lkml@gmail.com> writes:

> The values passed this way will override whatever is defined
> in the config files.
>
> Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
> ---
>
> Someone wanted to have this once. I accidentally remembered
> that when I wanted to temporarily set some config parameter
> (format.suffix?). From looking at code it seemed simple enough,
> so I did it.

How does this interact with core.worktree and the setup sequence in
general?

By "setup sequence", I mean something I tried to extract from Nguyen here:

 http://thread.gmane.org/gmane.comp.version-control.git/141962/focus=142001
 
During the process of finding the repository (.git/ or project.git/), we
would open its config to check the repository format version, that that
would be the earliest point we might decide where the work tree is (or if
we have work tree at all).  Where should this new mechanism hook into the
sequence to give users an expected behaviour (what's expected in the first
place)?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command  line
  2010-03-19 19:36 ` Junio C Hamano
@ 2010-03-20  9:09   ` Nguyen Thai Ngoc Duy
  2010-03-20  9:17     ` Alex Riesen
  0 siblings, 1 reply; 8+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2010-03-20  9:09 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Alex Riesen, Git Mailing List, Linus Torvalds, Johannes Schindelin

On 3/20/10, Junio C Hamano <gitster@pobox.com> wrote:
> Alex Riesen <raa.lkml@gmail.com> writes:
>
>  > The values passed this way will override whatever is defined
>  > in the config files.
>  >
>  > Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
>  > ---
>  >
>  > Someone wanted to have this once. I accidentally remembered
>  > that when I wanted to temporarily set some config parameter
>  > (format.suffix?). From looking at code it seemed simple enough,
>  > so I did it.
>
>
> How does this interact with core.worktree and the setup sequence in
>  general?

To me it looks like another config file to the config stack. No thing
can go worse (except that if you have core.worktree in
$GIT_DIR/config, now also specify -c core.worktree=foo, then
core.worktree code would be called twice).

However, specifying "-c foo=relativepath" may surprise users. Current
working directory may have been moved when that config is used.
-- 
Duy

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command  line
  2010-03-20  9:09   ` Nguyen Thai Ngoc Duy
@ 2010-03-20  9:17     ` Alex Riesen
  0 siblings, 0 replies; 8+ messages in thread
From: Alex Riesen @ 2010-03-20  9:17 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy
  Cc: Junio C Hamano, Git Mailing List, Linus Torvalds, Johannes Schindelin

On Sat, Mar 20, 2010 at 10:09, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> On 3/20/10, Junio C Hamano <gitster@pobox.com> wrote:
>> Alex Riesen <raa.lkml@gmail.com> writes:
>>
>>  > The values passed this way will override whatever is defined
>>  > in the config files.
>>  >
>>  > Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
>>  > ---
>>  >
>>  > Someone wanted to have this once. I accidentally remembered
>>  > that when I wanted to temporarily set some config parameter
>>  > (format.suffix?). From looking at code it seemed simple enough,
>>  > so I did it.
>>
>> How does this interact with core.worktree and the setup sequence in
>>  general?
>
> To me it looks like another config file to the config stack. No thing
> can go worse (except that if you have core.worktree in
> $GIT_DIR/config, now also specify -c core.worktree=foo, then
> core.worktree code would be called twice).

Yes, that's why I said the whole thing is not very friendly.
To an experienced user it will be expected, though.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command line
  2010-03-19 14:42 [PATCH] Allow passing of configuration parameters in the command line Alex Riesen
  2010-03-19 19:36 ` Junio C Hamano
@ 2010-03-20 16:00 ` Junio C Hamano
  2010-03-20 16:03   ` Alex Riesen
  2010-03-20 16:05   ` [PATCH, resend] " Alex Riesen
  1 sibling, 2 replies; 8+ messages in thread
From: Junio C Hamano @ 2010-03-20 16:00 UTC (permalink / raw)
  To: Alex Riesen
  Cc: Git Mailing List, Junio C Hamano, Linus Torvalds, Johannes Schindelin

Alex Riesen <raa.lkml@gmail.com> writes:

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

You sent MIME multipart-mixed and I am getting a broken patch.

How could this be... If I cannot expect to reliably get a non-linewrapped
patch, there doesn't seem to be much point in you and I taking extra time
to bother with MIME.

Very unhappy (not with you, Alex, but with MIME and whatever tool that
wrapped your lines).

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command  line
  2010-03-20 16:00 ` Junio C Hamano
@ 2010-03-20 16:03   ` Alex Riesen
  2010-03-20 16:20     ` Junio C Hamano
  2010-03-20 16:05   ` [PATCH, resend] " Alex Riesen
  1 sibling, 1 reply; 8+ messages in thread
From: Alex Riesen @ 2010-03-20 16:03 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Git Mailing List, Junio C Hamano, Linus Torvalds, Johannes Schindelin

On Sat, Mar 20, 2010 at 17:00, Junio C Hamano <gitster@pobox.com> wrote:
> Alex Riesen <raa.lkml@gmail.com> writes:
>
>> The values passed this way will override whatever is defined
>> in the config files.
>
> You sent MIME multipart-mixed and I am getting a broken patch.
>
> How could this be... If I cannot expect to reliably get a non-linewrapped
> patch, there doesn't seem to be much point in you and I taking extra time
> to bother with MIME.

That's gmail, again. There must be an attachment with a normal patch,
but I'll resend.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH, resend] Allow passing of configuration parameters in the command line
  2010-03-20 16:00 ` Junio C Hamano
  2010-03-20 16:03   ` Alex Riesen
@ 2010-03-20 16:05   ` Alex Riesen
  1 sibling, 0 replies; 8+ messages in thread
From: Alex Riesen @ 2010-03-20 16:05 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Linus Torvalds, Johannes Schindelin

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

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
 Documentation/git.txt  |    7 +++++
 builtin/config.c       |    6 +++-
 cache.h                |    2 +
 config.c               |   71 ++++++++++++++++++++++++++++++++++++++++++++++++
 git.c                  |    9 ++++++
 t/t1300-repo-config.sh |    7 +++++
 6 files changed, 101 insertions(+), 1 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 35c0c79..755fa4d 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
@@ -219,6 +220,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 89f6a40..4a0c75d 100644
--- a/cache.h
+++ b/cache.h
@@ -932,6 +932,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..2376ae9 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];
+};
+static struct config_item *config_parameters;
+static struct config_item **config_parametes_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 = calloc(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 = strndup(val, text - val);
+	}
+	*config_parametes_tail = ct;
+	config_parametes_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..d7c5501 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -824,4 +824,11 @@ 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 flag config --bool flag)" = ztrue &&
+	test_must_fail git -c core.name=value config name
+'
+
 test_done
-- 
1.7.0.2.318.g49250

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Allow passing of configuration parameters in the command line
  2010-03-20 16:03   ` Alex Riesen
@ 2010-03-20 16:20     ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2010-03-20 16:20 UTC (permalink / raw)
  To: Alex Riesen
  Cc: Junio C Hamano, Git Mailing List, Junio C Hamano, Linus Torvalds,
	Johannes Schindelin

Alex Riesen <raa.lkml@gmail.com> writes:

> On Sat, Mar 20, 2010 at 17:00, Junio C Hamano <gitster@pobox.com> wrote:
>> Alex Riesen <raa.lkml@gmail.com> writes:
>>
>>> The values passed this way will override whatever is defined
>>> in the config files.
>>
>> You sent MIME multipart-mixed and I am getting a broken patch.
>>
>> How could this be... If I cannot expect to reliably get a non-linewrapped
>> patch, there doesn't seem to be much point in you and I taking extra time
>> to bother with MIME.
>
> That's gmail, again. There must be an attachment with a normal patch,
> but I'll resend.

I think it was coming from duplicates.  The attachment was fine, but the
normal part was wrapped.

Applied with a manual fix.  But thanks anyway.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-03-20 16:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-19 14:42 [PATCH] Allow passing of configuration parameters in the command line Alex Riesen
2010-03-19 19:36 ` Junio C Hamano
2010-03-20  9:09   ` Nguyen Thai Ngoc Duy
2010-03-20  9:17     ` Alex Riesen
2010-03-20 16:00 ` Junio C Hamano
2010-03-20 16:03   ` Alex Riesen
2010-03-20 16:20     ` Junio C Hamano
2010-03-20 16:05   ` [PATCH, resend] " Alex Riesen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.