When an alias expands to a shell command, and when we are inside a regular worktree's subdirectory (i.e. not inside the .git/ directory nor in a worktree initialized via `git worktree add`), and only then, the current working directory is switched to the top-level directory of the worktree before running the expanded alias. While this behavior is somewhat confusing, it is well-established and needs to be preserved, even with the upcoming change to use the early config machinery to expand aliases. That means that alias_lookup() needs to determine the working directory to switch to, in case the alias turns out to expand to a shall command. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- alias.c | 33 +++++++++++++++++++++++++-------- builtin/help.c | 2 +- cache.h | 2 +- git.c | 2 +- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/alias.c b/alias.c index 3b90397a99d..b7c4a4f0217 100644 --- a/alias.c +++ b/alias.c @@ -1,14 +1,31 @@ #include "cache.h" -char *alias_lookup(const char *alias) +struct config_alias_data { - char *v = NULL; - struct strbuf key = STRBUF_INIT; - strbuf_addf(&key, "alias.%s", alias); - if (git_config_key_is_valid(key.buf)) - git_config_get_string(key.buf, &v); - strbuf_release(&key); - return v; + struct strbuf key; + char *v; +}; + +static int config_alias_cb(const char *key, const char *value, void *d) +{ + struct config_alias_data *data = d; + + if (!strcmp(key, data->key.buf)) + return git_config_string((const char **)&data->v, key, value); + + return 0; +} + +char *alias_lookup(const char *alias, struct strbuf *cdup_dir) +{ + struct config_alias_data data = { STRBUF_INIT, NULL }; + + strbuf_addf(&data.key, "alias.%s", alias); + if (git_config_key_is_valid(data.key.buf)) + read_early_config(config_alias_cb, &data, cdup_dir); + strbuf_release(&data.key); + + return data.v; } #define SPLIT_CMDLINE_BAD_ENDING 1 diff --git a/builtin/help.c b/builtin/help.c index 49f7a07f85d..6f208ff1ab3 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -435,7 +435,7 @@ static const char *check_git_cmd(const char* cmd) if (is_git_command(cmd)) return cmd; - alias = alias_lookup(cmd); + alias = alias_lookup(cmd, NULL); if (alias) { printf_ln(_("`git %s' is aliased to `%s'"), cmd, alias); free(alias); diff --git a/cache.h b/cache.h index f769ef1779c..65f2e5bf04c 100644 --- a/cache.h +++ b/cache.h @@ -2189,7 +2189,7 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule); /* ls-files */ void overlay_tree_on_cache(const char *tree_name, const char *prefix); -char *alias_lookup(const char *alias); +char *alias_lookup(const char *alias, struct strbuf *cdup_dir); int split_cmdline(char *cmdline, const char ***argv); /* Takes a negative value returned by split_cmdline */ const char *split_cmdline_strerror(int cmdline_errno); diff --git a/git.c b/git.c index 8ff44f081d4..4163beaead4 100644 --- a/git.c +++ b/git.c @@ -256,7 +256,7 @@ static int handle_alias(int *argcp, const char ***argv) setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; - alias_string = alias_lookup(alias_command); + alias_string = alias_lookup(alias_command, NULL); if (alias_string) { if (alias_string[0] == '!') { struct child_process child = CHILD_PROCESS_INIT; -- 2.13.0.windows.1.460.g13f583bedb5