Skip to content

Commit

Permalink
completion: add and use --list-cmds=alias
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
pclouds authored and gitster committed May 21, 2018
1 parent e11dca1 commit 3301d36
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Documentation/git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
parse-options), main (all commands in libexec directory),
others (all other commands in `$PATH` that have git- prefix),
list-<category> (see categories in command-list.txt),
nohelpers (exclude helper commands).
nohelpers (exclude helper commands) and alias.

GIT COMMANDS
------------
Expand Down
21 changes: 19 additions & 2 deletions alias.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
#include "cache.h"
#include "alias.h"
#include "config.h"
#include "string-list.h"

struct config_alias_data {
const char *alias;
char *v;
struct string_list *list;
};

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) && !strcasecmp(p, data->alias))
return git_config_string((const char **)&data->v, key, value);
if (!skip_prefix(key, "alias.", &p))
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;
}
Expand All @@ -27,6 +37,13 @@ char *alias_lookup(const char *alias)
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_UNCLOSED_QUOTE 2
static const char *split_cmdline_errors[] = {
Expand Down
3 changes: 3 additions & 0 deletions alias.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#ifndef __ALIAS_H__
#define __ALIAS_H__

struct string_list;

char *alias_lookup(const char *alias);
int split_cmdline(char *cmdline, const char ***argv);
/* Takes a negative value returned by split_cmdline */
const char *split_cmdline_strerror(int cmdline_errno);
void list_aliases(struct string_list *list);

#endif
75 changes: 15 additions & 60 deletions contrib/completion/git-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -834,51 +834,11 @@ __git_complete_strategy ()
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_compute_all_commands ()
{
test -n "$__git_all_commands" ||
__git_all_commands=$(__git_list_all_commands)
}

__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)
__git_all_commands=$(git --list-cmds=main,others,alias,nohelpers)
}

# Lists all set config variables starting with the given section prefix,
Expand All @@ -896,11 +856,6 @@ __git_pretty_aliases ()
__git_get_config_variables "pretty"
}

__git_aliases ()
{
__git_get_config_variables "alias"
}

# __git_aliased_command requires 1 argument
__git_aliased_command ()
{
Expand Down Expand Up @@ -1500,13 +1455,6 @@ _git_grep ()
__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 ()
{
case "$cur" in
Expand All @@ -1515,11 +1463,12 @@ _git_help ()
return
;;
esac
__git_compute_all_commands
__git_compute_all_guides
__gitcomp "$__git_all_commands $(__git_aliases) $__git_all_guides
gitk
"
if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
then
__gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk"
else
__gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk"
fi
}

_git_init ()
Expand Down Expand Up @@ -3058,8 +3007,14 @@ __git_main ()
--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
return
fi
Expand Down
2 changes: 2 additions & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ static int list_cmds(const char *spec)
list_all_other_cmds(&list);
else if (match_token(spec, len, "nohelpers"))
exclude_helpers_from_list(&list);
else if (match_token(spec, len, "alias"))
list_aliases(&list);
else if (len > 5 && !strncmp(spec, "list-", 5)) {
struct strbuf sb = STRBUF_INIT;

Expand Down
18 changes: 0 additions & 18 deletions t/t9902-completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1192,17 +1192,6 @@ test_expect_success '__git_pretty_aliases' '
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' '
run_completion "git " &&
# built-in
Expand Down Expand Up @@ -1511,13 +1500,6 @@ test_expect_success 'sourcing the completion script clears cached 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' '
__git_compute_merge_strategies &&
verbose test -n "$__git_merge_strategies" &&
Expand Down

0 comments on commit 3301d36

Please sign in to comment.