Merge branch 'js/alias-early-config' into maint
The code to pick up and execute command alias definition from the configuration used to switch to the top of the working tree and then come back when the expanded alias was executed, which was unnecessarilyl complex. Attempt to simplify the logic by using the early-config mechanism that does not chdir around. * js/alias-early-config: alias: use the early config machinery to expand aliases t7006: demonstrate a problem with aliases in subdirectories t1308: relax the test verifying that empty alias values are disallowed help: use early config when autocorrecting aliases config: report correct line number upon error discover_git_directory(): avoid setting invalid git_dir
This commit is contained in:
commit
040746c061
28
alias.c
28
alias.c
@ -1,14 +1,28 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
|
struct config_alias_data {
|
||||||
|
const char *alias;
|
||||||
|
char *v;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int config_alias_cb(const char *key, const char *value, void *d)
|
||||||
|
{
|
||||||
|
struct config_alias_data *data = d;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
if (skip_prefix(key, "alias.", &p) && !strcmp(p, data->alias))
|
||||||
|
return git_config_string((const char **)&data->v, key, value);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char *alias_lookup(const char *alias)
|
char *alias_lookup(const char *alias)
|
||||||
{
|
{
|
||||||
char *v = NULL;
|
struct config_alias_data data = { alias, NULL };
|
||||||
struct strbuf key = STRBUF_INIT;
|
|
||||||
strbuf_addf(&key, "alias.%s", alias);
|
read_early_config(config_alias_cb, &data);
|
||||||
if (git_config_key_is_valid(key.buf))
|
|
||||||
git_config_get_string(key.buf, &v);
|
return data.v;
|
||||||
strbuf_release(&key);
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPLIT_CMDLINE_BAD_ENDING 1
|
#define SPLIT_CMDLINE_BAD_ENDING 1
|
||||||
|
1
config.c
1
config.c
@ -588,6 +588,7 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
|
|||||||
*/
|
*/
|
||||||
cf->linenr--;
|
cf->linenr--;
|
||||||
ret = fn(name->buf, value, data);
|
ret = fn(name->buf, value, data);
|
||||||
|
if (ret >= 0)
|
||||||
cf->linenr++;
|
cf->linenr++;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
55
git.c
55
git.c
@ -16,50 +16,6 @@ const char git_more_info_string[] =
|
|||||||
"to read about a specific subcommand or concept.");
|
"to read about a specific subcommand or concept.");
|
||||||
|
|
||||||
static int use_pager = -1;
|
static int use_pager = -1;
|
||||||
static char *orig_cwd;
|
|
||||||
static const char *env_names[] = {
|
|
||||||
GIT_DIR_ENVIRONMENT,
|
|
||||||
GIT_WORK_TREE_ENVIRONMENT,
|
|
||||||
GIT_IMPLICIT_WORK_TREE_ENVIRONMENT,
|
|
||||||
GIT_PREFIX_ENVIRONMENT
|
|
||||||
};
|
|
||||||
static char *orig_env[4];
|
|
||||||
static int save_restore_env_balance;
|
|
||||||
|
|
||||||
static void save_env_before_alias(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(save_restore_env_balance == 0);
|
|
||||||
save_restore_env_balance = 1;
|
|
||||||
orig_cwd = xgetcwd();
|
|
||||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
|
||||||
orig_env[i] = getenv(env_names[i]);
|
|
||||||
orig_env[i] = xstrdup_or_null(orig_env[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void restore_env(int external_alias)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(save_restore_env_balance == 1);
|
|
||||||
save_restore_env_balance = 0;
|
|
||||||
if (!external_alias && orig_cwd && chdir(orig_cwd))
|
|
||||||
die_errno("could not move to %s", orig_cwd);
|
|
||||||
free(orig_cwd);
|
|
||||||
for (i = 0; i < ARRAY_SIZE(env_names); i++) {
|
|
||||||
if (external_alias &&
|
|
||||||
!strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT))
|
|
||||||
continue;
|
|
||||||
if (orig_env[i]) {
|
|
||||||
setenv(env_names[i], orig_env[i], 1);
|
|
||||||
free(orig_env[i]);
|
|
||||||
} else {
|
|
||||||
unsetenv(env_names[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void commit_pager_choice(void) {
|
static void commit_pager_choice(void) {
|
||||||
switch (use_pager) {
|
switch (use_pager) {
|
||||||
@ -250,19 +206,18 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||||||
const char **new_argv;
|
const char **new_argv;
|
||||||
const char *alias_command;
|
const char *alias_command;
|
||||||
char *alias_string;
|
char *alias_string;
|
||||||
int unused_nongit;
|
|
||||||
|
|
||||||
save_env_before_alias();
|
|
||||||
setup_git_directory_gently(&unused_nongit);
|
|
||||||
|
|
||||||
alias_command = (*argv)[0];
|
alias_command = (*argv)[0];
|
||||||
alias_string = alias_lookup(alias_command);
|
alias_string = alias_lookup(alias_command);
|
||||||
if (alias_string) {
|
if (alias_string) {
|
||||||
if (alias_string[0] == '!') {
|
if (alias_string[0] == '!') {
|
||||||
struct child_process child = CHILD_PROCESS_INIT;
|
struct child_process child = CHILD_PROCESS_INIT;
|
||||||
|
int nongit_ok;
|
||||||
|
|
||||||
|
/* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */
|
||||||
|
setup_git_directory_gently(&nongit_ok);
|
||||||
|
|
||||||
commit_pager_choice();
|
commit_pager_choice();
|
||||||
restore_env(1);
|
|
||||||
|
|
||||||
child.use_shell = 1;
|
child.use_shell = 1;
|
||||||
argv_array_push(&child.args, alias_string + 1);
|
argv_array_push(&child.args, alias_string + 1);
|
||||||
@ -308,8 +263,6 @@ static int handle_alias(int *argcp, const char ***argv)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_env(0);
|
|
||||||
|
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
2
help.c
2
help.c
@ -289,7 +289,7 @@ const char *help_unknown_cmd(const char *cmd)
|
|||||||
memset(&other_cmds, 0, sizeof(other_cmds));
|
memset(&other_cmds, 0, sizeof(other_cmds));
|
||||||
memset(&aliases, 0, sizeof(aliases));
|
memset(&aliases, 0, sizeof(aliases));
|
||||||
|
|
||||||
git_config(git_unknown_cmd_config, NULL);
|
read_early_config(git_unknown_cmd_config, NULL);
|
||||||
|
|
||||||
load_command_list("git-", &main_cmds, &other_cmds);
|
load_command_list("git-", &main_cmds, &other_cmds);
|
||||||
|
|
||||||
|
1
setup.c
1
setup.c
@ -982,6 +982,7 @@ const char *discover_git_directory(struct strbuf *gitdir)
|
|||||||
warning("ignoring git dir '%s': %s",
|
warning("ignoring git dir '%s': %s",
|
||||||
gitdir->buf + gitdir_offset, err.buf);
|
gitdir->buf + gitdir_offset, err.buf);
|
||||||
strbuf_release(&err);
|
strbuf_release(&err);
|
||||||
|
strbuf_setlen(gitdir, gitdir_offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,6 +703,12 @@ test_expect_success 'invalid unit' '
|
|||||||
test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
|
test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'line number is reported correctly' '
|
||||||
|
printf "[bool]\n\tvar\n" >invalid &&
|
||||||
|
test_must_fail git config -f invalid --path bool.var 2>actual &&
|
||||||
|
test_i18ngrep "line 2" actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'invalid stdin config' '
|
test_expect_success 'invalid stdin config' '
|
||||||
echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
|
echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
|
||||||
test_i18ngrep "bad config line 1 in standard input" output
|
test_i18ngrep "bad config line 1 in standard input" output
|
||||||
|
@ -215,7 +215,9 @@ test_expect_success 'check line errors for malformed values' '
|
|||||||
br
|
br
|
||||||
EOF
|
EOF
|
||||||
test_expect_code 128 git br 2>result &&
|
test_expect_code 128 git br 2>result &&
|
||||||
test_i18ngrep "fatal: .*alias\.br.*\.git/config.*line 2" result
|
test_i18ngrep "missing value for .alias\.br" result &&
|
||||||
|
test_i18ngrep "fatal: .*\.git/config" result &&
|
||||||
|
test_i18ngrep "fatal: .*line 2" result
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'error on modifying repo config without repo' '
|
test_expect_success 'error on modifying repo config without repo' '
|
||||||
|
@ -391,6 +391,17 @@ test_expect_success TTY 'core.pager in repo config works and retains cwd' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success TTY 'core.pager is found via alias in subdirectory' '
|
||||||
|
sane_unset GIT_PAGER &&
|
||||||
|
test_config core.pager "cat >via-alias" &&
|
||||||
|
(
|
||||||
|
cd sub &&
|
||||||
|
rm -f via-alias &&
|
||||||
|
test_terminal git -c alias.r="-p rev-parse" r HEAD &&
|
||||||
|
test_path_is_file via-alias
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_doesnt_paginate expect_failure test_must_fail 'git -p nonsense'
|
test_doesnt_paginate expect_failure test_must_fail 'git -p nonsense'
|
||||||
|
|
||||||
test_pager_choices 'git shortlog'
|
test_pager_choices 'git shortlog'
|
||||||
|
Loading…
Reference in New Issue
Block a user