Skip to content

Commit

Permalink
Allow passing of configuration parameters in the command line
Browse files Browse the repository at this point in the history
The values passed this way will override whatever is defined
in the config files.

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Alex Riesen authored and Junio C Hamano committed Mar 28, 2010
1 parent f1ba1c9 commit 8b1fa77
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion builtin/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down
71 changes: 71 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions t/t1300-repo-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 8b1fa77

Please sign in to comment.