nd/command-list updates
Subsystems (2)
cover nd/command-list updates
This should be the final update before nd/command-list hits 'next', hopefully.
Besides the interdiff below, the old 12/13 is split into two: 12/14 keeps the complete output as close as possible to the base version and 13/14 removes some commands from the completion list.
interdiff
command-list.txt +3 -2
@@ -39,8 +39,9 @@ # mainporcelain commands are completable so you don't need this # attribute. # -# While not true commands, guides are also specified here, which can -# only have "guide" attribute and nothing else. +# As part of the Git man page list, the man(5/7) guides are also +# specified here, which can only have "guide" attribute and nothing +# else. # ### command list (do not change this line, also do not change alignment) # command name category [category] [category]
contrib/completion/git-completion.bash +2 -0
@@ -857,6 +857,8 @@ __git_complete_strategy () return 1 } +# __git_commands requires 1 argument: +# 1: the command group, either "all" or "porcelain" __git_commands () { case "$1" in porcelain)
Nguyễn Thái Ngọc Duy (14):
generate-cmds.sh: factor out synopsis extract code generate-cmds.sh: export all commands to command-list.h
help: use command-list.h for common command list Remove common-cmds.h
git.c: convert --list-* to --list-cmds=*
git --list-cmds: collect command list in a string_list
completion: implement and use --list-cmds=main,others
git: support --list-cmds=list-<category>
help: add "-a --verbose" to list all commands with synopsis
help: use command-list.txt for the source of guides command-list.txt: documentation and guide line
completion: let git provide the completable command list
completion: reduce completable command list
completion: allow to customize the completable command list
.gitignore | 2 +- Documentation/config.txt | 10 + Documentation/git-help.txt | 4 +- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- Makefile | 16 +- builtin/help.c | 39 +--- command-list.txt | 112 +++++++++--- contrib/completion/git-completion.bash | 162 +++++++--------- generate-cmdlist.sh | 126 ++++++++----- git.c | 68 ++++++- help.c | 244 ++++++++++++++++++++++--- help.h | 10 + t/t0012-help.sh | 26 ++- t/t9902-completion.sh | 5 +- 16 files changed, 576 insertions(+), 254 deletions(-)
Signature · 1 line
2.17.0.705.g3525833791
PATCH 1/14 generate-cmds.sh: factor out synopsis extract code
This makes it easier to reuse the same code in another place (very soon).
--- generate-cmdlist.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
generate-cmdlist.sh +11 -7
@@ -1,5 +1,15 @@ #!/bin/sh +get_synopsis () { + sed -n ' + /^NAME/,/'"$1"'/H + ${ + x + s/.*'"$1"' - \(.*\)/N_("\1")/ + p + }' "Documentation/$1.txt" +} + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { char name[16];
@@ -39,12 +49,6 @@ sort | while read cmd tags do tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") - sed -n ' - /^NAME/,/git-'"$cmd"'/H - ${ - x - s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", N_("\1"), '$tag'},/ - p - }' "Documentation/git-$cmd.txt" + echo " {\"$cmd\", $(get_synopsis git-$cmd), $tag}," done echo "};"
Signature · 1 line
2.17.0.705.g3525833791
PATCH 2/14 generate-cmds.sh: export all commands to command-list.h
In reply to Nguyễn Thái Ngọc DuyThe current generate-cmds.sh generates just enough to print "git help" output. That is, it only extracts help text for common commands.
The script is now updated to extract help text for all commands and keep command classification a new file, command-list.h. This will be useful later:
- "git help -a" could print a short summary of all commands instead of just the common ones.
- "git" could produce a list of commands of one or more category. One of its use is to reduce another command classification embedded in git-completion.bash.
The new file can be generated but is not used anywhere yet. The plan is we migrate away from common-cmds.h. Then we can kill off common-cmds.h build rules and generation code (and also delete duplicate content in command-list.h which we keep for now to not mess generate-cmds.sh up too much).
PS. The new fixed column requirement on command-list.txt is technically not needed. But it helps simplify the code a bit at this stage. We could lift this restriction later if we want to.
--- .gitignore | 1 + Makefile | 13 ++++++--- command-list.txt | 4 +-- generate-cmdlist.sh | 67 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 10 deletions(-)
.gitignore +1 -0
@@ -180,6 +180,7 @@ /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* /common-cmds.h +/command-list.h *.tar.gz *.dsc *.deb
Makefile +9 -4
@@ -757,7 +757,7 @@ LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a VCSSVN_LIB = vcs-svn/lib.a -GENERATED_H += common-cmds.h +GENERATED_H += common-cmds.h command-list.h LIB_H = $(shell $(FIND) . \ -name .git -prune -o \
@@ -1938,6 +1938,11 @@ $(BUILT_INS): git$X common-cmds.h: generate-cmdlist.sh command-list.txt common-cmds.h: $(wildcard Documentation/git-*.txt) + $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt COMMON >$@+ && mv $@+ $@ + +command-list.h: generate-cmdlist.sh command-list.txt + +command-list.h: $(wildcard Documentation/git-*.txt) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
@@ -2148,7 +2153,7 @@ else # Dependencies on header files, for platforms that do not support # the gcc -MMD option. # -# Dependencies on automatically generated headers such as common-cmds.h +# Dependencies on automatically generated headers such as common-cmds.h or command-list.h # should _not_ be included here, since they are necessary even when # building an object for the first time.
@@ -2527,7 +2532,7 @@ sparse: $(SP_OBJ) style: git clang-format --style file --diff --extensions c,h -check: common-cmds.h +check: common-cmds.h command-list.h @if sparse; \ then \ echo >&2 "Use 'make sparse' instead"; \
@@ -2775,7 +2780,7 @@ clean: profile-clean coverage-clean $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) $(RM) -r bin-wrappers $(dep_dirs) $(RM) -r po/build/ - $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope* + $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h command-list.h $(ETAGS_TARGET) tags cscope* $(RM) -r $(GIT_TARNAME) .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
command-list.txt +2 -2
@@ -8,8 +8,8 @@ info examine the history and state (see also: git help revisions) history grow, mark and tweak your common history remote collaborate (see also: git help workflows) -### command list (do not change this line) -# command name category [deprecated] [common] +### command list (do not change this line, also do not change alignment) +# command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators
generate-cmdlist.sh +63 -4
82 lines not on this page · raw message
Signature · 1 line
2.17.0.705.g3525833791
PATCH 3/14 help: use command-list.h for common command list
In reply to Nguyễn Thái Ngọc DuyThe previous commit added code generation for all_cmd_desc[] which includes almost everything we need to generate common command list. Convert help code to use that array instead and drop common_cmds[] array.
The description of each common command group is removed from command-list.txt. This keeps this file format simpler. common-cmds.h will not be generated correctly after this change due to the command-list.txt format change. But it does not matter and common-cmds.h will be removed.
--- Makefile | 4 +- command-list.txt | 10 --- generate-cmdlist.sh | 4 +- help.c | 145 +++++++++++++++++++++++++++++++++----------- t/t0012-help.sh | 9 +++ 5 files changed, 122 insertions(+), 50 deletions(-)
Makefile +2 -2
@@ -1914,9 +1914,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ $(filter %.o,$^) $(LIBS) -help.sp help.s help.o: common-cmds.h +help.sp help.s help.o: common-cmds.h command-list.h -builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX +builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h command-list.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
command-list.txt +0 -10
@@ -1,13 +1,3 @@ -# common commands are grouped by themes -# these groups are output by 'git help' in the order declared here. -# map each common command in the command list to one of these groups. -### common groups (do not change this line) -init start a working area (see also: git help tutorial) -worktree work on the current change (see also: git help everyday) -info examine the history and state (see also: git help revisions) -history grow, mark and tweak your common history -remote collaborate (see also: git help workflows) - ### command list (do not change this line, also do not change alignment) # command name category [category] [category] git-add mainporcelain worktree
generate-cmdlist.sh +2 -2
@@ -6,7 +6,7 @@ die () { } command_list () { - sed '1,/^### command list/d;/^#/d' "$1" + grep -v '^#' "$1" } get_categories () {
@@ -65,7 +65,7 @@ echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { const char *name; const char *help; - uint32_t group; + uint32_t category; }; " if test -z "$2"
help.c +109 -36
192 lines not on this page · raw message
t/t0012-help.sh +9 -0
@@ -49,6 +49,15 @@ test_expect_success "--help does not work for guides" " test_i18ncmp expect actual " +test_expect_success 'git help' ' + git help >help.output && + test_i18ngrep "^ clone " help.output && + test_i18ngrep "^ add " help.output && + test_i18ngrep "^ log " help.output && + test_i18ngrep "^ commit " help.output && + test_i18ngrep "^ fetch " help.output +' + test_expect_success 'generate builtin list' ' git --list-builtins >builtins '
Signature · 1 line
2.17.0.705.g3525833791
PATCH 4/14 Remove common-cmds.h
In reply to Nguyễn Thái Ngọc DuyAfter the last patch, common-cmds.h is no longer used (and it was actually broken). Remove all related code. command-list.h will take its place from now on.
--- .gitignore | 1 - Makefile | 17 ++++++----------- generate-cmdlist.sh | 46 +++------------------------------------------ 3 files changed, 9 insertions(+), 55 deletions(-)
.gitignore +0 -1
@@ -179,7 +179,6 @@ /gitweb/gitweb.cgi /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* -/common-cmds.h /command-list.h *.tar.gz *.dsc
Makefile +6 -11
@@ -757,7 +757,7 @@ LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a VCSSVN_LIB = vcs-svn/lib.a -GENERATED_H += common-cmds.h command-list.h +GENERATED_H += command-list.h LIB_H = $(shell $(FIND) . \ -name .git -prune -o \
@@ -1914,9 +1914,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ $(filter %.o,$^) $(LIBS) -help.sp help.s help.o: common-cmds.h command-list.h +help.sp help.s help.o: command-list.h -builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h command-list.h GIT-PREFIX +builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
@@ -1935,11 +1935,6 @@ $(BUILT_INS): git$X ln -s $< $@ 2>/dev/null || \ cp $< $@ -common-cmds.h: generate-cmdlist.sh command-list.txt - -common-cmds.h: $(wildcard Documentation/git-*.txt) - $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt COMMON >$@+ && mv $@+ $@ - command-list.h: generate-cmdlist.sh command-list.txt command-list.h: $(wildcard Documentation/git-*.txt)
@@ -2153,7 +2148,7 @@ else # Dependencies on header files, for platforms that do not support # the gcc -MMD option. # -# Dependencies on automatically generated headers such as common-cmds.h or command-list.h +# Dependencies on automatically generated headers such as command-list.h # should _not_ be included here, since they are necessary even when # building an object for the first time.
@@ -2532,7 +2527,7 @@ sparse: $(SP_OBJ) style: git clang-format --style file --diff --extensions c,h -check: common-cmds.h command-list.h +check: command-list.h @if sparse; \ then \ echo >&2 "Use 'make sparse' instead"; \
@@ -2780,7 +2775,7 @@ clean: profile-clean coverage-clean $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) $(RM) -r bin-wrappers $(dep_dirs) $(RM) -r po/build/ - $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h command-list.h $(ETAGS_TARGET) tags cscope* + $(RM) *.pyc *.pyo */*.pyc */*.pyo command-list.h $(ETAGS_TARGET) tags cscope* $(RM) -r $(GIT_TARNAME) .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
generate-cmdlist.sh +3 -43
49 lines not on this page · raw message
Signature · 1 line
2.17.0.705.g3525833791
PATCH 5/14 git.c: convert --list-* to --list-cmds=*
In reply to Nguyễn Thái Ngọc DuyEven if these are hidden options, let's make them a bit more generic since we're introducing more listing types shortly. The code is structured to allow combining multiple listing types together because we will soon add more types the 'builtins'.
'parseopt' remains separate because it has separate (SPC) to match git-completion.bash needs and will not combine with others.
--- contrib/completion/git-completion.bash | 2 +- git.c | 37 +++++++++++++++++++++----- t/t0012-help.sh | 2 +- 3 files changed, 33 insertions(+), 8 deletions(-)
contrib/completion/git-completion.bash +1 -1
@@ -3049,7 +3049,7 @@ __git_complete_common () { __git_cmds_with_parseopt_helper= __git_support_parseopt_helper () { test -n "$__git_cmds_with_parseopt_helper" || - __git_cmds_with_parseopt_helper="$(__git --list-parseopt-builtins)" + __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)" case " $__git_cmds_with_parseopt_helper " in *" $1 "*)
git.c +31 -6
@@ -38,6 +38,30 @@ static int use_pager = -1;static void list_builtins (unsigned int exclude_option,char sep); +static int match_token (const char *spec,int len,const char *token) +{ +int token_len =strlen (token); + +return len == token_len && !strncmp (spec, token, token_len); +} + +static int list_cmds (const char *spec) +{ +while (*spec) { +const char *sep =strchrnul (spec,',' ); +int len = sep - spec; + +if (match_token (spec, len,"builtins" )) +list_builtins (0 ,'\n' ); +else +die (_ ("unsupported command listing type '%s'" ), spec); + spec += len; +if (*spec ==',' ) + spec++; + } +return 0 ; +} +static void commit_pager_choice (void ) {switch (use_pager) {case 0 :
@@ -223,12 +247,13 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) } (*argv)++; (*argc)--; - }else if (!strcmp (cmd,"--list-builtins" )) { -list_builtins (0 ,'\n' ); -exit (0 ); - }else if (!strcmp (cmd,"--list-parseopt-builtins" )) { -list_builtins (NO_PARSEOPT ,' ' ); -exit (0 ); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"parseopt" )) { +list_builtins (NO_PARSEOPT ,' ' ); +exit (0 ); + }else { +exit (list_cmds (cmd)); + } }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);usage (git_usage_string);
t/t0012-help.sh +1 -1
@@ -59,7 +59,7 @@ test_expect_success 'git help' ' ' test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.705.g3525833791
PATCH 6/14 git --list-cmds: collect command list in a string_list
In reply to Nguyễn Thái Ngọc DuyInstead of printing the command directly one by one, keep them in a list and print at the end. This allows more modification before we print out (e.g. sorting, removing duplicates or even excluding some items).
--- git.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
git.c +17 -5
@@ -36,7 +36,7 @@ const char git_more_info_string[] =static int use_pager =-1 ; -static void list_builtins (unsigned int exclude_option,char sep); +static void list_builtins (struct string_list *list,unsigned int exclude_option);static int match_token (const char *spec,int len,const char *token) {
@@ -47,18 +47,24 @@ static int match_token(const char *spec, int len, const char *token)static int list_cmds (const char *spec) { +struct string_list list =STRING_LIST_INIT_DUP ; +int i; +while (*spec) {const char *sep =strchrnul (spec,',' );int len = sep - spec;if (match_token (spec, len,"builtins" )) -list_builtins (0 ,'\n' ); +list_builtins (&list,0 );else die (_ ("unsupported command listing type '%s'" ), spec); spec += len;if (*spec ==',' ) spec++; } +for (i =0 ; i < list.nr; i++) +puts (list.items[i].string); +string_list_clear (&list,0 );return 0 ; }
@@ -249,7 +255,13 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argc)--; }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) {if (!strcmp (cmd,"parseopt" )) { -list_builtins (NO_PARSEOPT ,' ' ); +struct string_list list =STRING_LIST_INIT_DUP ; +int i; + +list_builtins (&list,NO_PARSEOPT ); +for (i =0 ; i < list.nr; i++) +printf ("%s " , list.items[i].string); +string_list_clear (&list,0 );exit (0 ); }else {exit (list_cmds (cmd));
@@ -533,14 +545,14 @@ int is_builtin(const char *s)return !!get_builtin (s); } -static void list_builtins (unsigned int exclude_option,char sep) +static void list_builtins (struct string_list *out,unsigned int exclude_option) {int i;for (i =0 ; i <ARRAY_SIZE (commands); i++) {if (exclude_option && (commands[i].option & exclude_option))continue ; -printf ("%s%c" , commands[i].cmd, sep); +string_list_append (out, commands[i].cmd); } }
Signature · 1 line
2.17.0.705.g3525833791
PATCH 7/14 completion: implement and use --list-cmds=main,others
In reply to Nguyễn Thái Ngọc DuyThis is part of the effort to break down and provide commands by category in machine-readable form. This could be helpful later on when completion script switches to use --list-cmds for selecting completable commands. It would be much easier for the user to choose to complete _all_ commands instead of the default selection by passing different values to --list-cmds in git-completino.bash.
While at there, replace "git help -a" in git-completion.bash with --list-cmds since it's better suited for this task.
--- contrib/completion/git-completion.bash | 2 +- git.c | 4 ++++ help.c | 32 ++++++++++++++++++++++++++ help.h | 4 ++++ 4 files changed, 41 insertions(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
@@ -839,7 +839,7 @@ __git_commands () { then printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" else - git help -a|egrep '^ [a-zA-Z0-9]' + git --list-cmds=main,others fi }
git.c +4 -0
@@ -56,6 +56,10 @@ static int list_cmds(const char *spec)if (match_token (spec, len,"builtins" ))list_builtins (&list,0 ); +else if (match_token (spec, len,"main" )) +list_all_main_cmds (&list); +else if (match_token (spec, len,"others" )) +list_all_other_cmds (&list);else die (_ ("unsupported command listing type '%s'" ), spec); spec += len;
help.c +32 -0
@@ -297,6 +297,38 @@ void list_common_cmds_help(void)print_cmd_by_category (common_categories); } +void list_all_main_cmds (struct string_list *list) +{ +struct cmdnames main_cmds, other_cmds; +int i; + +memset (&main_cmds,0 ,sizeof (main_cmds)); +memset (&other_cmds,0 ,sizeof (other_cmds)); +load_command_list ("git-" , &main_cmds, &other_cmds); + +for (i =0 ; i < main_cmds.cnt; i++) +string_list_append (list, main_cmds.names[i]->name); + +clean_cmdnames (&main_cmds); +clean_cmdnames (&other_cmds); +} + +void list_all_other_cmds (struct string_list *list) +{ +struct cmdnames main_cmds, other_cmds; +int i; + +memset (&main_cmds,0 ,sizeof (main_cmds)); +memset (&other_cmds,0 ,sizeof (other_cmds)); +load_command_list ("git-" , &main_cmds, &other_cmds); + +for (i =0 ; i < other_cmds.cnt; i++) +string_list_append (list, other_cmds.names[i]->name); + +clean_cmdnames (&main_cmds); +clean_cmdnames (&other_cmds); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +4 -0
@@ -1,6 +1,8 @@ #ifndef HELP_H #define HELP_H +struct string_list; + struct cmdnames { int alloc; int cnt;
@@ -17,6 +19,8 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_main_cmds (struct string_list *list); +extern void list_all_other_cmds (struct string_list *list);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791
PATCH 8/14 git: support --list-cmds=list-<category>
In reply to Nguyễn Thái Ngọc DuyThis allows us to select any group of commands by a category defined in command-list.txt. This is an internal/hidden option so we don't have to be picky about the category name or worried about exposing too much.
This will be used later by git-completion.bash to retrieve certain command groups.
--- generate-cmdlist.sh | 17 +++++++++++++++++ git.c | 7 +++++++ help.c | 23 +++++++++++++++++++++++ help.h | 2 ++ 4 files changed, 49 insertions(+)
generate-cmdlist.sh +17 -0
@@ -45,6 +45,21 @@ define_categories () { test "$bit" -gt 32 && die "Urgh.. too many categories?" } +define_category_names () { + echo + echo "/* Category names */" + echo "static const char *category_names[] = {" + bit=0 + category_list "$1" | + while read cat + do + echo " \"$cat\", /* (1UL << $bit) */" + bit=$(($bit+1)) + done + echo " NULL" + echo "};" +} + print_command_list () { echo "static struct cmdname_help command_list[] = {"
@@ -70,4 +85,6 @@ struct cmdname_help { " define_categories "$1" echo +define_category_names "$1" +echo print_command_list "$1"
git.c +7 -0
@@ -60,6 +60,13 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) list_all_other_cmds(&list); + else if (len > 5 && !strncmp(spec, "list-", 5)) { +struct strbuf sb =STRBUF_INIT ; + +strbuf_add (&sb, spec +5 , len -5 ); +list_cmds_by_category (&list, sb.buf); +strbuf_release (&sb); + } else die(_("unsupported command listing type '%s'"), spec); spec += len;
help.c +23 -0
@@ -329,6 +329,29 @@ void list_all_other_cmds(struct string_list *list)clean_cmdnames (&other_cmds); } +void list_cmds_by_category (struct string_list *list, +const char *cat) +{ +int i, n =ARRAY_SIZE (command_list); +uint32_t cat_id =0 ; + +for (i =0 ; category_names[i]; i++) { +if (!strcmp (cat, category_names[i])) { + cat_id =1UL << i; +break ; + } + } +if (!cat_id) +die (_ ("unsupported command listing type '%s'" ), cat); + +for (i =0 ; i < n; i++) { +struct cmdname_help *cmd = command_list + i; + +if (cmd->category & cat_id) +string_list_append (list,drop_prefix (cmd->name)); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +2 -0
@@ -21,6 +21,8 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list); +extern void list_cmds_by_category (struct string_list *list, +const char *category);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791
PATCH 9/14 help: add "-a --verbose" to list all commands with synopsis
In reply to Nguyễn Thái Ngọc DuyThis lists all recognized commands [1] by category. The group order follows closely git.txt.
[1] We may actually show commands that are not built (e.g. if you set NO_PERL you don't have git-instaweb but it's still listed here). I ignore the problem because on Linux a git package could be split anyway. The "git-core" package may not contain git-instaweb even if it's built because it may end up in a separate package. We can't know anyway.
--- Documentation/git-help.txt | 4 +++- builtin/help.c | 7 +++++++ help.c | 16 ++++++++++++++++ help.h | 2 ++ t/t0012-help.sh | 9 +++++++++ 5 files changed, 37 insertions(+), 1 deletion(-)
Documentation/git-help.txt +3 -1
@@ -8,7 +8,7 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all] [-g|--guide] +'git help' [-a|--all [--verbose]] [-g|--guide] [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE] DESCRIPTION
@@ -42,6 +42,8 @@ OPTIONS --all:: Prints all the available commands on the standard output. This option overrides any given command or guide name. + When used with `--verbose` print description for all recognized + commands. -g:: --guides::
builtin/help.c +7 -0
@@ -36,6 +36,7 @@ static const char *html_path;static int show_all =0 ;static int show_guides =0 ; +static int verbose;static unsigned int colopts;static enum help_format help_format =HELP_FORMAT_NONE ;static int exclude_guides;
@@ -48,6 +49,7 @@ static struct option builtin_help_options[] = { HELP_FORMAT_WEB),OPT_SET_INT ('i' ,"info" , &help_format,N_ ("show info page" ),HELP_FORMAT_INFO ), +OPT__VERBOSE (&verbose,N_ ("print command description" )), OPT_END(), };
@@ -463,6 +465,11 @@ int cmd_help(int argc, const char **argv, const char *prefix)if (show_all) {git_config (git_help_config,NULL ); +if (verbose) { +setup_pager (); +list_all_cmds_help (); +return 0 ; + }printf (_ ("usage: %s%s" ),_ (git_usage_string),"\n\n" );load_command_list ("git-" , &main_cmds, &other_cmds);list_commands (colopts, &main_cmds, &other_cmds);
help.c +16 -0
@@ -27,6 +27,17 @@ static struct category_description common_categories[] = { { CAT_remote, N_("collaborate (see also: git help workflows)") }, { 0, NULL } }; +static struct category_description main_categories[] = { + { CAT_mainporcelain,N_ ("Main Porcelain Commands" ) }, + { CAT_ancillarymanipulators,N_ ("Ancillary Commands / Manipulators" ) }, + { CAT_ancillaryinterrogators,N_ ("Ancillary Commands / Interrogators" ) }, + { CAT_foreignscminterface,N_ ("Interacting with Others" ) }, + { CAT_plumbingmanipulators,N_ ("Low-level Commands / Manipulators" ) }, + { CAT_plumbinginterrogators,N_ ("Low-level Commands / Interrogators" ) }, + { CAT_synchingrepositories,N_ ("Low-level Commands / Synching Repositories" ) }, + { CAT_purehelpers,N_ ("Low-level Commands / Internal Helpers" ) }, + {0 ,NULL } +};static const char *drop_prefix (const char *name) {
@@ -352,6 +363,11 @@ void list_cmds_by_category(struct string_list *list, } } +void list_all_cmds_help (void ) +{ +print_cmd_by_category (main_categories); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +2 -0
@@ -19,6 +19,8 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds_help (void ); +extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list); extern void list_cmds_by_category(struct string_list *list,
t/t0012-help.sh +9 -0
@@ -25,6 +25,15 @@ test_expect_success "setup" ' EOF ' +# make sure to exercise these code paths, the output is a bit tricky +# to verify +test_expect_success 'basic help commands' ' + git help >/dev/null && + git help -a >/dev/null && + git help -g >/dev/null && + git help -av >/dev/null +' + test_expect_success "works for commands and guides by default" ' configure_help && git help status &&
Signature · 1 line
2.17.0.705.g3525833791
PATCH 10/14 help: use command-list.txt for the source of guides
In reply to Nguyễn Thái Ngọc DuyThe help command currently hard codes the list of guides and their summary in C. Let's move this list to command-list.txt. This lets us extract summary lines from Documentation/git*.txt. This also potentially lets us list guides in git.txt, but I'll leave that for now.
--- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- Makefile | 2 +- builtin/help.c | 32 -------------------------- command-list.txt | 16 +++++++++++++ contrib/completion/git-completion.bash | 15 ++++++++---- help.c | 21 +++++++++++++---- help.h | 1 + t/t0012-help.sh | 6 +++++ 10 files changed, 54 insertions(+), 45 deletions(-)
Documentation/gitattributes.txt +1 -1
@@ -3,7 +3,7 @@ gitattributes(5) NAME ---- -gitattributes - defining attributes per path +gitattributes - Defining attributes per path SYNOPSIS --------
Documentation/gitmodules.txt +1 -1
@@ -3,7 +3,7 @@ gitmodules(5) NAME ---- -gitmodules - defining submodule properties +gitmodules - Defining submodule properties SYNOPSIS --------
Documentation/gitrevisions.txt +1 -1
@@ -3,7 +3,7 @@ gitrevisions(7) NAME ---- -gitrevisions - specifying revisions and ranges for Git +gitrevisions - Specifying revisions and ranges for Git SYNOPSIS --------
Makefile +1 -1
@@ -1937,7 +1937,7 @@ $(BUILT_INS): git$X command-list.h: generate-cmdlist.sh command-list.txt -command-list.h: $(wildcard Documentation/git-*.txt) +command-list.h: $(wildcard Documentation/git*.txt) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
builtin/help.c +0 -32
@@ -402,38 +402,6 @@ static void show_html_page(const char *git_cmd)open_html (page_path.buf); } -static struct { -const char *name; -const char *help; -} common_guides[] = { - {"attributes" ,N_ ("Defining attributes per path" ) }, - {"everyday" ,N_ ("Everyday Git With 20 Commands Or So" ) }, - {"glossary" ,N_ ("A Git glossary" ) }, - {"ignore" ,N_ ("Specifies intentionally untracked files to ignore" ) }, - {"modules" ,N_ ("Defining submodule properties" ) }, - {"revisions" ,N_ ("Specifying revisions and ranges for Git" ) }, - {"tutorial" ,N_ ("A tutorial introduction to Git (for version 1.5.1 or newer)" ) }, - {"workflows" ,N_ ("An overview of recommended workflows with Git" ) }, -}; - -static void list_common_guides_help (void ) -{ -int i, longest =0 ; - -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -if (longest <strlen (common_guides[i].name)) - longest =strlen (common_guides[i].name); - } - -puts (_ ("The common Git guides are:\n" )); -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -printf (" %s " , common_guides[i].name); -mput_char (' ' , longest -strlen (common_guides[i].name)); -puts (_ (common_guides[i].help)); - } -putchar ('\n' ); -} -static const char *check_git_cmd (const char * cmd) {char *alias;
command-list.txt +16 -0
@@ -139,3 +139,19 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +gitcli guide +gitcore-tutorial guide +gitcvs-migration guide +gitdiffcore guide +giteveryday guide +gitglossary guide +githooks guide +gitignore guide +gitmodules guide +gitnamespaces guide +gitrepository-layout guide +gitrevisions guide +gittutorial-2 guide +gittutorial guide +gitworkflows guide
contrib/completion/git-completion.bash +10 -5
@@ -1575,6 +1575,13 @@ _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
@@ -1584,11 +1591,9 @@ _git_help () ;; esac __git_compute_all_commands - __gitcomp "$__git_all_commands $(__git_aliases) - attributes cli core-tutorial cvs-migration - diffcore everyday gitk glossary hooks ignore modules - namespaces repository-layout revisions tutorial tutorial-2 - workflows + __git_compute_all_guides + __gitcomp "$__git_all_commands $(__git_aliases) $__git_all_guides + gitk " }
help.c +17 -4
@@ -39,12 +39,14 @@ static struct category_description main_categories[] = { { 0, NULL } }; -static const char *drop_prefix (const char *name) +static const char *drop_prefix (const char *name,uint32_t category) {const char *new_name;if (skip_prefix (name,"git-" , &new_name))return new_name; +if (category == CAT_guide &&skip_prefix (name,"git" , &new_name)) +return new_name;return name; }
@@ -66,7 +68,7 @@ static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask)continue ; cmds[nr] = *cmd; - cmds[nr].name =drop_prefix (cmd->name); + cmds[nr].name =drop_prefix (cmd->name, cmd->category); nr++; }
@@ -358,11 +360,22 @@ void list_cmds_by_category(struct string_list *list,for (i =0 ; i < n; i++) {struct cmdname_help *cmd = command_list + i; -if (cmd->category & cat_id) -string_list_append (list,drop_prefix (cmd->name)); +if (!(cmd->category & cat_id)) +continue ; +string_list_append (list,drop_prefix (cmd->name, cmd->category)); } } +void list_common_guides_help (void ) +{ +struct category_description catdesc[] = { + { CAT_guide,N_ ("The common Git guides are:" ) }, + {0 ,NULL } + }; +print_cmd_by_category (catdesc); +putchar ('\n' ); +} +void list_all_cmds_help (void ) {print_cmd_by_category (main_categories);
help.h +1 -0
@@ -20,6 +20,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds_help (void ); +extern void list_common_guides_help (void );extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list);
t/t0012-help.sh +6 -0
@@ -66,6 +66,12 @@ test_expect_success 'git help' ' test_i18ngrep "^ commit " help.output && test_i18ngrep "^ fetch " help.output ' +test_expect_success 'git help -g' ' + git help -g >help.output && + test_i18ngrep "^ attributes " help.output && + test_i18ngrep "^ everyday " help.output && + test_i18ngrep "^ tutorial " help.output +' test_expect_success 'generate builtin list' ' git --list-cmds=builtins >builtins
Signature · 1 line
2.17.0.705.g3525833791
PATCH 11/14 command-list.txt: documentation and guide line
In reply to Nguyễn Thái Ngọc DuyThis is intended to help anybody who needs to update command-list.txt. It gives a brief introduction of all attributes a command can take.
--- command-list.txt | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
command-list.txt +45 -0
@@ -1,3 +1,48 @@ +# Command classification list +# --------------------------- +# All supported commands, builtin or external, must be described in +# here. This info is used to list commands in various places. Each +# command is on one line followed by one or more attributes. +# +# The first attribute group is mandatory and indicates the command +# type. This group includes: +# +# mainporcelain +# ancillarymanipulators +# ancillaryinterrogators +# foreignscminterface +# plumbingmanipulators +# plumbinginterrogators +# synchingrepositories +# synchelpers +# purehelpers +# +# The type names are self explanatory. But if you want to see what +# command belongs to what group to get a better picture, have a look +# at "git" man page, "GIT COMMANDS" section. +# +# Commands of type mainporcelain can also optionally have one of these +# attributes: +# +# init +# worktree +# info +# history +# remote +# +# These commands are considered "common" and will show up in "git +# help" output in groups. Uncommon porcelain commands must not +# specify any of these attributes. +# +# "complete" attribute is used to mark that the command should be +# completable by git-completion.bash. Note that by default, +# mainporcelain commands are completable so you don't need this +# attribute. +# +# As part of the Git man page list, the man(5/7) guides are also +# specified here, which can only have "guide" attribute and nothing +# else. +# ### command list (do not change this line, also do not change alignment) # command name category [category] [category] git-add mainporcelain worktree
Signature · 1 line
2.17.0.705.g3525833791
PATCH 12/14 completion: let git provide the completable command list
In reply to Nguyễn Thái Ngọc DuyInstead of maintaining a separate list of command classification, which often could go out of date, let's centralize the information back in git.
While the function in git-completion.bash implies "list porcelain commands", that's not exactly what it does. It gets all commands (aka --list-cmds=main,others) then exclude certain non-porcelain ones. We could almost recreate this list two lists list-mainporcelain and others. The non-porcelain-but-included-anyway is added by the third category list-complete.
list-complete does not recreate exactly the command list before this patch though. The following commands will disappear from the complete list because they are not in command-list.txt and it's not worth adding them back: lost-found, peek-remote and tar-tree.
Note that the current completion script incorrectly classifies filter-branch as porcelain and t9902 tests this behavior. We keep it this way in t9902 because this test does not really care which particular command is porcelain or plubmbing, they're just names.
--- command-list.txt | 53 +++++------ contrib/completion/git-completion.bash | 119 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 58 insertions(+), 119 deletions(-)
command-list.txt +27 -26
@@ -47,12 +47,12 @@ # command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain -git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +git-annotate ancillaryinterrogators complete +git-apply plumbingmanipulators complete git-archimport foreignscminterface git-archive mainporcelain git-bisect mainporcelain info -git-blame ancillaryinterrogators +git-blame ancillaryinterrogators complete git-branch mainporcelain history git-bundle mainporcelain git-cat-file plumbinginterrogators
@@ -62,7 +62,7 @@ git-check-mailmap purehelpers git-checkout mainporcelain history git-checkout-index plumbingmanipulators git-check-ref-format purehelpers -git-cherry ancillaryinterrogators +git-cherry ancillaryinterrogators complete git-cherry-pick mainporcelain git-citool mainporcelain git-clean mainporcelain
@@ -70,7 +70,7 @@ git-clone mainporcelain init git-column purehelpers git-commit mainporcelain history git-commit-tree plumbingmanipulators -git-config ancillarymanipulators +git-config ancillarymanipulators complete git-count-objects ancillaryinterrogators git-credential purehelpers git-credential-cache purehelpers
@@ -84,30 +84,30 @@ git-diff mainporcelain history git-diff-files plumbinginterrogators git-diff-index plumbinginterrogators git-diff-tree plumbinginterrogators -git-difftool ancillaryinterrogators +git-difftool ancillaryinterrogators complete git-fast-export ancillarymanipulators git-fast-import ancillarymanipulators git-fetch mainporcelain remote git-fetch-pack synchingrepositories -git-filter-branch ancillarymanipulators +git-filter-branch ancillarymanipulators complete git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain -git-fsck ancillaryinterrogators +git-fsck ancillaryinterrogators complete git-gc mainporcelain -git-get-tar-commit-id ancillaryinterrogators +git-get-tar-commit-id ancillaryinterrogators complete git-grep mainporcelain info git-gui mainporcelain git-hash-object plumbingmanipulators -git-help ancillaryinterrogators +git-help ancillaryinterrogators complete git-http-backend synchingrepositories git-http-fetch synchelpers git-http-push synchelpers -git-imap-send foreignscminterface +git-imap-send foreignscminterface complete git-index-pack plumbingmanipulators git-init mainporcelain init -git-instaweb ancillaryinterrogators -git-interpret-trailers purehelpers +git-instaweb ancillaryinterrogators complete +git-interpret-trailers purehelpers complete gitk mainporcelain git-log mainporcelain info git-ls-files plumbinginterrogators
@@ -120,14 +120,14 @@ git-merge-base plumbinginterrogators git-merge-file plumbingmanipulators git-merge-index plumbingmanipulators git-merge-one-file purehelpers -git-mergetool ancillarymanipulators +git-mergetool ancillarymanipulators complete git-merge-tree ancillaryinterrogators git-mktag plumbingmanipulators git-mktree plumbingmanipulators git-mv mainporcelain worktree -git-name-rev plumbinginterrogators +git-name-rev plumbinginterrogators complete git-notes mainporcelain -git-p4 foreignscminterface +git-p4 foreignscminterface complete git-pack-objects plumbingmanipulators git-pack-redundant plumbinginterrogators git-pack-refs ancillarymanipulators
@@ -141,32 +141,33 @@ git-quiltimport foreignscminterface git-read-tree plumbingmanipulators git-rebase mainporcelain history git-receive-pack synchelpers -git-reflog ancillarymanipulators -git-remote ancillarymanipulators -git-repack ancillarymanipulators -git-replace ancillarymanipulators -git-request-pull foreignscminterface +git-reflog ancillarymanipulators complete +git-remote ancillarymanipulators complete +git-repack ancillarymanipulators complete +git-replace ancillarymanipulators complete +git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain worktree git-revert mainporcelain git-rev-list plumbinginterrogators git-rev-parse ancillaryinterrogators git-rm mainporcelain worktree -git-send-email foreignscminterface +git-send-email foreignscminterface complete git-send-pack synchingrepositories git-shell synchelpers git-shortlog mainporcelain git-show mainporcelain info -git-show-branch ancillaryinterrogators +git-show-branch ancillaryinterrogators complete git-show-index plumbinginterrogators git-show-ref plumbinginterrogators git-sh-i18n purehelpers git-sh-setup purehelpers git-stash mainporcelain +git-stage complete git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain -git-svn foreignscminterface +git-svn foreignscminterface complete git-symbolic-ref plumbingmanipulators git-tag mainporcelain history git-unpack-file plumbinginterrogators
@@ -177,11 +178,11 @@ git-update-server-info synchingrepositories git-upload-archive synchelpers git-upload-pack synchelpers git-var plumbinginterrogators -git-verify-commit ancillaryinterrogators +git-verify-commit ancillaryinterrogators complete git-verify-pack plumbinginterrogators git-verify-tag ancillaryinterrogators gitweb ancillaryinterrogators -git-whatchanged ancillaryinterrogators +git-whatchanged ancillaryinterrogators complete git-worktree mainporcelain git-write-tree plumbingmanipulators gitattributes guide
contrib/completion/git-completion.bash +28 -91
142 lines not on this page · raw message
t/t9902-completion.sh +3 -2
@@ -13,7 +13,7 @@ complete () return 0 } -# Be careful when updating this list: +# Be careful when updating these lists: # # (1) The build tree may have build artifact from different branch, or # the user's $PATH may have a random executable that may begin
@@ -30,7 +30,8 @@ complete () # completion for "git <TAB>", and a plumbing is excluded. "add", # "filter-branch" and "ls-files" are listed for this. -GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files' +GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files' +GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch' . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
Signature · 1 line
2.17.0.705.g3525833791
Re: [PATCH 12/14] completion: let git provide the completable command list
Quoted 11 lines · Nguyễn Thái Ngọc Duy
Instead of maintaining a separate list of command classification, which often could go out of date, let's centralize the information back in git.
While the function in git-completion.bash implies "list porcelain commands", that's not exactly what it does. It gets all commands (aka --list-cmds=main,others) then exclude certain non-porcelain ones. We could almost recreate this list two lists list-mainporcelain and others. The non-porcelain-but-included-anyway is added by the third category list-complete.
Quoted 4 lines
list-complete does not recreate exactly the command list before this patch though. The following commands will disappear from the complete list because they are not in command-list.txt and it's not worth adding them back: lost-found, peek-remote and tar-tree.
These commands have been removed long ago, see the topic leading to 577aed296a (Merge branch 'jk/remove-deprecated', 2013-12-12). Perhaps you saw them only because they are still somewhere on your $PATH or $GIT_EXEC_PATH?
Quoted 4 lines
Note that the current completion script incorrectly classifies filter-branch as porcelain and t9902 tests this behavior. We keep it this way in t9902 because this test does not really care which particular command is porcelain or plubmbing, they're just names.
s/plubmbing/plumbing/
Re: [PATCH 12/14] completion: let git provide the completable command list
Quoted 17 lines · SZEDER Gábor
Quoted 11 lines · Nguyễn Thái Ngọc Duy
Instead of maintaining a separate list of command classification, which often could go out of date, let's centralize the information back in git.
While the function in git-completion.bash implies "list porcelain commands", that's not exactly what it does. It gets all commands (aka --list-cmds=main,others) then exclude certain non-porcelain ones. We could almost recreate this list two lists list-mainporcelain and others. The non-porcelain-but-included-anyway is added by the third category list-complete.
Quoted 4 lines
list-complete does not recreate exactly the command list before this patch though. The following commands will disappear from the complete list because they are not in command-list.txt and it's not worth adding them back: lost-found, peek-remote and tar-tree.
Quoted 4 lines
These commands have been removed long ago, see the topic leading to
577aed296a(Merge branch 'jk/remove-deprecated', 2013-12-12). Perhaps you saw them only because they are still somewhere on your $PATH or $GIT_EXEC_PATH?
Right. Old commands remain in my libexec dir. Will clean up this commit message.
Signature · 1 line
Duy
PATCH 13/14 completion: reduce completable command list
In reply to Nguyễn Thái Ngọc DuyThe following commands are removed from the complete list:
- annotate obsolete, discouraged to use - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - p4 too short and probably not often used (*) - svn same category as p4 (*) - verify-commit not often used
(*) to be fair, send-email command which is in the same foreignscminterface group as svn and p4 does get completion, just because it's used by git and kernel development. So maybe we should include them.
--- command-list.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
command-list.txt +8 -8
@@ -47,7 +47,7 @@ # command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain -git-annotate ancillaryinterrogators complete +git-annotate ancillaryinterrogators git-apply plumbingmanipulators complete git-archimport foreignscminterface git-archive mainporcelain
@@ -89,13 +89,13 @@ git-fast-export ancillarymanipulators git-fast-import ancillarymanipulators git-fetch mainporcelain remote git-fetch-pack synchingrepositories -git-filter-branch ancillarymanipulators complete +git-filter-branch ancillarymanipulators git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain git-fsck ancillaryinterrogators complete git-gc mainporcelain -git-get-tar-commit-id ancillaryinterrogators complete +git-get-tar-commit-id ancillaryinterrogators git-grep mainporcelain info git-gui mainporcelain git-hash-object plumbingmanipulators
@@ -103,11 +103,11 @@ git-help ancillaryinterrogators complete git-http-backend synchingrepositories git-http-fetch synchelpers git-http-push synchelpers -git-imap-send foreignscminterface complete +git-imap-send foreignscminterface git-index-pack plumbingmanipulators git-init mainporcelain init git-instaweb ancillaryinterrogators complete -git-interpret-trailers purehelpers complete +git-interpret-trailers purehelpers gitk mainporcelain git-log mainporcelain info git-ls-files plumbinginterrogators
@@ -127,7 +127,7 @@ git-mktree plumbingmanipulators git-mv mainporcelain worktree git-name-rev plumbinginterrogators complete git-notes mainporcelain -git-p4 foreignscminterface complete +git-p4 foreignscminterface git-pack-objects plumbingmanipulators git-pack-redundant plumbinginterrogators git-pack-refs ancillarymanipulators
@@ -167,7 +167,7 @@ git-stage complete git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain -git-svn foreignscminterface complete +git-svn foreignscminterface git-symbolic-ref plumbingmanipulators git-tag mainporcelain history git-unpack-file plumbinginterrogators
@@ -178,7 +178,7 @@ git-update-server-info synchingrepositories git-upload-archive synchelpers git-upload-pack synchelpers git-var plumbinginterrogators -git-verify-commit ancillaryinterrogators complete +git-verify-commit ancillaryinterrogators git-verify-pack plumbinginterrogators git-verify-tag ancillaryinterrogators gitweb ancillaryinterrogators
Signature · 1 line
2.17.0.705.g3525833791
Re: [PATCH 13/14] completion: reduce completable command list
Quoted 13 lines · Nguyễn Thái Ngọc Duy
The following commands are removed from the complete list:
- annotate obsolete, discouraged to use - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - p4 too short and probably not often used (*) - svn same category as p4 (*) - verify-commit not often used
command-list.txt git-mktree plumbingmanipulators · line 128
Quoted 2 lines
command-list.txt +0
-0@@ -127,7 +127,7 @@ git-mktree plumbingmanipulators git-mv mainporcelain worktree git-name-rev plumbinginterrogators complete
Since 'git name-rev' is plumbing, and since it's functionality is fully covered by the 'git describe' porcelain, shouldn't it be removed as well?
Re: [PATCH 13/14] completion: reduce completable command list
In reply to Nguyễn Thái Ngọc DuyQuoted 3 lines · Nguyễn Thái Ngọc Duy
The following commands are removed from the complete list:
- interpreter-trailers not for interactive use
Typo here. see below.
Quoted 2 lines
command-list.txt +1
-1-git-interpret-trailers purehelpers complete +git-interpret-trailers purehelpers
PATCH 14/14 completion: allow to customize the completable command list
In reply to Nguyễn Thái Ngọc DuyBy default we show porcelain, external commands and a couple others that are also popular. If you are not happy with this list, you can now customize it. See the big comment block for details.
PS. perhaps I should make aliases a group too, which makes it possible to _not_ complete aliases by omitting this special group in $GIT_COMPLETION_CMD_GROUPS
--- Documentation/config.txt | 10 ++++++++ contrib/completion/git-completion.bash | 28 +++++++++++++++++++++- git.c | 2 ++ help.c | 33 ++++++++++++++++++++++++++ help.h | 1 + 5 files changed, 73 insertions(+), 1 deletion(-)
Documentation/config.txt +10 -0
@@ -1343,6 +1343,16 @@ credential.<url>.*:: credentialCache.ignoreSIGHUP:: Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting. +completion.commands:: + This is only used by git-completion.bash to add or remove + commands from the complete list. Normally only porcelain + commands and a few select others are in the complete list. You + can add more commands, separated by space, in this + variable. Prefixing the command with '-' will remove it from + the existing list. ++ +This variable should not be per-repository. + include::diff-config.txt[] difftool.<tool>.path::
contrib/completion/git-completion.bash +27 -1
@@ -38,6 +38,29 @@ # # When set to "1", do not include "DWIM" suggestions in git-checkout # completion (e.g., completing "foo" when "origin/foo" exists). +# +# GIT_COMPLETION_CMD_GROUPS +# +# When set, "git --list-cmds=$GIT_COMPLETION_CMD_GROUPS" will be +# used to get the list of completable commands. The default is +# "mainporcelain,others,list-complete" (in English: all porcelain +# commands and external ones are included. Certain non-porcelain +# commands are also marked for completion in command-list.txt). +# You could for example complete all commands with +# +# GIT_COMPLETION_CMD_GROUPS=main,others +# +# Or you could go with main porcelain only and extra commands in +# the configuration variable completion.commands with +# +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,config +# +# Or go completely custom group with +# +# GIT_COMPLETION_CMD_GROUPS=config +# +# Or you could even play with other command categories found in +# command-list.txt. case "$COMP_WORDBREAKS" in *:*) : great ;;
@@ -842,8 +865,11 @@ __git_commands () { if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST" then printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + elif test -n "$GIT_COMPLETION_CMD_GROUPS" + then + git --list-cmds="$GIT_COMPLETION_CMD_GROUPS" else - git --list-cmds=list-mainporcelain,others,list-complete + git --list-cmds=list-mainporcelain,others,list-complete,config fi ;; all)
git.c +2 -0
@@ -60,6 +60,8 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) list_all_other_cmds(&list); + else if (match_token(spec, len, "config")) + list_cmds_by_config(&list); else if (len > 5 && !strncmp(spec, "list-", 5)) {struct strbuf sb =STRBUF_INIT ;
help.c +33 -0
@@ -366,6 +366,39 @@ void list_cmds_by_category(struct string_list *list, } } +void list_cmds_by_config (struct string_list *list) +{ +const char *cmd_list; + +/* +* There's no actual repository setup at this point (and even +* if there is, we don't really care; only global config +* matters). If we accidentally set up a repository, it's ok +* too since the caller (git --list-cmds=) should exit shortly +* anyway. +*/ +if (git_config_get_string_const ("completion.commands" , &cmd_list)) +return ; + +string_list_sort (list); +string_list_remove_duplicates (list,0 ); + +while (*cmd_list) { +struct strbuf sb =STRBUF_INIT ; +const char *p =strchrnul (cmd_list,' ' ); + +strbuf_add (&sb, cmd_list, p - cmd_list); +if (*cmd_list =='-' ) +string_list_remove (list, cmd_list +1 ,0 ); +else +string_list_insert (list, sb.buf); +strbuf_release (&sb); +while (*p ==' ' ) + p++; + cmd_list = p; + } +} +void list_common_guides_help (void ) {struct category_description catdesc[] = {
help.h +1 -0
@@ -26,6 +26,7 @@ extern void list_all_main_cmds(struct string_list *list);extern void list_all_other_cmds (struct string_list *list);extern void list_cmds_by_category (struct string_list *list,const char *category); +extern void list_cmds_by_config (struct string_list *list);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791
Re: [PATCH 14/14] completion: allow to customize the completable command list
Quoted 7 lines · Nguyễn Thái Ngọc Duy
By default we show porcelain, external commands and a couple others that are also popular. If you are not happy with this list, you can now customize it. See the big comment block for details.
PS. perhaps I should make aliases a group too, which makes it possible to _not_ complete aliases by omitting this special group in $GIT_COMPLETION_CMD_GROUPS
Note that the completion script reads the configured aliases each time the user attempts to complete commands. So if the user adds or removes an alias, then it will automatically be taken into account the next time after 'git <TAB>'. By turning aliases into a group listed by 'git help' they would be cached like all other commands, so this would no longer be the case.
Quoted 14 lines
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- Documentation/config.txt | 10 ++++++++ contrib/completion/git-completion.bash | 28 +++++++++++++++++++++- git.c | 2 ++ help.c | 33 ++++++++++++++++++++++++++ help.h | 1 + 5 files changed, 73 insertions(+), 1 deletion(-)Documentation/config.txt +0
-0
Documentation/config.txt credential.<url>.*:: · line 1348
Quoted 6 lines
Documentation/config.txt +3
-0@@ -1343,6 +1343,16 @@ credential.<url>.*:: credentialCache.ignoreSIGHUP:: Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting. +completion.commands:: + This is only used by git-completion.bash to add or remove + commands from the complete list. Normally only porcelain
s/complete list/list of completed commands/ perhaps?
Documentation/config.txt credential.<url>.*:: · line 1349
Quoted 1 line
Documentation/config.txt +1
-0+ commands and a few select others are in the complete list. You
s/in the complete list/completed/
Documentation/config.txt credential.<url>.*:: · line 1354
Quoted 5 lines
Documentation/config.txt +5
-0+ can add more commands, separated by space, in this + variable. Prefixing the command with '-' will remove it from + the existing list. ++ +This variable should not be per-repository.
I think this should also mention that changing the value of this config variable will not immediately affect the commands listed after 'git <TAB>', but the user will have to re-dot-source the completion script first.
The way I understand the rest of the patch, this config variable doesn't have any effect if $GIT_COMPLETION_CMD_GROUPS doesn't contain "config". If that is indeed the case, then that should be mentioned here as well.
Having said that, I wonder whether we should really require "config" in $GIT_COMPLETION_CMD_GROUPS. Isn't having 'completion.commands' set in the config a clear enough indication in itself that the user wants to customize the listed commands?
Quoted 9 lines
Documentation/config.txt +1
-0+ include::diff-config.txt[] difftool.<tool>.path::contrib/completion/git-completion.bash +0
-0
contrib/completion/git-completion.bash line 46
Quoted 9 lines
contrib/completion/git-completion.bash +6
-0@@ -38,6 +38,29 @@ # # When set to "1", do not include "DWIM" suggestions in git-checkout # completion (e.g., completing "foo" when "origin/foo" exists). +# +# GIT_COMPLETION_CMD_GROUPS +# +# When set, "git --list-cmds=$GIT_COMPLETION_CMD_GROUPS" will be +# used to get the list of completable commands. The default is +# "mainporcelain,others,list-complete" (in English: all porcelain
Mental note #1: "mainporcelain"
contrib/completion/git-completion.bash line 51
Quoted 5 lines
contrib/completion/git-completion.bash +5
-0+# commands and external ones are included. Certain non-porcelain +# commands are also marked for completion in command-list.txt). +# You could for example complete all commands with +# +# GIT_COMPLETION_CMD_GROUPS=main,others
Mental note #2: "main"
Quoted 16 lines
contrib/completion/git-completion.bash +12
-0+# +# Or you could go with main porcelain only and extra commands in +# the configuration variable completion.commands with +# +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,config +# +# Or go completely custom group with +# +# GIT_COMPLETION_CMD_GROUPS=config +# +# Or you could even play with other command categories found in +# command-list.txt. case "$COMP_WORDBREAKS" in *:*) : great ;;
contrib/completion/git-completion.bash __git_commands () { · line 872
Quoted 9 lines
contrib/completion/git-completion.bash +4
-1@@ -842,8 +865,11 @@ __git_commands () { if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST" then printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + elif test -n "$GIT_COMPLETION_CMD_GROUPS" + then + git --list-cmds="$GIT_COMPLETION_CMD_GROUPS" else - git --list-cmds=list-mainporcelain,others,list-complete + git --list-cmds=list-mainporcelain,others,list-complete,config
So first it was "mainporcelain", then simply "main", then "mainporcelain" again, and now "list-mainporcelain"?! You've lost me here.
Are the possible values documented anywhere?
Furthermore, the default value mentioned in the comments above didn't include "config", either (but then again, I don't think we really need "config" in the first place).
Quoted 75 lines
contrib/completion/git-completion.bash +0
-0fi ;; all)git.c +2
-0@@ -60,6 +60,8 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) list_all_other_cmds(&list); + else if (match_token(spec, len, "config")) + list_cmds_by_config(&list); else if (len > 5 && !strncmp(spec, "list-", 5)) {struct strbuf sb =STRBUF_INIT ;help.c +33
-0@@ -366,6 +366,39 @@ void list_cmds_by_category(struct string_list *list, } } +void list_cmds_by_config (struct string_list *list) +{ +const char *cmd_list; + +/* +* There's no actual repository setup at this point (and even +* if there is, we don't really care; only global config +* matters). If we accidentally set up a repository, it's ok +* too since the caller (git --list-cmds=) should exit shortly +* anyway. +*/ +if (git_config_get_string_const ("completion.commands" , &cmd_list)) +return ; + +string_list_sort (list); +string_list_remove_duplicates (list,0 ); + +while (*cmd_list) { +struct strbuf sb =STRBUF_INIT ; +const char *p =strchrnul (cmd_list,' ' ); + +strbuf_add (&sb, cmd_list, p - cmd_list); +if (*cmd_list =='-' ) +string_list_remove (list, cmd_list +1 ,0 ); +else +string_list_insert (list, sb.buf); +strbuf_release (&sb); +while (*p ==' ' ) + p++; + cmd_list = p; + } +} +void list_common_guides_help (void ) {struct category_description catdesc[] = {help.h +1
-1@@ -26,6 +26,7 @@ extern void list_all_main_cmds(struct string_list *list);extern void list_all_other_cmds (struct string_list *list);extern void list_cmds_by_category (struct string_list *list,const char *category); +extern void list_cmds_by_config (struct string_list *list);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds, --2.17.0.705.g3525833791
Re: [PATCH 14/14] completion: allow to customize the completable command list
Quoted 9 lines · SZEDER Gábor
Quoted 7 lines · Nguyễn Thái Ngọc Duy
By default we show porcelain, external commands and a couple others that are also popular. If you are not happy with this list, you can now customize it. See the big comment block for details.
PS. perhaps I should make aliases a group too, which makes it possible to _not_ complete aliases by omitting this special group in $GIT_COMPLETION_CMD_GROUPS
Quoted 6 lines
Note that the completion script reads the configured aliases each time the user attempts to complete commands. So if the user adds or removes an alias, then it will automatically be taken into account the next time after 'git <TAB>'. By turning aliases into a group listed by 'git help' they would be cached like all other commands, so this would no longer be the case.
Maybe we can stop caching "git --list-cmds=..." then. We achieve the same effect for completion.commands (changes take effect immediately) and don't add any more overhead (still one git call per completion)? This can also avoid the per-repository limitation below.
Quoted 44 lines
Quoted 15 lines
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- Documentation/config.txt | 10 ++++++++ contrib/completion/git-completion.bash | 28 +++++++++++++++++++++- git.c | 2 ++ help.c | 33 ++++++++++++++++++++++++++ help.h | 1 + 5 files changed, 73 insertions(+), 1 deletion(-)Documentation/config.txt +0
-0Documentation/config.txt credential.<url>.*:: · line 1348
Quoted 6 lines
Documentation/config.txt +3
-0@@ -1343,6 +1343,16 @@ credential.<url>.*:: credentialCache.ignoreSIGHUP:: Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting. +completion.commands:: + This is only used by git-completion.bash to add or remove + commands from the complete list. Normally only porcelains/complete list/list of completed commands/ perhaps?
Documentation/config.txt credential.<url>.*:: · line 1349
Quoted 1 line
Documentation/config.txt +1
-0+ commands and a few select others are in the complete list. Yous/in the complete list/completed/
Documentation/config.txt credential.<url>.*:: · line 1354
Quoted 5 lines
Documentation/config.txt +5
-0+ can add more commands, separated by space, in this + variable. Prefixing the command with '-' will remove it from + the existing list. ++ +This variable should not be per-repository.I think this should also mention that changing the value of this config variable will not immediately affect the commands listed after 'git <TAB>', but the user will have to re-dot-source the completion script first.
The way I understand the rest of the patch, this config variable doesn't have any effect if $GIT_COMPLETION_CMD_GROUPS doesn't contain "config". If that is indeed the case, then that should be mentioned here as well.
Quoted 4 lines
Having said that, I wonder whether we should really require "config" in $GIT_COMPLETION_CMD_GROUPS. Isn't having 'completion.commands' set in the config a clear enough indication in itself that the user wants to customize the listed commands?
$GIT_COMPLETION_CMD_GROUPS is for really specific customization. I initially added it because "config" was not default, and because completion.commands could not exclude commands, only include them. Now that is possible, perhaps just completion.commands (no $GIT_COMPLETINO_CMD_GROUPS) would suffice for most cases?
Quoted 60 lines
Quoted 10 lines
Documentation/config.txt +1
-0+ include::diff-config.txt[] difftool.<tool>.path::contrib/completion/git-completion.bash +0
-0contrib/completion/git-completion.bash line 46
Quoted 9 lines
contrib/completion/git-completion.bash +6
-0@@ -38,6 +38,29 @@ # # When set to "1", do not include "DWIM" suggestions in git-checkout # completion (e.g., completing "foo" when "origin/foo" exists). +# +# GIT_COMPLETION_CMD_GROUPS +# +# When set, "git --list-cmds=$GIT_COMPLETION_CMD_GROUPS" will be +# used to get the list of completable commands. The default is +# "mainporcelain,others,list-complete" (in English: all porcelainMental note #1: "mainporcelain"
contrib/completion/git-completion.bash line 51
Quoted 5 lines
contrib/completion/git-completion.bash +5
-0+# commands and external ones are included. Certain non-porcelain +# commands are also marked for completion in command-list.txt). +# You could for example complete all commands with +# +# GIT_COMPLETION_CMD_GROUPS=main,othersMental note #2: "main"
Quoted 16 lines
contrib/completion/git-completion.bash +12
-0+# +# Or you could go with main porcelain only and extra commands in +# the configuration variable completion.commands with +# +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,config +# +# Or go completely custom group with +# +# GIT_COMPLETION_CMD_GROUPS=config +# +# Or you could even play with other command categories found in +# command-list.txt. case "$COMP_WORDBREAKS" in *:*) : great ;;contrib/completion/git-completion.bash __git_commands () { · line 872
Quoted 9 lines
contrib/completion/git-completion.bash +4
-1@@ -842,8 +865,11 @@ __git_commands () { if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST" then printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + elif test -n "$GIT_COMPLETION_CMD_GROUPS" + then + git --list-cmds="$GIT_COMPLETION_CMD_GROUPS" else - git --list-cmds=list-mainporcelain,others,list-complete + git --list-cmds=list-mainporcelain,others,list-complete,configSo first it was "mainporcelain", then simply "main", then "mainporcelain" again, and now "list-mainporcelain"?! You've lost me here.
Quoted 1 line
Are the possible values documented anywhere?
In the code :) I did not document it because it was hidden option and it may change again. list-XXX corresponds to the XXX tag in command-list.txt while the no "list-" like "main", "config", or "others" provide the command list from other sources (e.g. libexec for "main", $PATH for "ohers", completion.commands for "config")
Quoted 3 lines
Furthermore, the default value mentioned in the comments above didn't include "config", either (but then again, I don't think we really need "config" in the first place).
Yeah that comment block was out of date. I think including "config" by default gives a smoother experience. You just update completion.commands and ready, you don't need to export $GITC_COMPLETION_CMD_GROUPS before sourcing git-completion.bash (which, depends on distro, may be done automatically and hard to intervene except modifying the script itself).
Signature · 1 line
Duy
v2 cover nd/command-list updates
In reply to Nguyễn Thái Ngọc DuyIt turns out this series is not done as I thought it was :)
v2 makes it possible to write
gitcomp "$(git --list-cmds=...)"
which is really nice and very close to what gitcomp_builtin does. Other changes are
- support --list-cmds=alias and --list-cmds=nohelpers so that we could do the above
- a bit more document about --list-cmds
- $GIT_COMPLETION_CMD_GROUPS is dropped. I think it just causes more confusion and complete.commands should be enough in most cases
- name-rev is no longer compleable
- "git help <tab>" does not show truly external commands anymore (those that are in $PATH but not in libexec and very unlikely to have a man page)
Documentation/config.txt +2 -4
@@ -1345,13 +1345,11 @@ credentialCache.ignoreSIGHUP:: completion.commands:: This is only used by git-completion.bash to add or remove - commands from the complete list. Normally only porcelain - commands and a few select others are in the complete list. You + commands from the list of completed commands. Normally only + porcelain commands and a few select others are completed. You can add more commands, separated by space, in this variable. Prefixing the command with '-' will remove it from the existing list. -+ -This variable should not be per-repository. include::diff-config.txt[]
Documentation/git.txt +10 -0
@@ -163,6 +163,16 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config Do not perform optional operations that require locks. This is equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`. +--list-cmds=group[,group...]:: + List commands by group. This is an internal/experimental + option and may change or be removed in the future. Supported + groups are: builtins, parseopt (builtin commands that use + 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), alias and config + (retrieve command list from config variable completion.commands) + GIT COMMANDS ------------
alias.c +20 -2
@@ -1,9 +1,12 @@#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)
@@ -11,8 +14,16 @@ 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 ; }
@@ -26,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 2static const char *split_cmdline_errors[] = {
alias.h new file +12 -0
@@ -0,0 +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
builtin/help.c +1 -0
@@ -9,6 +9,7 @@#include "run-command.h" #include "column.h" #include "help.h" +#include "alias.h" #ifndef DEFAULT_HELP_FORMAT #define DEFAULT_HELP_FORMAT "man"
builtin/merge.c +1 -0
@@ -34,6 +34,7 @@#include "string-list.h" #include "packfile.h" #include "tag.h" +#include "alias.h" #define DEFAULT_TWOHEAD (1<<0)#define DEFAULT_OCTOPUS (1<<1)
cache.h +0 -5
@@ -1835,11 +1835,6 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);void overlay_tree_on_index (struct index_state *istate,const char *tree_name,const char *prefix); -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); -/* setup.c */ struct startup_info {int have_repository;
command-list.txt +1 -1
@@ -125,7 +125,7 @@ git-merge-tree ancillaryinterrogators git-mktag plumbingmanipulators git-mktree plumbingmanipulators git-mv mainporcelain worktree -git-name-rev plumbinginterrogators complete +git-name-rev plumbinginterrogators git-notes mainporcelain git-p4 foreignscminterface git-pack-objects plumbingmanipulators
connect.c +1 -0
@@ -13,6 +13,7 @@#include "transport.h" #include "strbuf.h" #include "protocol.h" +#include "alias.h" static char *server_capabilities;static const char *parse_feature_value (const char *,const char *,int *);
contrib/completion/git-completion.bash +15 -98
153 lines not on this page · raw message
git.c +17 -0
@@ -3,6 +3,7 @@#include "exec_cmd.h" #include "help.h" #include "run-command.h" +#include "alias.h" #define RUN_SETUP (1<<0)#define RUN_SETUP_GENTLY (1<<1)
@@ -38,6 +39,18 @@ static int use_pager = -1;static void list_builtins (struct string_list *list,unsigned int exclude_option); +static void exclude_helpers_from_list (struct string_list *list) +{ +int i =0 ; + +while (i < list->nr) { +if (strstr (list->items[i].string,"--" )) +unsorted_string_list_delete_item (list, i,0 ); +else + i++; + } +} +static int match_token (const char *spec,int len,const char *token) {int token_len =strlen (token);
@@ -60,6 +73,10 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) 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 (match_token(spec, len, "config")) list_cmds_by_config(&list); else if (len > 5 && !strncmp(spec, "list-", 5)) {
pager.c +1 -0
@@ -2,6 +2,7 @@#include "config.h" #include "run-command.h" #include "sigchain.h" +#include "alias.h" #ifndef DEFAULT_PAGER #define DEFAULT_PAGER "less"
sequencer.c +1 -0
@@ -23,6 +23,7 @@#include "hashmap.h" #include "notes-utils.h" #include "sigchain.h" +#include "alias.h" #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
shell.c +1 -0
@@ -3,6 +3,7 @@#include "exec_cmd.h" #include "strbuf.h" #include "run-command.h" +#include "alias.h" #define COMMAND_DIR "git-shell-commands"#define HELP_COMMAND COMMAND_DIR "/help"
t/t9902-completion.sh +0 -18
@@ -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
@@ -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" &&
Nguyễn Thái Ngọc Duy (17):
generate-cmds.sh: factor out synopsis extract code generate-cmds.sh: export all commands to command-list.h
help: use command-list.h for common command list Remove common-cmds.h
git.c: convert --list-* to --list-cmds=*
git --list-cmds: collect command list in a string_list
completion: implement and use --list-cmds=main,others
git: support --list-cmds=list-<category>
help: add "-a --verbose" to list all commands with synopsis
help: use command-list.txt for the source of guides command-list.txt: documentation and guide line
completion: let git provide the completable command list
completion: reduce completable command list
Move declaration for alias.c to alias.h
completion: add and use --list-cmds=nohelpers
completion: add and use --list-cmds=alias
completion: allow to customize the completable command list
.gitignore | 2 +- Documentation/config.txt | 8 + Documentation/git-help.txt | 4 +- Documentation/git.txt | 10 + Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- Makefile | 16 +- alias.c | 22 ++- alias.h | 12 ++ builtin/help.c | 40 +--- builtin/merge.c | 1 + cache.h | 5 - command-list.txt | 110 ++++++++--- connect.c | 1 + contrib/completion/git-completion.bash | 147 ++------------- generate-cmdlist.sh | 126 ++++++++----- git.c | 85 ++++++++- help.c | 244 ++++++++++++++++++++++--- help.h | 10 + pager.c | 1 + sequencer.c | 1 + shell.c | 1 + t/t0012-help.sh | 26 ++- t/t9902-completion.sh | 23 +-- 25 files changed, 589 insertions(+), 312 deletions(-) create mode 100644 alias.h
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 1/17 generate-cmds.sh: factor out synopsis extract code
This makes it easier to reuse the same code in another place (very soon).
--- generate-cmdlist.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
generate-cmdlist.sh +11 -7
@@ -1,5 +1,15 @@ #!/bin/sh +get_synopsis () { + sed -n ' + /^NAME/,/'"$1"'/H + ${ + x + s/.*'"$1"' - \(.*\)/N_("\1")/ + p + }' "Documentation/$1.txt" +} + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { char name[16];
@@ -39,12 +49,6 @@ sort | while read cmd tags do tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") - sed -n ' - /^NAME/,/git-'"$cmd"'/H - ${ - x - s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", N_("\1"), '$tag'},/ - p - }' "Documentation/git-$cmd.txt" + echo " {\"$cmd\", $(get_synopsis git-$cmd), $tag}," done echo "};"
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 2/17 generate-cmds.sh: export all commands to command-list.h
In reply to Nguyễn Thái Ngọc DuyThe current generate-cmds.sh generates just enough to print "git help" output. That is, it only extracts help text for common commands.
The script is now updated to extract help text for all commands and keep command classification a new file, command-list.h. This will be useful later:
- "git help -a" could print a short summary of all commands instead of just the common ones.
- "git" could produce a list of commands of one or more category. One of its use is to reduce another command classification embedded in git-completion.bash.
The new file can be generated but is not used anywhere yet. The plan is we migrate away from common-cmds.h. Then we can kill off common-cmds.h build rules and generation code (and also delete duplicate content in command-list.h which we keep for now to not mess generate-cmds.sh up too much).
PS. The new fixed column requirement on command-list.txt is technically not needed. But it helps simplify the code a bit at this stage. We could lift this restriction later if we want to.
--- .gitignore | 1 + Makefile | 13 ++++++--- command-list.txt | 4 +-- generate-cmdlist.sh | 67 ++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 75 insertions(+), 10 deletions(-)
.gitignore +1 -0
@@ -180,6 +180,7 @@ /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* /common-cmds.h +/command-list.h *.tar.gz *.dsc *.deb
Makefile +9 -4
@@ -757,7 +757,7 @@ LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a VCSSVN_LIB = vcs-svn/lib.a -GENERATED_H += common-cmds.h +GENERATED_H += common-cmds.h command-list.h LIB_H = $(shell $(FIND) . \ -name .git -prune -o \
@@ -1938,6 +1938,11 @@ $(BUILT_INS): git$X common-cmds.h: generate-cmdlist.sh command-list.txt common-cmds.h: $(wildcard Documentation/git-*.txt) + $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt COMMON >$@+ && mv $@+ $@ + +command-list.h: generate-cmdlist.sh command-list.txt + +command-list.h: $(wildcard Documentation/git-*.txt) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
@@ -2148,7 +2153,7 @@ else # Dependencies on header files, for platforms that do not support # the gcc -MMD option. # -# Dependencies on automatically generated headers such as common-cmds.h +# Dependencies on automatically generated headers such as common-cmds.h or command-list.h # should _not_ be included here, since they are necessary even when # building an object for the first time.
@@ -2527,7 +2532,7 @@ sparse: $(SP_OBJ) style: git clang-format --style file --diff --extensions c,h -check: common-cmds.h +check: common-cmds.h command-list.h @if sparse; \ then \ echo >&2 "Use 'make sparse' instead"; \
@@ -2775,7 +2780,7 @@ clean: profile-clean coverage-clean $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) $(RM) -r bin-wrappers $(dep_dirs) $(RM) -r po/build/ - $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope* + $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h command-list.h $(ETAGS_TARGET) tags cscope* $(RM) -r $(GIT_TARNAME) .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
command-list.txt +2 -2
@@ -8,8 +8,8 @@ info examine the history and state (see also: git help revisions) history grow, mark and tweak your common history remote collaborate (see also: git help workflows) -### command list (do not change this line) -# command name category [deprecated] [common] +### command list (do not change this line, also do not change alignment) +# command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators
generate-cmdlist.sh +63 -4
82 lines not on this page · raw message
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 3/17 help: use command-list.h for common command list
In reply to Nguyễn Thái Ngọc DuyThe previous commit added code generation for all_cmd_desc[] which includes almost everything we need to generate common command list. Convert help code to use that array instead and drop common_cmds[] array.
The description of each common command group is removed from command-list.txt. This keeps this file format simpler. common-cmds.h will not be generated correctly after this change due to the command-list.txt format change. But it does not matter and common-cmds.h will be removed.
--- Makefile | 4 +- command-list.txt | 10 --- generate-cmdlist.sh | 4 +- help.c | 145 +++++++++++++++++++++++++++++++++----------- t/t0012-help.sh | 9 +++ 5 files changed, 122 insertions(+), 50 deletions(-)
Makefile +2 -2
@@ -1914,9 +1914,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ $(filter %.o,$^) $(LIBS) -help.sp help.s help.o: common-cmds.h +help.sp help.s help.o: common-cmds.h command-list.h -builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX +builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h command-list.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
command-list.txt +0 -10
@@ -1,13 +1,3 @@ -# common commands are grouped by themes -# these groups are output by 'git help' in the order declared here. -# map each common command in the command list to one of these groups. -### common groups (do not change this line) -init start a working area (see also: git help tutorial) -worktree work on the current change (see also: git help everyday) -info examine the history and state (see also: git help revisions) -history grow, mark and tweak your common history -remote collaborate (see also: git help workflows) - ### command list (do not change this line, also do not change alignment) # command name category [category] [category] git-add mainporcelain worktree
generate-cmdlist.sh +2 -2
@@ -6,7 +6,7 @@ die () { } command_list () { - sed '1,/^### command list/d;/^#/d' "$1" + grep -v '^#' "$1" } get_categories () {
@@ -65,7 +65,7 @@ echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { const char *name; const char *help; - uint32_t group; + uint32_t category; }; " if test -z "$2"
help.c +109 -36
192 lines not on this page · raw message
t/t0012-help.sh +9 -0
@@ -49,6 +49,15 @@ test_expect_success "--help does not work for guides" " test_i18ncmp expect actual " +test_expect_success 'git help' ' + git help >help.output && + test_i18ngrep "^ clone " help.output && + test_i18ngrep "^ add " help.output && + test_i18ngrep "^ log " help.output && + test_i18ngrep "^ commit " help.output && + test_i18ngrep "^ fetch " help.output +' + test_expect_success 'generate builtin list' ' git --list-builtins >builtins '
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 4/17 Remove common-cmds.h
In reply to Nguyễn Thái Ngọc DuyAfter the last patch, common-cmds.h is no longer used (and it was actually broken). Remove all related code. command-list.h will take its place from now on.
--- .gitignore | 1 - Makefile | 17 ++++++----------- generate-cmdlist.sh | 46 +++------------------------------------------ 3 files changed, 9 insertions(+), 55 deletions(-)
.gitignore +0 -1
@@ -179,7 +179,6 @@ /gitweb/gitweb.cgi /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* -/common-cmds.h /command-list.h *.tar.gz *.dsc
Makefile +6 -11
@@ -757,7 +757,7 @@ LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a VCSSVN_LIB = vcs-svn/lib.a -GENERATED_H += common-cmds.h command-list.h +GENERATED_H += command-list.h LIB_H = $(shell $(FIND) . \ -name .git -prune -o \
@@ -1914,9 +1914,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ $(filter %.o,$^) $(LIBS) -help.sp help.s help.o: common-cmds.h command-list.h +help.sp help.s help.o: command-list.h -builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h command-list.h GIT-PREFIX +builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
@@ -1935,11 +1935,6 @@ $(BUILT_INS): git$X ln -s $< $@ 2>/dev/null || \ cp $< $@ -common-cmds.h: generate-cmdlist.sh command-list.txt - -common-cmds.h: $(wildcard Documentation/git-*.txt) - $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt COMMON >$@+ && mv $@+ $@ - command-list.h: generate-cmdlist.sh command-list.txt command-list.h: $(wildcard Documentation/git-*.txt)
@@ -2153,7 +2148,7 @@ else # Dependencies on header files, for platforms that do not support # the gcc -MMD option. # -# Dependencies on automatically generated headers such as common-cmds.h or command-list.h +# Dependencies on automatically generated headers such as command-list.h # should _not_ be included here, since they are necessary even when # building an object for the first time.
@@ -2532,7 +2527,7 @@ sparse: $(SP_OBJ) style: git clang-format --style file --diff --extensions c,h -check: common-cmds.h command-list.h +check: command-list.h @if sparse; \ then \ echo >&2 "Use 'make sparse' instead"; \
@@ -2780,7 +2775,7 @@ clean: profile-clean coverage-clean $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) $(RM) -r bin-wrappers $(dep_dirs) $(RM) -r po/build/ - $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h command-list.h $(ETAGS_TARGET) tags cscope* + $(RM) *.pyc *.pyo */*.pyc */*.pyo command-list.h $(ETAGS_TARGET) tags cscope* $(RM) -r $(GIT_TARNAME) .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
generate-cmdlist.sh +3 -43
49 lines not on this page · raw message
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 5/17 git.c: convert --list-* to --list-cmds=*
In reply to Nguyễn Thái Ngọc DuyEven if these are hidden options, let's make them a bit more generic since we're introducing more listing types shortly. The code is structured to allow combining multiple listing types together because we will soon add more types the 'builtins'.
'parseopt' remains separate because it has separate (SPC) to match git-completion.bash needs and will not combine with others.
--- Documentation/git.txt | 6 +++++ contrib/completion/git-completion.bash | 2 +- git.c | 37 +++++++++++++++++++++----- t/t0012-help.sh | 2 +- 4 files changed, 39 insertions(+), 8 deletions(-)
Documentation/git.txt +6 -0
@@ -163,6 +163,12 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config Do not perform optional operations that require locks. This is equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`. +--list-cmds=group[,group...]:: + List commands by group. This is an internal/experimental + option and may change or be removed in the future. Supported + groups are: builtins, parseopt (builtin commands that use + parse-options). + GIT COMMANDS ------------
contrib/completion/git-completion.bash +1 -1
@@ -3049,7 +3049,7 @@ __git_complete_common () { __git_cmds_with_parseopt_helper= __git_support_parseopt_helper () { test -n "$__git_cmds_with_parseopt_helper" || - __git_cmds_with_parseopt_helper="$(__git --list-parseopt-builtins)" + __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)" case " $__git_cmds_with_parseopt_helper " in *" $1 "*)
git.c +31 -6
@@ -38,6 +38,30 @@ static int use_pager = -1;static void list_builtins (unsigned int exclude_option,char sep); +static int match_token (const char *spec,int len,const char *token) +{ +int token_len =strlen (token); + +return len == token_len && !strncmp (spec, token, token_len); +} + +static int list_cmds (const char *spec) +{ +while (*spec) { +const char *sep =strchrnul (spec,',' ); +int len = sep - spec; + +if (match_token (spec, len,"builtins" )) +list_builtins (0 ,'\n' ); +else +die (_ ("unsupported command listing type '%s'" ), spec); + spec += len; +if (*spec ==',' ) + spec++; + } +return 0 ; +} +static void commit_pager_choice (void ) {switch (use_pager) {case 0 :
@@ -223,12 +247,13 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) } (*argv)++; (*argc)--; - }else if (!strcmp (cmd,"--list-builtins" )) { -list_builtins (0 ,'\n' ); -exit (0 ); - }else if (!strcmp (cmd,"--list-parseopt-builtins" )) { -list_builtins (NO_PARSEOPT ,' ' ); -exit (0 ); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"parseopt" )) { +list_builtins (NO_PARSEOPT ,' ' ); +exit (0 ); + }else { +exit (list_cmds (cmd)); + } }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);usage (git_usage_string);
t/t0012-help.sh +1 -1
@@ -59,7 +59,7 @@ test_expect_success 'git help' ' ' test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 6/17 git --list-cmds: collect command list in a string_list
In reply to Nguyễn Thái Ngọc DuyInstead of printing the command directly one by one, keep them in a list and print at the end. This allows more modification before we print out (e.g. sorting, removing duplicates or even excluding some items).
--- git.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
git.c +17 -5
@@ -36,7 +36,7 @@ const char git_more_info_string[] =static int use_pager =-1 ; -static void list_builtins (unsigned int exclude_option,char sep); +static void list_builtins (struct string_list *list,unsigned int exclude_option);static int match_token (const char *spec,int len,const char *token) {
@@ -47,18 +47,24 @@ static int match_token(const char *spec, int len, const char *token)static int list_cmds (const char *spec) { +struct string_list list =STRING_LIST_INIT_DUP ; +int i; +while (*spec) {const char *sep =strchrnul (spec,',' );int len = sep - spec;if (match_token (spec, len,"builtins" )) -list_builtins (0 ,'\n' ); +list_builtins (&list,0 );else die (_ ("unsupported command listing type '%s'" ), spec); spec += len;if (*spec ==',' ) spec++; } +for (i =0 ; i < list.nr; i++) +puts (list.items[i].string); +string_list_clear (&list,0 );return 0 ; }
@@ -249,7 +255,13 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argc)--; }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) {if (!strcmp (cmd,"parseopt" )) { -list_builtins (NO_PARSEOPT ,' ' ); +struct string_list list =STRING_LIST_INIT_DUP ; +int i; + +list_builtins (&list,NO_PARSEOPT ); +for (i =0 ; i < list.nr; i++) +printf ("%s " , list.items[i].string); +string_list_clear (&list,0 );exit (0 ); }else {exit (list_cmds (cmd));
@@ -533,14 +545,14 @@ int is_builtin(const char *s)return !!get_builtin (s); } -static void list_builtins (unsigned int exclude_option,char sep) +static void list_builtins (struct string_list *out,unsigned int exclude_option) {int i;for (i =0 ; i <ARRAY_SIZE (commands); i++) {if (exclude_option && (commands[i].option & exclude_option))continue ; -printf ("%s%c" , commands[i].cmd, sep); +string_list_append (out, commands[i].cmd); } }
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 7/17 completion: implement and use --list-cmds=main,others
In reply to Nguyễn Thái Ngọc DuyThis is part of the effort to break down and provide commands by category in machine-readable form. This could be helpful later on when completion script switches to use --list-cmds for selecting completable commands. It would be much easier for the user to choose to complete _all_ commands instead of the default selection by passing different values to --list-cmds in git-completino.bash.
While at there, replace "git help -a" in git-completion.bash with --list-cmds since it's better suited for this task.
--- Documentation/git.txt | 3 ++- contrib/completion/git-completion.bash | 2 +- git.c | 4 ++++ help.c | 32 ++++++++++++++++++++++++++ help.h | 4 ++++ 5 files changed, 43 insertions(+), 2 deletions(-)
Documentation/git.txt +2 -1
@@ -167,7 +167,8 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use - parse-options). + parse-options), main (all commands in libexec directory), + others (all other commands in `$PATH` that have git- prefix). GIT COMMANDS ------------
contrib/completion/git-completion.bash +1 -1
@@ -839,7 +839,7 @@ __git_commands () { then printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" else - git help -a|egrep '^ [a-zA-Z0-9]' + git --list-cmds=main,others fi }
git.c +4 -0
@@ -56,6 +56,10 @@ static int list_cmds(const char *spec)if (match_token (spec, len,"builtins" ))list_builtins (&list,0 ); +else if (match_token (spec, len,"main" )) +list_all_main_cmds (&list); +else if (match_token (spec, len,"others" )) +list_all_other_cmds (&list);else die (_ ("unsupported command listing type '%s'" ), spec); spec += len;
help.c +32 -0
@@ -297,6 +297,38 @@ void list_common_cmds_help(void)print_cmd_by_category (common_categories); } +void list_all_main_cmds (struct string_list *list) +{ +struct cmdnames main_cmds, other_cmds; +int i; + +memset (&main_cmds,0 ,sizeof (main_cmds)); +memset (&other_cmds,0 ,sizeof (other_cmds)); +load_command_list ("git-" , &main_cmds, &other_cmds); + +for (i =0 ; i < main_cmds.cnt; i++) +string_list_append (list, main_cmds.names[i]->name); + +clean_cmdnames (&main_cmds); +clean_cmdnames (&other_cmds); +} + +void list_all_other_cmds (struct string_list *list) +{ +struct cmdnames main_cmds, other_cmds; +int i; + +memset (&main_cmds,0 ,sizeof (main_cmds)); +memset (&other_cmds,0 ,sizeof (other_cmds)); +load_command_list ("git-" , &main_cmds, &other_cmds); + +for (i =0 ; i < other_cmds.cnt; i++) +string_list_append (list, other_cmds.names[i]->name); + +clean_cmdnames (&main_cmds); +clean_cmdnames (&other_cmds); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +4 -0
@@ -1,6 +1,8 @@ #ifndef HELP_H #define HELP_H +struct string_list; + struct cmdnames { int alloc; int cnt;
@@ -17,6 +19,8 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_main_cmds (struct string_list *list); +extern void list_all_other_cmds (struct string_list *list);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 8/17 git: support --list-cmds=list-<category>
In reply to Nguyễn Thái Ngọc DuyThis allows us to select any group of commands by a category defined in command-list.txt. This is an internal/hidden option so we don't have to be picky about the category name or worried about exposing too much.
This will be used later by git-completion.bash to retrieve certain command groups.
--- Documentation/git.txt | 3 ++- generate-cmdlist.sh | 17 +++++++++++++++++ git.c | 7 +++++++ help.c | 23 +++++++++++++++++++++++ help.h | 2 ++ 5 files changed, 51 insertions(+), 1 deletion(-)
Documentation/git.txt +2 -1
@@ -168,7 +168,8 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use 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) GIT COMMANDS ------------
generate-cmdlist.sh +17 -0
@@ -45,6 +45,21 @@ define_categories () { test "$bit" -gt 32 && die "Urgh.. too many categories?" } +define_category_names () { + echo + echo "/* Category names */" + echo "static const char *category_names[] = {" + bit=0 + category_list "$1" | + while read cat + do + echo " \"$cat\", /* (1UL << $bit) */" + bit=$(($bit+1)) + done + echo " NULL" + echo "};" +} + print_command_list () { echo "static struct cmdname_help command_list[] = {"
@@ -70,4 +85,6 @@ struct cmdname_help { " define_categories "$1" echo +define_category_names "$1" +echo print_command_list "$1"
git.c +7 -0
@@ -60,6 +60,13 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) list_all_other_cmds(&list); + else if (len > 5 && !strncmp(spec, "list-", 5)) { +struct strbuf sb =STRBUF_INIT ; + +strbuf_add (&sb, spec +5 , len -5 ); +list_cmds_by_category (&list, sb.buf); +strbuf_release (&sb); + } else die(_("unsupported command listing type '%s'"), spec); spec += len;
help.c +23 -0
@@ -329,6 +329,29 @@ void list_all_other_cmds(struct string_list *list)clean_cmdnames (&other_cmds); } +void list_cmds_by_category (struct string_list *list, +const char *cat) +{ +int i, n =ARRAY_SIZE (command_list); +uint32_t cat_id =0 ; + +for (i =0 ; category_names[i]; i++) { +if (!strcmp (cat, category_names[i])) { + cat_id =1UL << i; +break ; + } + } +if (!cat_id) +die (_ ("unsupported command listing type '%s'" ), cat); + +for (i =0 ; i < n; i++) { +struct cmdname_help *cmd = command_list + i; + +if (cmd->category & cat_id) +string_list_append (list,drop_prefix (cmd->name)); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +2 -0
@@ -21,6 +21,8 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list); +extern void list_cmds_by_category (struct string_list *list, +const char *category);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 9/17 help: add "-a --verbose" to list all commands with synopsis
In reply to Nguyễn Thái Ngọc DuyThis lists all recognized commands [1] by category. The group order follows closely git.txt.
[1] We may actually show commands that are not built (e.g. if you set NO_PERL you don't have git-instaweb but it's still listed here). I ignore the problem because on Linux a git package could be split anyway. The "git-core" package may not contain git-instaweb even if it's built because it may end up in a separate package. We can't know anyway.
--- Documentation/git-help.txt | 4 +++- builtin/help.c | 7 +++++++ help.c | 16 ++++++++++++++++ help.h | 2 ++ t/t0012-help.sh | 9 +++++++++ 5 files changed, 37 insertions(+), 1 deletion(-)
Documentation/git-help.txt +3 -1
@@ -8,7 +8,7 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all] [-g|--guide] +'git help' [-a|--all [--verbose]] [-g|--guide] [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE] DESCRIPTION
@@ -42,6 +42,8 @@ OPTIONS --all:: Prints all the available commands on the standard output. This option overrides any given command or guide name. + When used with `--verbose` print description for all recognized + commands. -g:: --guides::
builtin/help.c +7 -0
@@ -36,6 +36,7 @@ static const char *html_path;static int show_all =0 ;static int show_guides =0 ; +static int verbose;static unsigned int colopts;static enum help_format help_format =HELP_FORMAT_NONE ;static int exclude_guides;
@@ -48,6 +49,7 @@ static struct option builtin_help_options[] = { HELP_FORMAT_WEB),OPT_SET_INT ('i' ,"info" , &help_format,N_ ("show info page" ),HELP_FORMAT_INFO ), +OPT__VERBOSE (&verbose,N_ ("print command description" )), OPT_END(), };
@@ -463,6 +465,11 @@ int cmd_help(int argc, const char **argv, const char *prefix)if (show_all) {git_config (git_help_config,NULL ); +if (verbose) { +setup_pager (); +list_all_cmds_help (); +return 0 ; + }printf (_ ("usage: %s%s" ),_ (git_usage_string),"\n\n" );load_command_list ("git-" , &main_cmds, &other_cmds);list_commands (colopts, &main_cmds, &other_cmds);
help.c +16 -0
@@ -27,6 +27,17 @@ static struct category_description common_categories[] = { { CAT_remote, N_("collaborate (see also: git help workflows)") }, { 0, NULL } }; +static struct category_description main_categories[] = { + { CAT_mainporcelain,N_ ("Main Porcelain Commands" ) }, + { CAT_ancillarymanipulators,N_ ("Ancillary Commands / Manipulators" ) }, + { CAT_ancillaryinterrogators,N_ ("Ancillary Commands / Interrogators" ) }, + { CAT_foreignscminterface,N_ ("Interacting with Others" ) }, + { CAT_plumbingmanipulators,N_ ("Low-level Commands / Manipulators" ) }, + { CAT_plumbinginterrogators,N_ ("Low-level Commands / Interrogators" ) }, + { CAT_synchingrepositories,N_ ("Low-level Commands / Synching Repositories" ) }, + { CAT_purehelpers,N_ ("Low-level Commands / Internal Helpers" ) }, + {0 ,NULL } +};static const char *drop_prefix (const char *name) {
@@ -352,6 +363,11 @@ void list_cmds_by_category(struct string_list *list, } } +void list_all_cmds_help (void ) +{ +print_cmd_by_category (main_categories); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +2 -0
@@ -19,6 +19,8 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds_help (void ); +extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list); extern void list_cmds_by_category(struct string_list *list,
t/t0012-help.sh +9 -0
@@ -25,6 +25,15 @@ test_expect_success "setup" ' EOF ' +# make sure to exercise these code paths, the output is a bit tricky +# to verify +test_expect_success 'basic help commands' ' + git help >/dev/null && + git help -a >/dev/null && + git help -g >/dev/null && + git help -av >/dev/null +' + test_expect_success "works for commands and guides by default" ' configure_help && git help status &&
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 10/17 help: use command-list.txt for the source of guides
In reply to Nguyễn Thái Ngọc DuyThe help command currently hard codes the list of guides and their summary in C. Let's move this list to command-list.txt. This lets us extract summary lines from Documentation/git*.txt. This also potentially lets us list guides in git.txt, but I'll leave that for now.
--- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- Makefile | 2 +- builtin/help.c | 32 -------------------------- command-list.txt | 16 +++++++++++++ contrib/completion/git-completion.bash | 15 ++++++++---- help.c | 21 +++++++++++++---- help.h | 1 + t/t0012-help.sh | 6 +++++ 10 files changed, 54 insertions(+), 45 deletions(-)
Documentation/gitattributes.txt +1 -1
@@ -3,7 +3,7 @@ gitattributes(5) NAME ---- -gitattributes - defining attributes per path +gitattributes - Defining attributes per path SYNOPSIS --------
Documentation/gitmodules.txt +1 -1
@@ -3,7 +3,7 @@ gitmodules(5) NAME ---- -gitmodules - defining submodule properties +gitmodules - Defining submodule properties SYNOPSIS --------
Documentation/gitrevisions.txt +1 -1
@@ -3,7 +3,7 @@ gitrevisions(7) NAME ---- -gitrevisions - specifying revisions and ranges for Git +gitrevisions - Specifying revisions and ranges for Git SYNOPSIS --------
Makefile +1 -1
@@ -1937,7 +1937,7 @@ $(BUILT_INS): git$X command-list.h: generate-cmdlist.sh command-list.txt -command-list.h: $(wildcard Documentation/git-*.txt) +command-list.h: $(wildcard Documentation/git*.txt) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
builtin/help.c +0 -32
@@ -402,38 +402,6 @@ static void show_html_page(const char *git_cmd)open_html (page_path.buf); } -static struct { -const char *name; -const char *help; -} common_guides[] = { - {"attributes" ,N_ ("Defining attributes per path" ) }, - {"everyday" ,N_ ("Everyday Git With 20 Commands Or So" ) }, - {"glossary" ,N_ ("A Git glossary" ) }, - {"ignore" ,N_ ("Specifies intentionally untracked files to ignore" ) }, - {"modules" ,N_ ("Defining submodule properties" ) }, - {"revisions" ,N_ ("Specifying revisions and ranges for Git" ) }, - {"tutorial" ,N_ ("A tutorial introduction to Git (for version 1.5.1 or newer)" ) }, - {"workflows" ,N_ ("An overview of recommended workflows with Git" ) }, -}; - -static void list_common_guides_help (void ) -{ -int i, longest =0 ; - -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -if (longest <strlen (common_guides[i].name)) - longest =strlen (common_guides[i].name); - } - -puts (_ ("The common Git guides are:\n" )); -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -printf (" %s " , common_guides[i].name); -mput_char (' ' , longest -strlen (common_guides[i].name)); -puts (_ (common_guides[i].help)); - } -putchar ('\n' ); -} -static const char *check_git_cmd (const char * cmd) {char *alias;
command-list.txt +16 -0
@@ -139,3 +139,19 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +gitcli guide +gitcore-tutorial guide +gitcvs-migration guide +gitdiffcore guide +giteveryday guide +gitglossary guide +githooks guide +gitignore guide +gitmodules guide +gitnamespaces guide +gitrepository-layout guide +gitrevisions guide +gittutorial-2 guide +gittutorial guide +gitworkflows guide
contrib/completion/git-completion.bash +10 -5
@@ -1575,6 +1575,13 @@ _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
@@ -1584,11 +1591,9 @@ _git_help () ;; esac __git_compute_all_commands - __gitcomp "$__git_all_commands $(__git_aliases) - attributes cli core-tutorial cvs-migration - diffcore everyday gitk glossary hooks ignore modules - namespaces repository-layout revisions tutorial tutorial-2 - workflows + __git_compute_all_guides + __gitcomp "$__git_all_commands $(__git_aliases) $__git_all_guides + gitk " }
help.c +17 -4
@@ -39,12 +39,14 @@ static struct category_description main_categories[] = { { 0, NULL } }; -static const char *drop_prefix (const char *name) +static const char *drop_prefix (const char *name,uint32_t category) {const char *new_name;if (skip_prefix (name,"git-" , &new_name))return new_name; +if (category == CAT_guide &&skip_prefix (name,"git" , &new_name)) +return new_name;return name; }
@@ -66,7 +68,7 @@ static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask)continue ; cmds[nr] = *cmd; - cmds[nr].name =drop_prefix (cmd->name); + cmds[nr].name =drop_prefix (cmd->name, cmd->category); nr++; }
@@ -358,11 +360,22 @@ void list_cmds_by_category(struct string_list *list,for (i =0 ; i < n; i++) {struct cmdname_help *cmd = command_list + i; -if (cmd->category & cat_id) -string_list_append (list,drop_prefix (cmd->name)); +if (!(cmd->category & cat_id)) +continue ; +string_list_append (list,drop_prefix (cmd->name, cmd->category)); } } +void list_common_guides_help (void ) +{ +struct category_description catdesc[] = { + { CAT_guide,N_ ("The common Git guides are:" ) }, + {0 ,NULL } + }; +print_cmd_by_category (catdesc); +putchar ('\n' ); +} +void list_all_cmds_help (void ) {print_cmd_by_category (main_categories);
help.h +1 -0
@@ -20,6 +20,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds_help (void ); +extern void list_common_guides_help (void );extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list);
t/t0012-help.sh +6 -0
@@ -66,6 +66,12 @@ test_expect_success 'git help' ' test_i18ngrep "^ commit " help.output && test_i18ngrep "^ fetch " help.output ' +test_expect_success 'git help -g' ' + git help -g >help.output && + test_i18ngrep "^ attributes " help.output && + test_i18ngrep "^ everyday " help.output && + test_i18ngrep "^ tutorial " help.output +' test_expect_success 'generate builtin list' ' git --list-cmds=builtins >builtins
Signature · 1 line
2.17.0.705.g3525833791
Re: [PATCH v2 10/17] help: use command-list.txt for the source of guides
Quoted 245 lines · Nguyễn Thái Ngọc Duy
The help command currently hard codes the list of guides and their summary in C. Let's move this list to command-list.txt. This lets us extract summary lines from
Documentation/git*.txt. This also potentially lets us list guides in git.txt, but I'll leave that for now.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- Makefile | 2 +- builtin/help.c | 32 -------------------------- command-list.txt | 16 +++++++++++++ contrib/completion/git-completion.bash | 15 ++++++++---- help.c | 21 +++++++++++++---- help.h | 1 + t/t0012-help.sh | 6 +++++ 10 files changed, 54 insertions(+), 45 deletions(-)Documentation/gitattributes.txt +1
-1@@ -3,7 +3,7 @@ gitattributes(5) NAME ---- -gitattributes - defining attributes per path +gitattributes - Defining attributes per path SYNOPSIS --------Documentation/gitmodules.txt +1
-1@@ -3,7 +3,7 @@ gitmodules(5) NAME ---- -gitmodules - defining submodule properties +gitmodules - Defining submodule properties SYNOPSIS --------Documentation/gitrevisions.txt +1
-1@@ -3,7 +3,7 @@ gitrevisions(7) NAME ---- -gitrevisions - specifying revisions and ranges for Git +gitrevisions - Specifying revisions and ranges for Git SYNOPSIS --------Makefile +1
-1@@ -1937,7 +1937,7 @@ $(BUILT_INS): git$X command-list.h: generate-cmdlist.sh command-list.txt -command-list.h: $(wildcard Documentation/git-*.txt) +command-list.h: $(wildcard Documentation/git*.txt) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\builtin/help.c +0
-32@@ -402,38 +402,6 @@ static void show_html_page(const char *git_cmd)open_html (page_path.buf); } -static struct { -const char *name; -const char *help; -} common_guides[] = { - {"attributes" ,N_ ("Defining attributes per path" ) }, - {"everyday" ,N_ ("Everyday Git With 20 Commands Or So" ) }, - {"glossary" ,N_ ("A Git glossary" ) }, - {"ignore" ,N_ ("Specifies intentionally untracked files to ignore" ) }, - {"modules" ,N_ ("Defining submodule properties" ) }, - {"revisions" ,N_ ("Specifying revisions and ranges for Git" ) }, - {"tutorial" ,N_ ("A tutorial introduction to Git (for version 1.5.1 or newer)" ) }, - {"workflows" ,N_ ("An overview of recommended workflows with Git" ) }, -}; - -static void list_common_guides_help (void ) -{ -int i, longest =0 ; - -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -if (longest <strlen (common_guides[i].name)) - longest =strlen (common_guides[i].name); - } - -puts (_ ("The common Git guides are:\n" )); -for (i =0 ; i <ARRAY_SIZE (common_guides); i++) { -printf (" %s " , common_guides[i].name); -mput_char (' ' , longest -strlen (common_guides[i].name)); -puts (_ (common_guides[i].help)); - } -putchar ('\n' ); -} -static const char *check_git_cmd (const char * cmd) {char *alias;command-list.txt +16
-0@@ -139,3 +139,19 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +gitcli guide +gitcore-tutorial guide +gitcvs-migration guide +gitdiffcore guide +giteveryday guide +gitglossary guide +githooks guide +gitignore guide +gitmodules guide +gitnamespaces guide +gitrepository-layout guide +gitrevisions guide +gittutorial-2 guide +gittutorial guide +gitworkflows guidecontrib/completion/git-completion.bash +10
-5@@ -1575,6 +1575,13 @@ _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@@ -1584,11 +1591,9 @@ _git_help () ;; esac __git_compute_all_commands - __gitcomp "$__git_all_commands $(__git_aliases) - attributes cli core-tutorial cvs-migration - diffcore everyday gitk glossary hooks ignore modules - namespaces repository-layout revisions tutorial tutorial-2 - workflows + __git_compute_all_guides + __gitcomp "$__git_all_commands $(__git_aliases) $__git_all_guides + gitk " }help.c +17
-4@@ -39,12 +39,14 @@ static struct category_description main_categories[] = { { 0, NULL } }; -static const char *drop_prefix (const char *name) +static const char *drop_prefix (const char *name,uint32_t category) {const char *new_name;if (skip_prefix (name,"git-" , &new_name))return new_name; +if (category == CAT_guide &&skip_prefix (name,"git" , &new_name)) +return new_name;return name; }@@ -66,7 +68,7 @@ static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask)continue ; cmds[nr] = *cmd; - cmds[nr].name =drop_prefix (cmd->name); + cmds[nr].name =drop_prefix (cmd->name, cmd->category); nr++; }@@ -358,11 +360,22 @@ void list_cmds_by_category(struct string_list *list,for (i =0 ; i < n; i++) {struct cmdname_help *cmd = command_list + i; -if (cmd->category & cat_id) -string_list_append (list,drop_prefix (cmd->name)); +if (!(cmd->category & cat_id)) +continue ; +string_list_append (list,drop_prefix (cmd->name, cmd->category)); } } +void list_common_guides_help (void ) +{ +struct category_description catdesc[] = { + { CAT_guide,N_ ("The common Git guides are:" ) }, + {0 ,NULL } + }; +print_cmd_by_category (catdesc); +putchar ('\n' ); +} +void list_all_cmds_help (void ) {print_cmd_by_category (main_categories);help.h +1
-0@@ -20,6 +20,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds_help (void ); +extern void list_common_guides_help (void );extern void list_all_main_cmds (struct string_list *list);extern void list_all_other_cmds (struct string_list *list);t/t0012-help.sh +0
-0@@ -66,6 +66,12 @@ test_expect_success 'git help' ' test_i18ngrep "^ commit " help.output && test_i18ngrep "^ fetch " help.output
t/t0012-help.sh test_expect_success 'git help' ' · line 77
Quoted 10 lines
t/t0012-help.sh +6
-0' +test_expect_success 'git help -g' ' + git help -g >help.output && + test_i18ngrep "^ attributes " help.output && + test_i18ngrep "^ everyday " help.output && + test_i18ngrep "^ tutorial " help.output +' test_expect_success 'generate builtin list' ' git --list-cmds=builtins >builtins
On a branch I branched off current master (bb75be6cb9) I was consistently getting failures on this test:
expecting success:
git help -g >help.output &&
test_i18ngrep "^ attributes " help.output &&
test_i18ngrep "^ everyday " help.output &&
test_i18ngrep "^ tutorial " help.output
attributes Defining attributes per path
everyday A useful minimum set of commands for Everyday Git
error: 'grep ^ tutorial help.output' didn't find a match in:
The common Git guides are:
attributes Defining attributes per path
cli Git command-line interface and conventions
core-tutorial A Git core tutorial for developers
cvs-migration Git for CVS users
diffcore Tweaking diff output
everyday A useful minimum set of commands for Everyday Git
glossary A Git Glossary
hooks Hooks used by Git
ignore Specifies intentionally untracked files to ignore
modules Defining submodule properties
'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept.
not ok 7 - git help -g
#
# git help -g >help.output &&
# test_i18ngrep "^ attributes " help.output &&
# test_i18ngrep "^ everyday " help.output &&
# test_i18ngrep "^ tutorial " help.output
#
This was after running "make all doc". The issue went away when I ran 'git clean -dxf' and I haven't been able to reproduce it again. Just wanted to leave a note in case anyone else runs into this heisenbug, perhaps there's some missing dependency in the command-list.h generation logic.
PATCH v2 11/17 command-list.txt: documentation and guide line
In reply to Nguyễn Thái Ngọc DuyThis is intended to help anybody who needs to update command-list.txt. It gives a brief introduction of all attributes a command can take.
--- command-list.txt | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
command-list.txt +45 -0
@@ -1,3 +1,48 @@ +# Command classification list +# --------------------------- +# All supported commands, builtin or external, must be described in +# here. This info is used to list commands in various places. Each +# command is on one line followed by one or more attributes. +# +# The first attribute group is mandatory and indicates the command +# type. This group includes: +# +# mainporcelain +# ancillarymanipulators +# ancillaryinterrogators +# foreignscminterface +# plumbingmanipulators +# plumbinginterrogators +# synchingrepositories +# synchelpers +# purehelpers +# +# The type names are self explanatory. But if you want to see what +# command belongs to what group to get a better picture, have a look +# at "git" man page, "GIT COMMANDS" section. +# +# Commands of type mainporcelain can also optionally have one of these +# attributes: +# +# init +# worktree +# info +# history +# remote +# +# These commands are considered "common" and will show up in "git +# help" output in groups. Uncommon porcelain commands must not +# specify any of these attributes. +# +# "complete" attribute is used to mark that the command should be +# completable by git-completion.bash. Note that by default, +# mainporcelain commands are completable so you don't need this +# attribute. +# +# As part of the Git man page list, the man(5/7) guides are also +# specified here, which can only have "guide" attribute and nothing +# else. +# ### command list (do not change this line, also do not change alignment) # command name category [category] [category] git-add mainporcelain worktree
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 12/17 completion: let git provide the completable command list
In reply to Nguyễn Thái Ngọc DuyInstead of maintaining a separate list of command classification, which often could go out of date, let's centralize the information back in git.
While the function in git-completion.bash implies "list porcelain commands", that's not exactly what it does. It gets all commands (aka --list-cmds=main,others) then exclude certain non-porcelain ones. We could almost recreate this list two lists list-mainporcelain and others. The non-porcelain-but-included-anyway is added by the third category list-complete.
Note that the current completion script incorrectly classifies filter-branch as porcelain and t9902 tests this behavior. We keep it this way in t9902 because this test does not really care which particular command is porcelain or plumbing, they're just names.
--- command-list.txt | 53 +++++------ contrib/completion/git-completion.bash | 119 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 58 insertions(+), 119 deletions(-)
command-list.txt +27 -26
@@ -47,12 +47,12 @@ # command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain -git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +git-annotate ancillaryinterrogators complete +git-apply plumbingmanipulators complete git-archimport foreignscminterface git-archive mainporcelain git-bisect mainporcelain info -git-blame ancillaryinterrogators +git-blame ancillaryinterrogators complete git-branch mainporcelain history git-bundle mainporcelain git-cat-file plumbinginterrogators
@@ -62,7 +62,7 @@ git-check-mailmap purehelpers git-checkout mainporcelain history git-checkout-index plumbingmanipulators git-check-ref-format purehelpers -git-cherry ancillaryinterrogators +git-cherry ancillaryinterrogators complete git-cherry-pick mainporcelain git-citool mainporcelain git-clean mainporcelain
@@ -70,7 +70,7 @@ git-clone mainporcelain init git-column purehelpers git-commit mainporcelain history git-commit-tree plumbingmanipulators -git-config ancillarymanipulators +git-config ancillarymanipulators complete git-count-objects ancillaryinterrogators git-credential purehelpers git-credential-cache purehelpers
@@ -84,30 +84,30 @@ git-diff mainporcelain history git-diff-files plumbinginterrogators git-diff-index plumbinginterrogators git-diff-tree plumbinginterrogators -git-difftool ancillaryinterrogators +git-difftool ancillaryinterrogators complete git-fast-export ancillarymanipulators git-fast-import ancillarymanipulators git-fetch mainporcelain remote git-fetch-pack synchingrepositories -git-filter-branch ancillarymanipulators +git-filter-branch ancillarymanipulators complete git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain -git-fsck ancillaryinterrogators +git-fsck ancillaryinterrogators complete git-gc mainporcelain -git-get-tar-commit-id ancillaryinterrogators +git-get-tar-commit-id ancillaryinterrogators complete git-grep mainporcelain info git-gui mainporcelain git-hash-object plumbingmanipulators -git-help ancillaryinterrogators +git-help ancillaryinterrogators complete git-http-backend synchingrepositories git-http-fetch synchelpers git-http-push synchelpers -git-imap-send foreignscminterface +git-imap-send foreignscminterface complete git-index-pack plumbingmanipulators git-init mainporcelain init -git-instaweb ancillaryinterrogators -git-interpret-trailers purehelpers +git-instaweb ancillaryinterrogators complete +git-interpret-trailers purehelpers complete gitk mainporcelain git-log mainporcelain info git-ls-files plumbinginterrogators
@@ -120,14 +120,14 @@ git-merge-base plumbinginterrogators git-merge-file plumbingmanipulators git-merge-index plumbingmanipulators git-merge-one-file purehelpers -git-mergetool ancillarymanipulators +git-mergetool ancillarymanipulators complete git-merge-tree ancillaryinterrogators git-mktag plumbingmanipulators git-mktree plumbingmanipulators git-mv mainporcelain worktree -git-name-rev plumbinginterrogators +git-name-rev plumbinginterrogators complete git-notes mainporcelain -git-p4 foreignscminterface +git-p4 foreignscminterface complete git-pack-objects plumbingmanipulators git-pack-redundant plumbinginterrogators git-pack-refs ancillarymanipulators
@@ -141,32 +141,33 @@ git-quiltimport foreignscminterface git-read-tree plumbingmanipulators git-rebase mainporcelain history git-receive-pack synchelpers -git-reflog ancillarymanipulators -git-remote ancillarymanipulators -git-repack ancillarymanipulators -git-replace ancillarymanipulators -git-request-pull foreignscminterface +git-reflog ancillarymanipulators complete +git-remote ancillarymanipulators complete +git-repack ancillarymanipulators complete +git-replace ancillarymanipulators complete +git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain worktree git-revert mainporcelain git-rev-list plumbinginterrogators git-rev-parse ancillaryinterrogators git-rm mainporcelain worktree -git-send-email foreignscminterface +git-send-email foreignscminterface complete git-send-pack synchingrepositories git-shell synchelpers git-shortlog mainporcelain git-show mainporcelain info -git-show-branch ancillaryinterrogators +git-show-branch ancillaryinterrogators complete git-show-index plumbinginterrogators git-show-ref plumbinginterrogators git-sh-i18n purehelpers git-sh-setup purehelpers git-stash mainporcelain +git-stage complete git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain -git-svn foreignscminterface +git-svn foreignscminterface complete git-symbolic-ref plumbingmanipulators git-tag mainporcelain history git-unpack-file plumbinginterrogators
@@ -177,11 +178,11 @@ git-update-server-info synchingrepositories git-upload-archive synchelpers git-upload-pack synchelpers git-var plumbinginterrogators -git-verify-commit ancillaryinterrogators +git-verify-commit ancillaryinterrogators complete git-verify-pack plumbinginterrogators git-verify-tag ancillaryinterrogators gitweb ancillaryinterrogators -git-whatchanged ancillaryinterrogators +git-whatchanged ancillaryinterrogators complete git-worktree mainporcelain git-write-tree plumbingmanipulators gitattributes guide
contrib/completion/git-completion.bash +28 -91
142 lines not on this page · raw message
t/t9902-completion.sh +3 -2
@@ -13,7 +13,7 @@ complete () return 0 } -# Be careful when updating this list: +# Be careful when updating these lists: # # (1) The build tree may have build artifact from different branch, or # the user's $PATH may have a random executable that may begin
@@ -30,7 +30,8 @@ complete () # completion for "git <TAB>", and a plumbing is excluded. "add", # "filter-branch" and "ls-files" are listed for this. -GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files' +GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files' +GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch' . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 13/17 completion: reduce completable command list
In reply to Nguyễn Thái Ngọc DuyThe following commands are removed from the complete list:
- annotate obsolete, discouraged to use - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - name-rev plumbing, just use git-describe - p4 too short and probably not often used (*) - svn same category as p4 (*) - verify-commit not often used
(*) to be fair, send-email command which is in the same foreignscminterface group as svn and p4 does get completion, just because it's used by git and kernel development. So maybe we should include them.
--- command-list.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
command-list.txt +9 -9
@@ -47,7 +47,7 @@ # command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain -git-annotate ancillaryinterrogators complete +git-annotate ancillaryinterrogators git-apply plumbingmanipulators complete git-archimport foreignscminterface git-archive mainporcelain
@@ -89,13 +89,13 @@ git-fast-export ancillarymanipulators git-fast-import ancillarymanipulators git-fetch mainporcelain remote git-fetch-pack synchingrepositories -git-filter-branch ancillarymanipulators complete +git-filter-branch ancillarymanipulators git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain git-fsck ancillaryinterrogators complete git-gc mainporcelain -git-get-tar-commit-id ancillaryinterrogators complete +git-get-tar-commit-id ancillaryinterrogators git-grep mainporcelain info git-gui mainporcelain git-hash-object plumbingmanipulators
@@ -103,11 +103,11 @@ git-help ancillaryinterrogators complete git-http-backend synchingrepositories git-http-fetch synchelpers git-http-push synchelpers -git-imap-send foreignscminterface complete +git-imap-send foreignscminterface git-index-pack plumbingmanipulators git-init mainporcelain init git-instaweb ancillaryinterrogators complete -git-interpret-trailers purehelpers complete +git-interpret-trailers purehelpers gitk mainporcelain git-log mainporcelain info git-ls-files plumbinginterrogators
@@ -125,9 +125,9 @@ git-merge-tree ancillaryinterrogators git-mktag plumbingmanipulators git-mktree plumbingmanipulators git-mv mainporcelain worktree -git-name-rev plumbinginterrogators complete +git-name-rev plumbinginterrogators git-notes mainporcelain -git-p4 foreignscminterface complete +git-p4 foreignscminterface git-pack-objects plumbingmanipulators git-pack-redundant plumbinginterrogators git-pack-refs ancillarymanipulators
@@ -167,7 +167,7 @@ git-stage complete git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain -git-svn foreignscminterface complete +git-svn foreignscminterface git-symbolic-ref plumbingmanipulators git-tag mainporcelain history git-unpack-file plumbinginterrogators
@@ -178,7 +178,7 @@ git-update-server-info synchingrepositories git-upload-archive synchelpers git-upload-pack synchelpers git-var plumbinginterrogators -git-verify-commit ancillaryinterrogators complete +git-verify-commit ancillaryinterrogators git-verify-pack plumbinginterrogators git-verify-tag ancillaryinterrogators gitweb ancillaryinterrogators
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 14/17 Move declaration for alias.c to alias.h
In reply to Nguyễn Thái Ngọc Duy--- alias.c | 1 + alias.h | 9 +++++++++ builtin/help.c | 1 + builtin/merge.c | 1 + cache.h | 5 ----- connect.c | 1 + git.c | 1 + pager.c | 1 + sequencer.c | 1 + shell.c | 1 + 10 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 alias.h
alias.c +1 -0
@@ -1,4 +1,5 @@#include "cache.h" +#include "alias.h" #include "config.h" struct config_alias_data {
alias.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef __ALIAS_H__ +#define __ALIAS_H__ + +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); + +#endif
builtin/help.c +1 -0
@@ -9,6 +9,7 @@#include "run-command.h" #include "column.h" #include "help.h" +#include "alias.h" #ifndef DEFAULT_HELP_FORMAT #define DEFAULT_HELP_FORMAT "man"
builtin/merge.c +1 -0
@@ -34,6 +34,7 @@#include "string-list.h" #include "packfile.h" #include "tag.h" +#include "alias.h" #define DEFAULT_TWOHEAD (1<<0)#define DEFAULT_OCTOPUS (1<<1)
cache.h +0 -5
@@ -1835,11 +1835,6 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);void overlay_tree_on_index (struct index_state *istate,const char *tree_name,const char *prefix); -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); -/* setup.c */ struct startup_info {int have_repository;
connect.c +1 -0
@@ -13,6 +13,7 @@#include "transport.h" #include "strbuf.h" #include "protocol.h" +#include "alias.h" static char *server_capabilities;static const char *parse_feature_value (const char *,const char *,int *);
git.c +1 -0
@@ -3,6 +3,7 @@#include "exec_cmd.h" #include "help.h" #include "run-command.h" +#include "alias.h" #define RUN_SETUP (1<<0)#define RUN_SETUP_GENTLY (1<<1)
pager.c +1 -0
@@ -2,6 +2,7 @@#include "config.h" #include "run-command.h" #include "sigchain.h" +#include "alias.h" #ifndef DEFAULT_PAGER #define DEFAULT_PAGER "less"
sequencer.c +1 -0
@@ -23,6 +23,7 @@#include "hashmap.h" #include "notes-utils.h" #include "sigchain.h" +#include "alias.h" #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
shell.c +1 -0
@@ -3,6 +3,7 @@#include "exec_cmd.h" #include "strbuf.h" #include "run-command.h" +#include "alias.h" #define COMMAND_DIR "git-shell-commands"#define HELP_COMMAND COMMAND_DIR "/help"
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 15/17 completion: add and use --list-cmds=nohelpers
In reply to Nguyễn Thái Ngọc Duy--- Documentation/git.txt | 3 ++- contrib/completion/git-completion.bash | 20 ++++---------------- git.c | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 17 deletions(-)
Documentation/git.txt +2 -1
@@ -169,7 +169,8 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config groups are: builtins, parseopt (builtin commands that use 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) + list-<category> (see categories in command-list.txt), + nohelpers (exclude helper commands). GIT COMMANDS ------------
contrib/completion/git-completion.bash +4 -16
@@ -843,7 +843,7 @@ __git_commands () { then printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" else - git --list-cmds=list-mainporcelain,others,list-complete + git --list-cmds=list-mainporcelain,others,nohelpers,list-complete fi ;; all)
@@ -851,27 +851,15 @@ __git_commands () { then printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST" else - git --list-cmds=main,others + git --list-cmds=main,others,nohelpers fi ;; esac } -__git_list_commands () -{ - local i IFS=" "$'\n' - for i in $(__git_commands $1) - do - case $i in - *--*) : helper pattern;; - *) echo $i;; - esac - done -} - __git_list_all_commands () { - __git_list_commands all + __git_commands all } __git_all_commands=
@@ -883,7 +871,7 @@ __git_compute_all_commands () __git_list_porcelain_commands () { - __git_list_commands porcelain + __git_commands porcelain } __git_porcelain_commands=
git.c +14 -0
@@ -39,6 +39,18 @@ static int use_pager = -1;static void list_builtins (struct string_list *list,unsigned int exclude_option); +static void exclude_helpers_from_list (struct string_list *list) +{ +int i =0 ; + +while (i < list->nr) { +if (strstr (list->items[i].string,"--" )) +unsorted_string_list_delete_item (list, i,0 ); +else + i++; + } +} +static int match_token (const char *spec,int len,const char *token) {int token_len =strlen (token);
@@ -61,6 +73,8 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (match_token(spec, len, "others")) list_all_other_cmds(&list); + else if (match_token(spec, len, "nohelpers")) + exclude_helpers_from_list(&list); else if (len > 5 && !strncmp(spec, "list-", 5)) {struct strbuf sb =STRBUF_INIT ;
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 16/17 completion: add and use --list-cmds=alias
In reply to Nguyễn Thái Ngọc DuyBy 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.
--- Documentation/git.txt | 2 +- alias.c | 21 +++++++- alias.h | 3 ++ contrib/completion/git-completion.bash | 75 ++++++-------------------- git.c | 2 + t/t9902-completion.sh | 18 ------- 6 files changed, 40 insertions(+), 81 deletions(-)
Documentation/git.txt +1 -1
@@ -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 ------------
alias.c +19 -2
@@ -1,10 +1,12 @@#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)
@@ -12,8 +14,16 @@ 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 ; }
@@ -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 2static const char *split_cmdline_errors[] = {
alias.h +3 -0
@@ -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
contrib/completion/git-completion.bash +15 -60
109 lines not on this page · raw message
git.c +2 -0
@@ -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 ;
t/t9902-completion.sh +0 -18
@@ -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
@@ -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" &&
Signature · 1 line
2.17.0.705.g3525833791
PATCH v2 17/17 completion: allow to customize the completable command list
In reply to Nguyễn Thái Ngọc DuyBy default we show porcelain, external commands and a couple others that are also popular. If you are not happy with this list, you can now customize it a new config variable.
--- Documentation/config.txt | 8 +++++++ Documentation/git.txt | 3 ++- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 33 ++++++++++++++++++++++++++ help.h | 1 + 6 files changed, 47 insertions(+), 2 deletions(-)
Documentation/config.txt +8 -0
@@ -1343,6 +1343,14 @@ credential.<url>.*:: credentialCache.ignoreSIGHUP:: Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting. +completion.commands:: + This is only used by git-completion.bash to add or remove + commands from the list of completed commands. Normally only + porcelain commands and a few select others are completed. You + can add more commands, separated by space, in this + variable. Prefixing the command with '-' will remove it from + the existing list. + include::diff-config.txt[] difftool.<tool>.path::
Documentation/git.txt +2 -1
@@ -170,7 +170,8 @@ 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) and alias. + nohelpers (exclude helper commands), alias and config + (retrieve command list from config variable completion.commands) GIT COMMANDS ------------
contrib/completion/git-completion.bash +1 -1
@@ -3012,7 +3012,7 @@ __git_main () then __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST" else - __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete)" + __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" fi ;; esac
git.c +2 -0
@@ -77,6 +77,8 @@ static int list_cmds(const char *spec)exclude_helpers_from_list (&list); else if (match_token(spec, len, "alias")) list_aliases(&list); + else if (match_token(spec, len, "config")) + list_cmds_by_config(&list); else if (len > 5 && !strncmp(spec, "list-", 5)) {struct strbuf sb =STRBUF_INIT ;
help.c +33 -0
@@ -366,6 +366,39 @@ void list_cmds_by_category(struct string_list *list, } } +void list_cmds_by_config (struct string_list *list) +{ +const char *cmd_list; + +/* +* There's no actual repository setup at this point (and even +* if there is, we don't really care; only global config +* matters). If we accidentally set up a repository, it's ok +* too since the caller (git --list-cmds=) should exit shortly +* anyway. +*/ +if (git_config_get_string_const ("completion.commands" , &cmd_list)) +return ; + +string_list_sort (list); +string_list_remove_duplicates (list,0 ); + +while (*cmd_list) { +struct strbuf sb =STRBUF_INIT ; +const char *p =strchrnul (cmd_list,' ' ); + +strbuf_add (&sb, cmd_list, p - cmd_list); +if (*cmd_list =='-' ) +string_list_remove (list, cmd_list +1 ,0 ); +else +string_list_insert (list, sb.buf); +strbuf_release (&sb); +while (*p ==' ' ) + p++; + cmd_list = p; + } +} +void list_common_guides_help (void ) {struct category_description catdesc[] = {
help.h +1 -0
@@ -26,6 +26,7 @@ extern void list_all_main_cmds(struct string_list *list);extern void list_all_other_cmds (struct string_list *list);extern void list_cmds_by_category (struct string_list *list,const char *category); +extern void list_cmds_by_config (struct string_list *list);extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
Signature · 1 line
2.17.0.705.g3525833791