completion: add and use --list-cmds=alias
By providing aliases via --list-cmds=, we could simplify command collection code in the script. We only issue one git command. Before this patch that is "git config", after it's "git --list-cmds=". In "git help" completion case we actually reduce one "git" process (for getting guides) but that call was added in this series so it does not really count. A couple of bash functions are removed because they are not needed anymore. __git_compute_all_commands() and $__git_all_commands stay because they are still needed for completing pager.* config and without "alias" group, the result is still cacheable. There is a slight (good) change in _git_help() with this patch: before "git help <tab>" shows external commands (as in _not_ part of git) as well as part of $__git_all_commands. We have finer control over command listing now and can exclude that because we can't provide a man page for external commands anyway. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
e11dca10cf
commit
3301d36b29
@ -170,7 +170,7 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
|
|||||||
parse-options), main (all commands in libexec directory),
|
parse-options), main (all commands in libexec directory),
|
||||||
others (all other commands in `$PATH` that have git- prefix),
|
others (all other commands in `$PATH` that have git- prefix),
|
||||||
list-<category> (see categories in command-list.txt),
|
list-<category> (see categories in command-list.txt),
|
||||||
nohelpers (exclude helper commands).
|
nohelpers (exclude helper commands) and alias.
|
||||||
|
|
||||||
GIT COMMANDS
|
GIT COMMANDS
|
||||||
------------
|
------------
|
||||||
|
21
alias.c
21
alias.c
@ -1,10 +1,12 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "alias.h"
|
#include "alias.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "string-list.h"
|
||||||
|
|
||||||
struct config_alias_data {
|
struct config_alias_data {
|
||||||
const char *alias;
|
const char *alias;
|
||||||
char *v;
|
char *v;
|
||||||
|
struct string_list *list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int config_alias_cb(const char *key, const char *value, void *d)
|
static int config_alias_cb(const char *key, const char *value, void *d)
|
||||||
@ -12,8 +14,16 @@ static int config_alias_cb(const char *key, const char *value, void *d)
|
|||||||
struct config_alias_data *data = d;
|
struct config_alias_data *data = d;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
if (skip_prefix(key, "alias.", &p) && !strcasecmp(p, data->alias))
|
if (!skip_prefix(key, "alias.", &p))
|
||||||
return git_config_string((const char **)&data->v, key, value);
|
return 0;
|
||||||
|
|
||||||
|
if (data->alias) {
|
||||||
|
if (!strcasecmp(p, data->alias))
|
||||||
|
return git_config_string((const char **)&data->v,
|
||||||
|
key, value);
|
||||||
|
} else if (data->list) {
|
||||||
|
string_list_append(data->list, p);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -27,6 +37,13 @@ char *alias_lookup(const char *alias)
|
|||||||
return data.v;
|
return data.v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void list_aliases(struct string_list *list)
|
||||||
|
{
|
||||||
|
struct config_alias_data data = { NULL, NULL, list };
|
||||||
|
|
||||||
|
read_early_config(config_alias_cb, &data);
|
||||||
|
}
|
||||||
|
|
||||||
#define SPLIT_CMDLINE_BAD_ENDING 1
|
#define SPLIT_CMDLINE_BAD_ENDING 1
|
||||||
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
|
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
|
||||||
static const char *split_cmdline_errors[] = {
|
static const char *split_cmdline_errors[] = {
|
||||||
|
3
alias.h
3
alias.h
@ -1,9 +1,12 @@
|
|||||||
#ifndef __ALIAS_H__
|
#ifndef __ALIAS_H__
|
||||||
#define __ALIAS_H__
|
#define __ALIAS_H__
|
||||||
|
|
||||||
|
struct string_list;
|
||||||
|
|
||||||
char *alias_lookup(const char *alias);
|
char *alias_lookup(const char *alias);
|
||||||
int split_cmdline(char *cmdline, const char ***argv);
|
int split_cmdline(char *cmdline, const char ***argv);
|
||||||
/* Takes a negative value returned by split_cmdline */
|
/* Takes a negative value returned by split_cmdline */
|
||||||
const char *split_cmdline_strerror(int cmdline_errno);
|
const char *split_cmdline_strerror(int cmdline_errno);
|
||||||
|
void list_aliases(struct string_list *list);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -834,51 +834,11 @@ __git_complete_strategy ()
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# __git_commands requires 1 argument:
|
|
||||||
# 1: the command group, either "all" or "porcelain"
|
|
||||||
__git_commands () {
|
|
||||||
case "$1" in
|
|
||||||
porcelain)
|
|
||||||
if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
|
|
||||||
then
|
|
||||||
printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
|
|
||||||
else
|
|
||||||
git --list-cmds=list-mainporcelain,others,nohelpers,list-complete
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
all)
|
|
||||||
if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
|
|
||||||
then
|
|
||||||
printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST"
|
|
||||||
else
|
|
||||||
git --list-cmds=main,others,nohelpers
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
__git_list_all_commands ()
|
|
||||||
{
|
|
||||||
__git_commands all
|
|
||||||
}
|
|
||||||
|
|
||||||
__git_all_commands=
|
__git_all_commands=
|
||||||
__git_compute_all_commands ()
|
__git_compute_all_commands ()
|
||||||
{
|
{
|
||||||
test -n "$__git_all_commands" ||
|
test -n "$__git_all_commands" ||
|
||||||
__git_all_commands=$(__git_list_all_commands)
|
__git_all_commands=$(git --list-cmds=main,others,alias,nohelpers)
|
||||||
}
|
|
||||||
|
|
||||||
__git_list_porcelain_commands ()
|
|
||||||
{
|
|
||||||
__git_commands porcelain
|
|
||||||
}
|
|
||||||
|
|
||||||
__git_porcelain_commands=
|
|
||||||
__git_compute_porcelain_commands ()
|
|
||||||
{
|
|
||||||
test -n "$__git_porcelain_commands" ||
|
|
||||||
__git_porcelain_commands=$(__git_list_porcelain_commands)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Lists all set config variables starting with the given section prefix,
|
# Lists all set config variables starting with the given section prefix,
|
||||||
@ -896,11 +856,6 @@ __git_pretty_aliases ()
|
|||||||
__git_get_config_variables "pretty"
|
__git_get_config_variables "pretty"
|
||||||
}
|
}
|
||||||
|
|
||||||
__git_aliases ()
|
|
||||||
{
|
|
||||||
__git_get_config_variables "alias"
|
|
||||||
}
|
|
||||||
|
|
||||||
# __git_aliased_command requires 1 argument
|
# __git_aliased_command requires 1 argument
|
||||||
__git_aliased_command ()
|
__git_aliased_command ()
|
||||||
{
|
{
|
||||||
@ -1500,13 +1455,6 @@ _git_grep ()
|
|||||||
__git_complete_refs
|
__git_complete_refs
|
||||||
}
|
}
|
||||||
|
|
||||||
__git_all_guides=
|
|
||||||
__git_compute_all_guides ()
|
|
||||||
{
|
|
||||||
test -n "$__git_all_guides" ||
|
|
||||||
__git_all_guides=$(git --list-cmds=list-guide)
|
|
||||||
}
|
|
||||||
|
|
||||||
_git_help ()
|
_git_help ()
|
||||||
{
|
{
|
||||||
case "$cur" in
|
case "$cur" in
|
||||||
@ -1515,11 +1463,12 @@ _git_help ()
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
__git_compute_all_commands
|
if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
|
||||||
__git_compute_all_guides
|
then
|
||||||
__gitcomp "$__git_all_commands $(__git_aliases) $__git_all_guides
|
__gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk"
|
||||||
gitk
|
else
|
||||||
"
|
__gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_git_init ()
|
_git_init ()
|
||||||
@ -3058,8 +3007,14 @@ __git_main ()
|
|||||||
--help
|
--help
|
||||||
"
|
"
|
||||||
;;
|
;;
|
||||||
*) __git_compute_porcelain_commands
|
*)
|
||||||
__gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
|
if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
|
||||||
|
then
|
||||||
|
__gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
|
||||||
|
else
|
||||||
|
__gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete)"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
2
git.c
2
git.c
@ -75,6 +75,8 @@ static int list_cmds(const char *spec)
|
|||||||
list_all_other_cmds(&list);
|
list_all_other_cmds(&list);
|
||||||
else if (match_token(spec, len, "nohelpers"))
|
else if (match_token(spec, len, "nohelpers"))
|
||||||
exclude_helpers_from_list(&list);
|
exclude_helpers_from_list(&list);
|
||||||
|
else if (match_token(spec, len, "alias"))
|
||||||
|
list_aliases(&list);
|
||||||
else if (len > 5 && !strncmp(spec, "list-", 5)) {
|
else if (len > 5 && !strncmp(spec, "list-", 5)) {
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
|
|
||||||
|
@ -1192,17 +1192,6 @@ test_expect_success '__git_pretty_aliases' '
|
|||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '__git_aliases' '
|
|
||||||
cat >expect <<-EOF &&
|
|
||||||
ci
|
|
||||||
co
|
|
||||||
EOF
|
|
||||||
test_config alias.ci commit &&
|
|
||||||
test_config alias.co checkout &&
|
|
||||||
__git_aliases >actual &&
|
|
||||||
test_cmp expect actual
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success 'basic' '
|
test_expect_success 'basic' '
|
||||||
run_completion "git " &&
|
run_completion "git " &&
|
||||||
# built-in
|
# built-in
|
||||||
@ -1511,13 +1500,6 @@ test_expect_success 'sourcing the completion script clears cached commands' '
|
|||||||
verbose test -z "$__git_all_commands"
|
verbose test -z "$__git_all_commands"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'sourcing the completion script clears cached porcelain commands' '
|
|
||||||
__git_compute_porcelain_commands &&
|
|
||||||
verbose test -n "$__git_porcelain_commands" &&
|
|
||||||
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
|
||||||
verbose test -z "$__git_porcelain_commands"
|
|
||||||
'
|
|
||||||
|
|
||||||
test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
|
test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
|
||||||
__git_compute_merge_strategies &&
|
__git_compute_merge_strategies &&
|
||||||
verbose test -n "$__git_merge_strategies" &&
|
verbose test -n "$__git_merge_strategies" &&
|
||||||
|
Reference in New Issue
Block a user