Keep all info in command-list.txt in git binary
Subsystems (2)
cover Keep all info in command-list.txt in git binary
This is pretty rough but I'd like to see how people feel about this first.
I notice we have two places for command classification. One in command-list.txt, one in __git_list_porcelain_commands() in git-completion.bash. People who are following nd/parseopt-completion probably know that I'm try to reduce duplication in this script as much as possible, this is another step towards that.
By keeping all information of command-list.txt in git binary, we could provide the porcelain list to git-completion.bash via "git --list-cmds=porcelain", so we don't neeed a separate command classification in git-completion.bash anymore.
Because we have all command synopsis as a side effect, we could now support "git help -a --verbose" which prints something like "git help", a command name and a description, but we could do it for _all_ recognized commands. This could help people look for a command even if we don't provide "git appropos".
PS. Elsewhere I introduced --list-builtin-cmds, which should become --list-cmds=builtin if this series seems like a good idea to move forward.
Nguyễn Thái Ngọc Duy (5):
git.c: convert --list-builtins to --list-cmds=builtins git.c: implement --list-cmds=all and use it in git-completion.bash generate-cmdlist.sh: keep all information in common-cmds.h git.c: implement --list-cmds=porcelain
help: add "-a --verbose" to list all commands with synopsis
Documentation/git-help.txt | 4 +- builtin/help.c | 6 ++ contrib/completion/git-completion.bash | 94 +----------------- generate-cmdlist.sh | 46 ++++++--- git.c | 11 ++- help.c | 131 +++++++++++++++++++++++-- help.h | 3 + t/t0012-help.sh | 2 +- t/t9902-completion.sh | 4 +- 9 files changed, 187 insertions(+), 114 deletions(-)
Signature · 1 line
2.17.0.rc0.348.gd5a49e0b6f
PATCH 1/5 git.c: convert --list-builtins to --list-cmds=builtins
Even if this is a hidden option, let's make it a bit more generic since we're introducing more listing types.
--- git.c | 7 +++++-- t/t0012-help.sh | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-)
git.c +5 -2
@@ -205,8 +205,11 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) } (*argv)++; (*argc)--; - }else if (!strcmp (cmd,"--list-builtins" )) { -list_builtins (); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"builtins" )) +list_builtins (); +else +die ("unsupported command listing type '%s'" , cmd);exit (0 ); }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);
t/t0012-help.sh +1 -1
@@ -50,7 +50,7 @@ test_expect_success "--help does not work for guides" " " test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.rc0.348.gd5a49e0b6f
PATCH 2/5 git.c: implement --list-cmds=all and use it in git-completion.bash
In reply to Nguyễn Thái Ngọc Duy--- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 15 +++++++++++++++ help.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
@@ -833,7 +833,7 @@ __git_commands () { then printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" else - git help -a|egrep '^ [a-zA-Z0-9]' + git --list-cmds=all fi }
git.c +2 -0
@@ -208,6 +208,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) {if (!strcmp (cmd,"builtins" ))list_builtins (); +else if (!strcmp (cmd,"all" )) +list_all_cmds ();else die ("unsupported command listing type '%s'" , cmd);exit (0 );
help.c +15 -0
@@ -228,6 +228,21 @@ void list_common_cmds_help(void) } } +void list_all_cmds (void ) +{ +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++) +puts (main_cmds.names[i]->name); +for (i =0 ; i < other_cmds.cnt; i++) +puts (other_cmds.names[i]->name); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -17,6 +17,7 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds (void );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.rc0.348.gd5a49e0b6f
Re: [PATCH/RFC 2/5] git.c: implement --list-cmds=all and use it in git-completion.bash
Quoted 7 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
help.c +3
-0@@ -228,6 +228,21 @@ void list_common_cmds_help(void) +void list_all_cmds (void ) +{ +struct cmdnames main_cmds, other_cmds;
help.c void list_common_cmds_help(void) · line 240
Quoted 10 lines
help.c +10
-0+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++) +puts (main_cmds.names[i]->name); +for (i =0 ; i < other_cmds.cnt; i++) +puts (other_cmds.names[i]->name);
clean_cmdnames(&main_cmds);clean_cmdnames(&other_cmds);
Quoted 1 line
help.c +1
-0+}
PATCH 3/5 generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Nguyễn Thái Ngọc Duycommon-cmds.h is used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Update generate-cmdlist.sh to keep all the information. The extra info will be used shortly.
--- generate-cmdlist.sh | 46 ++++++++++++++++++++++++++++++++++----------- help.c | 43 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 17 deletions(-)
generate-cmdlist.sh +35 -11
@@ -2,9 +2,10 @@ echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { - char name[16]; + char name[32]; char help[80]; - unsigned char group; + unsigned int category; + unsigned int group; }; static const char *common_cmd_groups[] = {"
@@ -23,27 +24,50 @@ sed -n ' ' "$1" printf '};\n\n' +echo "#define GROUP_NONE 0xff /* no common group */" +echo "#define GROUP_ 0xff /* no common group */" n=0 -substnum= while read grp do - echo "^git-..*[ ]$grp" - substnum="$substnum${substnum:+;}s/[ ]$grp/$n/" + echo "#define GROUP_$grp $n" n=$(($n+1)) -done <"$grps" >"$match" +done <"$grps" +echo -printf 'static struct cmdname_help common_cmds[] = {\n' -grep -f "$match" "$1" | +echo '/*' +printf 'static const char *cmd_categories[] = {\n' +grep '^git-' "$1" | +awk '{print $2;}' | +sort | +uniq | +while read category; do + printf '\t\"'$category'\",\n' +done +printf '\tNULL\n};\n\n' +echo '*/' + +n=0 +grep '^git-' "$1" | +awk '{print $2;}' | +sort | +uniq | +while read category; do + echo "#define CAT_$category $n" + n=$(($n+1)) +done +echo + +printf 'static struct cmdname_help command_list[] = {\n' +grep "^git-" "$1" | sed 's/^git-//' | sort | -while read cmd tags +while read cmd category 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'},/ + s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", N_("\1"), CAT_'$category', GROUP_'$tags' },/ p }' "Documentation/git-$cmd.txt" done
help.c +37 -6
96 lines not on this page · raw message
Signature · 1 line
2.17.0.rc0.348.gd5a49e0b6f
Re: [PATCH/RFC 3/5] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 19 lines · Nguyễn Thái Ngọc Duy
common-cmds.his used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Updategenerate-cmdlist.shto keep all the information. The extra info will be used shortly.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +3
-2@@ -2,9 +2,10 @@ struct cmdname_help { - char name[16]; + char name[32]; char help[80]; - unsigned char group; + unsigned int category; + unsigned int group; };
generate-cmdlist.sh sed -n ' · line 25
Quoted 2 lines
generate-cmdlist.sh +2
-0@@ -23,27 +24,50 @@ sed -n ' +echo "#define GROUP_NONE 0xff /* no common group */" +echo "#define GROUP_ 0xff /* no common group */"
Meh, this "GROUP_" alias of "GROUP_NONE" isn't so nice.
generate-cmdlist.sh sed -n ' · line 34
Quoted 10 lines
generate-cmdlist.sh +2
-4n=0 -substnum= while read grp do - echo "^git-..*[ ]$grp" - substnum="$substnum${substnum:+;}s/[ ]$grp/$n/" + echo "#define GROUP_$grp $n" n=$(($n+1)) -done <"$grps" >"$match" +done <"$grps"
This patch drops all use of the file $match. Earlier in this script, not seen in the context, are a couple references to $match which ought to be adjusted to take its retirement into account:
match=match$$.tmp
trap "rm -f '$grps' '$match'" 0 1 2 3 15However, I'm concerned that this change may be going in the wrong direction. A line in "### command list" section looks like this:
command-name category [deprecated] [common]
Although we don't currently have any commands marked with tag "deprecated", we very well may have some day. More generally, new optional or required tags may be added in the future. As such, the line format is relatively free-form. Current clients don't even care in what order the tags appears (following 'category') nor how many tags there are. The new code added by this patch, however, is far less flexible and accommodating since it assumes hard-coded columns for the tags (and doesn't even take 'deprecated' into account).
The point of the $match file was to be able to extract only lines which mentioned one of the "common groups", and the point of the 'substnum' transformation was to transform the group name into a group number -- both of these operations were done without caring about the exact column the "common group" tag occupied.
Obviously, one option for addressing this concern would be to change the definition to make the tag columns fixed and non-optional, which would allow the simpler implementation used by this patch. Doing so may require fixing other consumers of command-list.txt (though, I'm pretty sure existing consumers wouldn't be bothered).
(Perl would be an obvious good choice for retaining the current relatively free-form line definition without having to jump through hoops in the shell. Unfortunately, though, a Perl dependency in the build system can be problematic[1].)
generate-cmdlist.sh sed -n ' · line 39
Quoted 5 lines
generate-cmdlist.sh +3
-2-printf 'static struct cmdname_help common_cmds[] = {\n' -grep -f "$match" "$1" | +echo '/*' +printf 'static const char *cmd_categories[] = {\n' +grep '^git-' "$1" |
This "grep '^git-'" (and those below) misses some commands, such as "gitk" and "gitweb". Is that intentional? If not, then you'll probably need to grab lines following "### command list", as is done earlier in the script. Same comment for the other couple grep's later in the patch.
generate-cmdlist.sh sed -n ' · line 35
Quoted 1 line
generate-cmdlist.sh +1
-0+awk '{print $2;}' |
At one time, Junio expressed concerns[2] about having an 'awk' dependency in the build system (in fact, with regards to this same generation process). Whether he still has such concerns is unknown, but it should be easy enough to avoid it here (and below).
Quoted 13 lines
generate-cmdlist.sh +7
-0+sort | +uniq | +while read category; do + printf '\t\"'$category'\",\n' +done +printf '\tNULL\n};\n\n' +echo '*/'help.c +4
-0@@ -190,6 +190,28 @@ void list_commands(unsigned int colopts, +static void extract_common_cmds (struct cmdname_help **p_common_cmds, +int *p_nr) +{ +int i, nr =0 ;
help.c void list_commands(unsigned int colopts, · line 203
Quoted 10 lines
help.c +10
-0+struct cmdname_help *common_cmds; + +ALLOC_ARRAY (common_cmds,ARRAY_SIZE (command_list)); + +for (i =0 ; i <ARRAY_SIZE (command_list); i++) { +const struct cmdname_help *cmd = command_list + i; + +if (cmd->category != CAT_mainporcelain || + cmd->group ==GROUP_NONE ) +continue ;
Is the CAT_mainporcelain condition necessary? Before this patch, the command list would contain only commands with an associated group, so it seems that you could get by just with the GROUP_NONE condition.
Quoted 7 lines
help.c +7
-0+ + common_cmds[nr++] = *cmd; + } + + *p_common_cmds = common_cmds; + *p_nr = nr; +}
Re: [PATCH/RFC 3/5] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 20 lines · Eric Sunshine
However, I'm concerned that this change may be going in the wrong direction. A line in "### command list" section looks like this:
command-name category [deprecated] [common]
Although we don't currently have any commands marked with tag "deprecated", we very well may have some day. More generally, new optional or required tags may be added in the future. As such, the line format is relatively free-form. Current clients don't even care in what order the tags appears (following 'category') nor how many tags there are. The new code added by this patch, however, is far less flexible and accommodating since it assumes hard-coded columns for the tags (and doesn't even take 'deprecated' into account).
The point of the $match file was to be able to extract only lines which mentioned one of the "common groups", and the point of the 'substnum' transformation was to transform the group name into a group number -- both of these operations were done without caring about the exact column the "common group" tag occupied.
Quoted 5 lines
Obviously, one option for addressing this concern would be to change the definition to make the tag columns fixed and non-optional, which would allow the simpler implementation used by this patch. Doing so may require fixing other consumers of command-list.txt (though, I'm pretty sure existing consumers wouldn't be bothered).
I should follow up by saying that, although the current relatively free-form line definition is nice due to its flexibility, considering how infrequently command-list.txt is edited and how much more complex the script is to support that flexibility, changing to a definition in which tags are required and at fixed columns seems like the pragmatic thing to do.
Re: [PATCH/RFC 3/5] generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Eric SunshineQuoted 17 lines · Eric Sunshine
Quoted 15 lines · Nguyễn Thái Ngọc Duy
common-cmds.his used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Updategenerate-cmdlist.shto keep all the information. The extra info will be used shortly.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +1
-2@@ -2,9 +2,10 @@ struct cmdname_help { - char name[16]; + char name[32]; char help[80]; - unsigned char group;
Quoted 8 lines
generate-cmdlist.sh sed -n ' · line 25
Quoted 6 lines
generate-cmdlist.sh +4
-0+ unsigned int category; + unsigned int group; };@@ -23,27 +24,50 @@ sed -n ' +echo "#define GROUP_NONE 0xff /* no common group */" +echo "#define GROUP_ 0xff /* no common group */"Meh, this "
GROUP_" alias of "GROUP_NONE" isn't so nice.
Yeah. I don't want to mess too much with shell script. I wonder if we should instead kill this script and extend Documentation/cmd-list.perl to handle this task too. It would be much nicer to write and maintain the script. The downside is NO_PERL builds will have no commands in "git help".
Signature · 1 line
Duy
Re: [PATCH/RFC 3/5] generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Eric SunshineQuoted 8 lines · Eric Sunshine
Quoted 1 line
+awk '{print $2;}' |
At one time, Junio expressed concerns[2] about having an 'awk' dependency in the build system (in fact, with regards to this same generation process). Whether he still has such concerns is unknown, but it should be easy enough to avoid it here (and below).
I'll stick with awk to avoid too much headache with regular expressions (replacements are welcome though). We do use awk in our test suite so it should be ok (who builds git and runs it without testing?)
Signature · 1 line
Duy
PATCH 4/5 git.c: implement --list-cmds=porcelain
In reply to Nguyễn Thái Ngọc DuyThis is useful for git-completion.bash because it needs this set of commands. Right now we have to maintain a separate command category in there.
--- contrib/completion/git-completion.bash | 94 ++------------------------ git.c | 2 + help.c | 12 ++++ help.h | 1 + t/t9902-completion.sh | 4 +- 5 files changed, 20 insertions(+), 93 deletions(-)
contrib/completion/git-completion.bash +4 -90
@@ -833,14 +833,15 @@ __git_commands () { then printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" else - git --list-cmds=all + git --list-cmds=$1 fi } __git_list_all_commands () { local i IFS=" "$'\n' - for i in $(__git_commands) + local category=${1-all} + for i in $(__git_commands $category) do case $i in *--*) : helper pattern;;
@@ -856,98 +857,11 @@ __git_compute_all_commands () __git_all_commands=$(__git_list_all_commands) } -__git_list_porcelain_commands () -{ - local i IFS=" "$'\n' - __git_compute_all_commands - for i in $__git_all_commands - do - case $i in - *--*) : helper pattern;; - applymbox) : ask gittus;; - applypatch) : ask gittus;; - archimport) : import;; - cat-file) : plumbing;; - check-attr) : plumbing;; - check-ignore) : plumbing;; - check-mailmap) : plumbing;; - check-ref-format) : plumbing;; - checkout-index) : plumbing;; - column) : internal helper;; - commit-tree) : plumbing;; - count-objects) : infrequent;; - credential) : credentials;; - credential-*) : credentials helper;; - cvsexportcommit) : export;; - cvsimport) : import;; - cvsserver) : daemon;; - daemon) : daemon;; - diff-files) : plumbing;; - diff-index) : plumbing;; - diff-tree) : plumbing;; - fast-import) : import;; - fast-export) : export;; - fsck-objects) : plumbing;; - fetch-pack) : plumbing;; - fmt-merge-msg) : plumbing;; - for-each-ref) : plumbing;; - hash-object) : plumbing;; - http-*) : transport;; - index-pack) : plumbing;; - init-db) : deprecated;; - local-fetch) : plumbing;; - ls-files) : plumbing;; - ls-remote) : plumbing;; - ls-tree) : plumbing;; - mailinfo) : plumbing;; - mailsplit) : plumbing;; - merge-*) : plumbing;; - mktree) : plumbing;; - mktag) : plumbing;; - pack-objects) : plumbing;; - pack-redundant) : plumbing;; - pack-refs) : plumbing;; - parse-remote) : plumbing;; - patch-id) : plumbing;; - prune) : plumbing;; - prune-packed) : plumbing;; - quiltimport) : import;; - read-tree) : plumbing;; - receive-pack) : plumbing;; - remote-*) : transport;; - rerere) : plumbing;; - rev-list) : plumbing;; - rev-parse) : plumbing;; - runstatus) : plumbing;; - sh-setup) : internal;; - shell) : daemon;; - show-ref) : plumbing;; - send-pack) : plumbing;; - show-index) : plumbing;; - ssh-*) : transport;; - stripspace) : plumbing;; - symbolic-ref) : plumbing;; - unpack-file) : plumbing;; - unpack-objects) : plumbing;; - update-index) : plumbing;; - update-ref) : plumbing;; - update-server-info) : daemon;; - upload-archive) : plumbing;; - upload-pack) : plumbing;; - write-tree) : plumbing;; - var) : infrequent;; - verify-pack) : infrequent;; - verify-tag) : plumbing;; - *) echo $i;; - esac - done -} - __git_porcelain_commands= __git_compute_porcelain_commands () { test -n "$__git_porcelain_commands" || - __git_porcelain_commands=$(__git_list_porcelain_commands) + __git_porcelain_commands=$(__git_list_all_commands porcelain) } # Lists all set config variables starting with the given section prefix,
git.c +2 -0
@@ -210,6 +210,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (); else if (!strcmp(cmd, "all"))list_all_cmds (); + else if (!strcmp(cmd, "porcelain")) +list_porcelain_cmds (); else die("unsupported command listing type '%s'", cmd);exit (0 );
help.c +12 -0
@@ -270,6 +270,18 @@ void list_all_cmds(void)puts (other_cmds.names[i]->name); } +void list_porcelain_cmds (void ) +{ +int i, nr =ARRAY_SIZE (command_list); +struct cmdname_help *cmds = command_list; + +for (i =0 ; i < nr; i++) { +if (cmds[i].category != CAT_mainporcelain) +continue ; +puts (cmds[i].name); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -18,6 +18,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds (void ); +extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
t/t9902-completion.sh +1 -3
@@ -1208,8 +1208,6 @@ test_expect_success 'basic' ' grep -q "^add \$" out && # script grep -q "^filter-branch \$" out && - # plumbing - ! grep -q "^ls-files \$" out && run_completion "git f" && ! grep -q -v "^f" out
@@ -1272,7 +1270,7 @@ test_expect_success 'general options' ' test_completion "git --no-r" "--no-replace-objects " ' -test_expect_success 'general options plus command' ' +test_expect_failure 'general options plus command' ' test_completion "git --version check" "checkout " && test_completion "git --paginate check" "checkout " && test_completion "git --git-dir=foo check" "checkout " &&
Signature · 1 line
2.17.0.rc0.348.gd5a49e0b6f
PATCH 5/5 help: add "-a --verbose" to list all commands with synopsis
In reply to Nguyễn Thái Ngọc Duy--- Documentation/git-help.txt | 4 ++- builtin/help.c | 6 ++++ help.c | 61 ++++++++++++++++++++++++++++++++++++++ help.h | 1 + 4 files changed, 71 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 +6 -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,10 @@ int cmd_help(int argc, const char **argv, const char *prefix)if (show_all) {git_config (git_help_config,NULL ); +if (verbose) { +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 +61 -0
67 lines not on this page · raw message
help.h +1 -0
@@ -17,6 +17,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_all_cmds (void );extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd);
Signature · 1 line
2.17.0.rc0.348.gd5a49e0b6f
Re: [PATCH/RFC 5/5] help: add "-a --verbose" to list all commands with synopsis
help.c void list_porcelain_cmds(void) · line 290
Quoted 13 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
help.c +9
-0@@ -282,6 +282,67 @@ void list_porcelain_cmds(void) +static const char *get_category_name (unsigned int category) +{ +switch (category) { +case CAT_ancillaryinterrogators:return _ ("Ancillary interrogators" ); +case CAT_ancillarymanipulators:return _ ("Ancillary manipulators" ); +case CAT_foreignscminterface:return _ ("Foreign SCM interface" ); +case CAT_mainporcelain:return _ ("Main porcelain" ); +case CAT_plumbinginterrogators:return _ ("Plumbing interrogators" ); +case CAT_plumbingmanipulators:return _ ("Plumbing interrogators" );
s/interrogators"/manipulators"/
Quoted 6 lines
help.c +6
-0+case CAT_purehelpers:return _ ("Pure helpers" ); +case CAT_synchelpers:return _ ("Sync helpers" ); +case CAT_synchingrepositories:return _ ("Synching repositories" ); +default : +die ("BUG: unknown command category %u" , category); + }
Re: [PATCH/RFC 5/5] help: add "-a --verbose" to list all commands with synopsis
Quoted 24 lines · Eric Sunshine
help.c void list_porcelain_cmds(void) · line 290
Quoted 13 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
help.c +9
-0@@ -282,6 +282,67 @@ void list_porcelain_cmds(void) +static const char *get_category_name (unsigned int category) +{ +switch (category) { +case CAT_ancillaryinterrogators:return _ ("Ancillary interrogators" ); +case CAT_ancillarymanipulators:return _ ("Ancillary manipulators" ); +case CAT_foreignscminterface:return _ ("Foreign SCM interface" ); +case CAT_mainporcelain:return _ ("Main porcelain" ); +case CAT_plumbinginterrogators:return _ ("Plumbing interrogators" ); +case CAT_plumbingmanipulators:return _ ("Plumbing interrogators" );s/interrogators"/manipulators"/
Quoted 6 lines
help.c +6
-0+case CAT_purehelpers:return _ ("Pure helpers" ); +case CAT_synchelpers:return _ ("Sync helpers" ); +case CAT_synchingrepositories:return _ ("Synching repositories" ); +default : +die ("BUG: unknown command category %u" , category); + }
Somehow this screams "an array of strings" at me. Aren't this CAT_things small and dense enum?
Re: [PATCH/RFC 5/5] help: add "-a --verbose" to list all commands with synopsis
Quoted 11 lines · Junio C Hamano
Quoted 10 lines · Eric Sunshine
Quoted 7 lines · Nguyễn Thái Ngọc Duy
help.c +7
-0+switch (category) { +case CAT_ancillaryinterrogators:return _ ("Ancillary interrogators" ); +case CAT_ancillarymanipulators:return _ ("Ancillary manipulators" ); +case CAT_foreignscminterface:return _ ("Foreign SCM interface" ); +case CAT_mainporcelain:return _ ("Main porcelain" ); +case CAT_plumbinginterrogators:return _ ("Plumbing interrogators" ); +case CAT_plumbingmanipulators:return _ ("Plumbing interrogators" );
Quoted 8 lines
Quoted 5 lines
s/interrogators"/manipulators"/
Quoted 3 lines
help.c +3
-0+case CAT_purehelpers:return _ ("Pure helpers" ); +case CAT_synchelpers:return _ ("Sync helpers" ); +case CAT_synchingrepositories:return _ ("Synching repositories" );Somehow this screams "an array of strings" at me. Aren't this
CAT_thingssmall and dense enum?
Duy's modified generate-cmdlist.sh does actually output an array of strings for these, but the (generated) array is commented out in this RFC. I suppose the reason it's not presently used is because the array looks like this:
static const char *cmd_categories[] = {
"ancillaryinterrogators",
"ancillarymanipulators",
"foreignscminterface",
"mainporcelain",
"plumbinginterrogators",
"plumbingmanipulators",
"purehelpers",
"synchelpers",
"synchingrepositories",
NULL
};
which doesn't give quite the human-friendly output he'd like. The series is RFC, after all.
A possible approach to fix it would be to add a new "### categories" section to command-list.txt which associates those category tags ("ancillaryinterrogators") with human-readable counterparts ("Ancillary interrogators").
Re: [PATCH/RFC 5/5] help: add "-a --verbose" to list all commands with synopsis
Quoted 39 lines · Eric Sunshine
Quoted 11 lines · Junio C Hamano
Quoted 10 lines · Eric Sunshine
Quoted 7 lines · Nguyễn Thái Ngọc Duy
help.c +7
-0+switch (category) { +case CAT_ancillaryinterrogators:return _ ("Ancillary interrogators" ); +case CAT_ancillarymanipulators:return _ ("Ancillary manipulators" ); +case CAT_foreignscminterface:return _ ("Foreign SCM interface" ); +case CAT_mainporcelain:return _ ("Main porcelain" ); +case CAT_plumbinginterrogators:return _ ("Plumbing interrogators" ); +case CAT_plumbingmanipulators:return _ ("Plumbing interrogators" );Quoted 8 lines
Quoted 5 lines
s/interrogators"/manipulators"/
Quoted 3 lines
help.c +3
-0+case CAT_purehelpers:return _ ("Pure helpers" ); +case CAT_synchelpers:return _ ("Sync helpers" ); +case CAT_synchingrepositories:return _ ("Synching repositories" );Somehow this screams "an array of strings" at me. Aren't this
CAT_thingssmall and dense enum?Duy's modified
generate-cmdlist.shdoes actually output an array of strings for these, but the (generated) array is commented out in this RFC. I suppose the reason it's not presently used is because the array looks like this:static const char *cmd_categories[] = {
"ancillaryinterrogators",
"ancillarymanipulators",
"foreignscminterface",
"mainporcelain",
"plumbinginterrogators",
"plumbingmanipulators",
"purehelpers",
"synchelpers",
"synchingrepositories",
NULL
};
Quoted 2 lines
which doesn't give quite the human-friendly output he'd like. The series is RFC, after all.
Yep.
Quoted 4 lines
A possible approach to fix it would be to add a new "### categories" section to command-list.txt which associates those category tags ("ancillaryinterrogators") with human-readable counterparts ("Ancillary interrogators").
Or extract the headlines from git.txt but that's not easy since it's not consistent. We could manually recreate the same grouping as in git.txt too, it's probably nicer than just printing groups sorted by category id.
Signature · 1 line
Duy
Quoted 9 lines · Nguyễn Thái Ngọc Duy
This is pretty rough but I'd like to see how people feel about this first.
I notice we have two places for command classification. One in command-list.txt, one in
__git_list_porcelain_commands()in git-completion.bash. People who are following nd/parseopt-completion probably know that I'm try to reduce duplication in this script as much as possible, this is another step towards that.
Quoted 4 lines
By keeping all information of command-list.txt in git binary, we could provide the porcelain list to git-completion.bash via "git --list-cmds=porcelain", so we don't neeed a separate command classification in git-completion.bash anymore.
I like the direction this series is taking.
Quoted 5 lines
Because we have all command synopsis as a side effect, we could now support "git help -a --verbose" which prints something like "git help", a command name and a description, but we could do it for _all_ recognized commands. This could help people look for a command even if we don't provide "git appropos".
Nice idea, and you practically get this for free (aside from the the obvious new code) since generate-cmdlist.sh already plucks the summary for each command directly from Documentation/git-*.txt.
From: "Eric Sunshine" <[email protected]> Monday, April 09, 2018 6:17 AM
Quoted 9 lines · Nguyễn Thái Ngọc Duy
This is pretty rough but I'd like to see how people feel about this first.
I notice we have two places for command classification. One in command-list.txt, one in
__git_list_porcelain_commands()in git-completion.bash. People who are following nd/parseopt-completion probably know that I'm try to reduce duplication in this script as much as possible, this is another step towards that.
Quoted 4 lines
By keeping all information of command-list.txt in git binary, we could provide the porcelain list to git-completion.bash via "git --list-cmds=porcelain", so we don't neeed a separate command classification in git-completion.bash anymore.
I like the direction this series is taking.
Quoted 5 lines
Because we have all command synopsis as a side effect, we could now support "git help -a --verbose" which prints something like "git help", a command name and a description, but we could do it for _all_ recognized commands. This could help people look for a command even if we don't provide "git appropos".
Nice idea, and you practically get this for free (aside from the the obvious new code) since generate-cmdlist.sh already plucks the summary for each command directly from Documentation/git-*.txt.
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can begin to list them all?
It was something I looked at some years ago (when I added the -g option) but at the time the idea of updating the command-list.txt was too invasive.
Just a thought.
Philip
Quoted 3 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can begin to list them all?
It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
Signature · 1 line
Duy
From: "Duy Nguyen" <[email protected]> : Saturday, April 14, 2018 4:44 PM
Quoted 7 lines
Quoted 4 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can
begin to list them all?
Quoted 7 lines
It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
Signature · 1 line
Duy
Is that something I should add to my todo to add a 'guide' category etc.?
A quick search of public-inbox suggests
https://public-inbox.org/git/[email protected]/
as being where I first made the suggestions, but it got trimmed back to not update (be embedded in) the command-list.txt
Philip
Quoted 11 lines · Philip Oakley
From: "Duy Nguyen" <[email protected]> : Saturday, April 14, 2018 4:44 PM
Quoted 9 lines
Quoted 5 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can
begin to list them all?
Quoted 8 lines
Quoted 7 lines
It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
--
DuyIs that something I should add to my todo to add a 'guide' category etc.?
I added it too [1]. Not sure if you want anything more on top though.
[1] https://public-inbox.org/git/[email protected]/T/#u
Signature · 1 line
Duy
Quoted 19 lines · Duy Nguyen
Quoted 18 lines · Philip Oakley
From: "Duy Nguyen" <[email protected]> : Saturday, April 14, 2018 4:44 PM
Quoted 16 lines
Quoted 5 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can
begin to list them all?It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
--
Duy
Quoted 3 lines
Quoted 1 line
Is that something I should add to my todo to add a 'guide' category etc.?
I added it too [1]. Not sure if you want anything more on top though.
The "anything more" that at least I had in mind was something like this. Though I'm not sure if it's a good thing to replace a hand crafted section with an automatedly generated one. This patch on top combines the "SEE ALSO" and "FURTHER DOCUMENT" into one with most of documents/guides are extracted from command-list.txt
-- 8< --
Documentation/Makefile +1 -0
@@ -292,6 +292,7 @@ doc.dep : $(docdep_prereqs) $(wildcard *.txt) build-docdep.perl cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-ancillarymanipulators.txt \ + cmds-guide.txt \ cmds-mainporcelain.txt \ cmds-plumbinginterrogators.txt \ cmds-plumbingmanipulators.txt \
Documentation/cmd-list.perl +1 -0
@@ -54,6 +54,7 @@ for (sort <>) { for my $cat (qw(ancillaryinterrogators ancillarymanipulators + guide mainporcelain plumbinginterrogators plumbingmanipulators
Documentation/git.txt +10 -28
@@ -808,29 +808,6 @@ The index is also capable of storing multiple entries (called "stages") for a given pathname. These stages are used to hold the various unmerged version of a file when a merge is in progress. -FURTHER DOCUMENTATION ---------------------- - -See the references in the "description" section to get started -using Git. The following is probably more detail than necessary -for a first-time user. - -The link:user-manual.html#git-concepts[Git concepts chapter of the -user-manual] and linkgit:gitcore-tutorial[7] both provide -introductions to the underlying Git architecture. - -See linkgit:gitworkflows[7] for an overview of recommended workflows. - -See also the link:howto-index.html[howto] documents for some useful -examples. - -The internals are documented in the -link:technical/api-index.html[Git API documentation]. - -Users migrating from CVS may also want to -read linkgit:gitcvs-migration[7]. - - Authors ------- Git was started by Linus Torvalds, and is currently maintained by Junio
@@ -854,11 +831,16 @@ the Git Security mailing list <[email protected]>. SEE ALSO -------- -linkgit:gittutorial[7], linkgit:gittutorial-2[7], -linkgit:giteveryday[7], linkgit:gitcvs-migration[7], -linkgit:gitglossary[7], linkgit:gitcore-tutorial[7], -linkgit:gitcli[7], link:user-manual.html[The Git User's Manual], -linkgit:gitworkflows[7] + +See the references in the "description" section to get started +using Git. The following is probably more detail than necessary +for a first-time user. + +include::cmds-guide.txt[] + +See also the link:howto-index.html[howto] documents for some useful +examples. The internals are documented in the +link:technical/api-index.html[Git API documentation]. GIT ---
command-list.txt +4 -0
@@ -150,10 +150,14 @@ git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators gitattributes guide +gitcvs-migration guide +gitcli guide +gitcore-tutorial guide giteveryday guide gitglossary guide gitignore guide gitmodules guide gitrevisions guide gittutorial guide +gittutorial-2 guide gitworkflows guide
-- 8< --
From: "Duy Nguyen" <[email protected]> : Tuesday, April 17, 2018 5:48 PM
Quoted 20 lines · Duy Nguyen
Quoted 19 lines · Philip Oakley
Quoted 18 lines
From: "Duy Nguyen" <[email protected]> : Saturday, April 14, 2018 4:44 PM
Quoted 16 lines
Quoted 5 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g' can
begin to list them all?It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
--
Duy
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
Is that something I should add to my todo to add a 'guide' category etc.?
I added it too [1]. Not sure if you want anything more on top though.
What I've seen is looking good - I've not had as much time as I'd like..
I'm not sure of the status of the git/generate-cmdlist.sh though. Should that also be updated, or did I miss that? --
Philip
Quoted 113 lines
The "anything more" that at least I had in mind was something like this. Though I'm not sure if it's a good thing to replace a hand crafted section with an automatedly generated one. This patch on top combines the "SEE ALSO" and "FURTHER DOCUMENT" into one with most of documents/guides are extracted from command-list.txt
-- 8< --
Documentation/Makefile +0
-0@@ -292,6 +292,7 @@ doc.dep : $(docdep_prereqs) $(wildcard *.txt)build-docdep.perl
cmds_txt= cmds-ancillaryinterrogators.txt \
cmds-ancillarymanipulators.txt \
+ cmds-guide.txt \
cmds-mainporcelain.txt \
cmds-plumbinginterrogators.txt \
cmds-plumbingmanipulators.txt \Documentation/cmd-list.perl +0
-0@@ -54,6 +54,7 @@ for (sort <>) {for my $cat (qw(ancillaryinterrogators
ancillarymanipulators
+ guide
mainporcelain
plumbinginterrogators
plumbingmanipulatorsDocumentation/git.txt +0
-0@@ -808,29 +808,6 @@ The index is also capable of storing multiple entries (called "stages")for a given pathname. These stages are used to hold the various unmerged version of a file when a merge is in progress.
Documentation/git.txt +0
-23-FURTHER DOCUMENTATION ---------------------- - -See the references in the "description" section to get started -using Git. The following is probably more detail than necessary -for a first-time user. - -The link:user-manual.html#git-concepts[Git concepts chapter of the -user-manual] and linkgit:gitcore-tutorial[7] both provide -introductions to the underlying Git architecture. - -See linkgit:gitworkflows[7] for an overview of recommended workflows. - -See also the link:howto-index.html[howto] documents for some useful -examples. - -The internals are documented in the -link:technical/api-index.html[Git API documentation]. - -Users migrating from CVS may also want to -read linkgit:gitcvs-migration[7]. - -Authors
-------
Git was started by Linus Torvalds, and is currently maintained by JunioDocumentation/git.txt +0
-0@@ -854,11 +831,16 @@ the Git Security mailing listSEE ALSO
--------Documentation/git.txt +10
-5-linkgit:gittutorial[7], linkgit:gittutorial-2[7], -linkgit:giteveryday[7], linkgit:gitcvs-migration[7], -linkgit:gitglossary[7], linkgit:gitcore-tutorial[7], -linkgit:gitcli[7], link:user-manual.html[The Git User's Manual], -linkgit:gitworkflows[7] + +See the references in the "description" section to get started +using Git. The following is probably more detail than necessary +for a first-time user. + +include::cmds-guide.txt[] + +See also the link:howto-index.html[howto] documents for some useful +examples. The internals are documented in the +link:technical/api-index.html[Git API documentation].GIT
---command-list.txt +0
-0@@ -150,10 +150,14 @@ git-whatchangedancillaryinterrogators
git-worktree mainporcelain git-write-tree plumbingmanipulators gitattributes guidecommand-list.txt +3
-0+gitcvs-migration guide +gitcli guide +gitcore-tutorial guidegiteveryday guide gitglossary guide gitignore guide gitmodules guide gitrevisions guide gittutorial guide+gittutorial-2 guide
gitworkflows guide
-- 8< --
From: "Philip Oakley" <[email protected]> : Tuesday, April 17, 2018 11:47 PM
Quoted 28 lines
From: "Duy Nguyen" <[email protected]> : Tuesday, April 17, 2018 5:48 PM
Quoted 27 lines · Duy Nguyen
Quoted 26 lines
Quoted 23 lines · Philip Oakley
From: "Duy Nguyen" <[email protected]> : Saturday, April 14, 2018 4:44 PM
Quoted 11 lines
Quoted 6 lines · Philip Oakley
I'm only just catching up, but does/can this series also capture the non-command guides that are available in git so that the 'git help -g'
can
begin to list them all?Quoted 7 lines
It currently does not. But I don't see why it should not. This should allow git.txt to list all the guides too, for people who skip "git help" and go hard core mode with "man git". Thanks for bringing this up.
--
DuyIs that something I should add to my todo to add a 'guide' category etc.?
Quoted 8 lines
Quoted 1 line
Quoted 1 line
I added it too [1]. Not sure if you want anything more on top though.
What I've seen is looking good - I've not had as much time as I'd like..
I'm not sure of the status of the
git/generate-cmdlist.shthough. Should that also be updated, or did I miss that?
--
Philip
I may be miss-remembering the order that the git help determines the list of commands and guides. There was at least one place where the list of commands was generated programatically that I may be confused with (I've not had time to delve into the code :-(
--
Quoted 115 lines
Quoted 113 lines
The "anything more" that at least I had in mind was something like this. Though I'm not sure if it's a good thing to replace a hand crafted section with an automatedly generated one. This patch on top combines the "SEE ALSO" and "FURTHER DOCUMENT" into one with most of documents/guides are extracted from command-list.txt
-- 8< --
Documentation/Makefile +0
-0@@ -292,6 +292,7 @@ doc.dep : $(docdep_prereqs) $(wildcard *.txt)build-docdep.perl
cmds_txt= cmds-ancillaryinterrogators.txt \
cmds-ancillarymanipulators.txt \
+ cmds-guide.txt \
cmds-mainporcelain.txt \
cmds-plumbinginterrogators.txt \
cmds-plumbingmanipulators.txt \Documentation/cmd-list.perl +0
-0@@ -54,6 +54,7 @@ for (sort <>) {for my $cat (qw(ancillaryinterrogators
ancillarymanipulators
+ guide
mainporcelain
plumbinginterrogators
plumbingmanipulatorsDocumentation/git.txt +0
-0@@ -808,29 +808,6 @@ The index is also capable of storing multiple entries (called "stages")for a given pathname. These stages are used to hold the various unmerged version of a file when a merge is in progress.
Documentation/git.txt +0
-23-FURTHER DOCUMENTATION ---------------------- - -See the references in the "description" section to get started -using Git. The following is probably more detail than necessary -for a first-time user. - -The link:user-manual.html#git-concepts[Git concepts chapter of the -user-manual] and linkgit:gitcore-tutorial[7] both provide -introductions to the underlying Git architecture. - -See linkgit:gitworkflows[7] for an overview of recommended workflows. - -See also the link:howto-index.html[howto] documents for some useful -examples. - -The internals are documented in the -link:technical/api-index.html[Git API documentation]. - -Users migrating from CVS may also want to -read linkgit:gitcvs-migration[7]. - -Authors
-------
Git was started by Linus Torvalds, and is currently maintained by JunioDocumentation/git.txt +0
-0@@ -854,11 +831,16 @@ the Git Security mailing listSEE ALSO
--------Documentation/git.txt +10
-5-linkgit:gittutorial[7], linkgit:gittutorial-2[7], -linkgit:giteveryday[7], linkgit:gitcvs-migration[7], -linkgit:gitglossary[7], linkgit:gitcore-tutorial[7], -linkgit:gitcli[7], link:user-manual.html[The Git User's Manual], -linkgit:gitworkflows[7] + +See the references in the "description" section to get started +using Git. The following is probably more detail than necessary +for a first-time user. + +include::cmds-guide.txt[] + +See also the link:howto-index.html[howto] documents for some useful +examples. The internals are documented in the +link:technical/api-index.html[Git API documentation].GIT
---command-list.txt +0
-0@@ -150,10 +150,14 @@ git-whatchanged ancillaryinterrogatorsgit-worktree mainporcelain git-write-tree plumbingmanipulators gitattributes guidecommand-list.txt +3
-0+gitcvs-migration guide +gitcli guide +gitcore-tutorial guidegiteveryday guide gitglossary guide gitignore guide gitmodules guide gitrevisions guide gittutorial guide+gittutorial-2 guide
gitworkflows guide
-- 8< --
Quoted 10 lines · Philip Oakley
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
Is that something I should add to my todo to add a 'guide' category > etc.?
I added it too [1]. Not sure if you want anything more on top though.
What I've seen is looking good - I've not had as much time as I'd like..
I'm not sure of the status of the
git/generate-cmdlist.shthough. Should that also be updated, or did I miss that?
Yes it's updated by other patches in the same thread.
Signature · 1 line
Duy
From: "Duy Nguyen" <[email protected]>
Quoted 8 lines
Quoted 6 lines · Philip Oakley
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines
Is that something I should add to my todo to add a 'guide' category > etc.?
I added it too [1]. Not sure if you want anything more on top though.
Quoted 7 lines
Quoted 4 lines
What I've seen is looking good - I've not had as much time as I'd like..
I'm not sure of the status of the
git/generate-cmdlist.shthough. Should that also be updated, or did I miss that?Yes it's updated by other patches in the same thread.
Thanks. Hopefully I'll have some time this weekend/coming week as my wife is away....
Philip
v2 cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc Duyv2 changes
- bug fixes spotted by Eric
- keep 'git help -av' layout close to what's in git.txt
- enable pager for 'git help -av' because it's usually long
- move guide list (aka 'help -g') to command-list.txt
Nguyễn Thái Ngọc Duy (6):
git.c: convert --list-builtins to --list-cmds=builtins git.c: implement --list-cmds=all and use it in git-completion.bash generate-cmdlist.sh: keep all information in common-cmds.h git.c: implement --list-cmds=porcelain
help: add "-a --verbose" to list all commands with synopsis
help: use command-list.txt for the source of guides
Documentation/git-help.txt | 4 +- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- builtin/help.c | 39 ++---- command-list.txt | 8 ++ contrib/completion/git-completion.bash | 96 +-------------- generate-cmdlist.sh | 65 +++++++--- git.c | 16 ++- help.c | 163 ++++++++++++++++++++++++- help.h | 4 + t/t0012-help.sh | 2 +- t/t9902-completion.sh | 4 +- 13 files changed, 249 insertions(+), 158 deletions(-)
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v2 1/6 git.c: convert --list-builtins to --list-cmds=builtins
Even if this is a hidden option, let's make it a bit more generic since we're introducing more listing types.
--- contrib/completion/git-completion.bash | 2 +- git.c | 12 +++++++----- t/t0012-help.sh | 2 +- 3 files changed, 9 insertions(+), 7 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 +7 -5
@@ -223,11 +223,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 ,' ' ); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"builtins" )) +list_builtins (0 ,'\n' ); +else if (!strcmp (cmd,"parseopt" )) +list_builtins (NO_PARSEOPT ,' ' ); +else +die ("unsupported command listing type '%s'" , cmd);exit (0 ); }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);
t/t0012-help.sh +1 -1
@@ -50,7 +50,7 @@ test_expect_success "--help does not work for guides" " " test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v2 2/6 git.c: implement --list-cmds=all and use it in git-completion.bash
In reply to Nguyễn Thái Ngọc Duy--- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 18 ++++++++++++++++++ help.h | 1 + 4 files changed, 22 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=all fi }
git.c +2 -0
@@ -228,6 +228,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (0 ,'\n' ); else if (!strcmp(cmd, "parseopt"))list_builtins (NO_PARSEOPT ,' ' ); + else if (!strcmp(cmd, "all")) +list_all_cmds (); else die("unsupported command listing type '%s'", cmd);exit (0 );
help.c +18 -0
@@ -228,6 +228,24 @@ void list_common_cmds_help(void) } } +void list_all_cmds (void ) +{ +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++) +puts (main_cmds.names[i]->name); +for (i =0 ; i < other_cmds.cnt; i++) +puts (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 +1 -0
@@ -17,6 +17,7 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds (void );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.367.g5dd2e386c3
Re: [PATCH v2 2/6] git.c: implement --list-cmds=all and use it in git-completion.bash
Quoted 13 lines · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 18 ++++++++++++++++++ help.h | 1 + 4 files changed, 22 insertions(+), 1 deletion(-)contrib/completion/git-completion.bash +0
-0
contrib/completion/git-completion.bash __git_commands () { · line 844
Quoted 7 lines
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=all fi }
To those of us who install a copy of git-completion.bash somewhere in $HOME and forget about it, while installing different versions of Git all the time for testing, may see breakage caused by an invalid combination of having new completion script with Git that does not know about --list=cmds=<all> option. I do not think it matters too much, though ;-)
Quoted 8 lines
contrib/completion/git-completion.bash +8
-0+void list_all_cmds(void) +{ + 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);
contrib/completion/git-completion.bash __git_commands () {
Quoted 10 lines
contrib/completion/git-completion.bash +10
-0+ + for (i = 0; i < main_cmds.cnt; i++) + puts(main_cmds.names[i]->name); + for (i = 0; i < other_cmds.cnt; i++) + puts(other_cmds.names[i]->name); + + clean_cmdnames(&main_cmds); + clean_cmdnames(&other_cmds); +} +
OK.
By reusing load_command_list(), the duplicate-removal logic at its end that is used for "help -a" kicks in; the above looks good.
PATCH v2 3/6 generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Nguyễn Thái Ngọc Duycommon-cmds.h is used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Update generate-cmdlist.sh to keep all the information. The extra info will be used shortly.
--- generate-cmdlist.sh | 61 +++++++++++++++++++++++++++++++++------------ help.c | 42 ++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 22 deletions(-)
generate-cmdlist.sh +45 -16
@@ -1,17 +1,30 @@ #!/bin/sh +# Don't let locale affect this script. +LC_ALL=C +LANG=C +export LC_ALL LANG + +command_list () { + sed '1,/^### command list/d;/^#/d' "$1" +} + +category_list () { + command_list "$1" | awk '{print $2;}' | sort | uniq +} + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { - char name[16]; + char name[32]; char help[80]; - unsigned char group; + unsigned int category; + unsigned int group; }; static const char *common_cmd_groups[] = {" grps=grps$$.tmp -match=match$$.tmp -trap "rm -f '$grps' '$match'" 0 1 2 3 15 +trap "rm -f '$grps'" 0 1 2 3 15 sed -n ' 1,/^### common groups/b
@@ -23,28 +36,44 @@ sed -n ' ' "$1" printf '};\n\n' +echo "#define GROUP_NONE 0xff /* no common group */" n=0 -substnum= while read grp do - echo "^git-..*[ ]$grp" - substnum="$substnum${substnum:+;}s/[ ]$grp/$n/" + echo "#define GROUP_${grp:-NONE} $n" n=$(($n+1)) -done <"$grps" >"$match" +done <"$grps" +echo + +echo '/*' +printf 'static const char *cmd_categories[] = {\n' +category_list "$1" | +while read category; do + printf '\t\"'$category'\",\n' +done +printf '\tNULL\n};\n\n' +echo '*/' + +n=0 +category_list "$1" | +while read category; do + echo "#define CAT_$category $n" + n=$(($n+1)) +done +echo -printf 'static struct cmdname_help common_cmds[] = {\n' -grep -f "$match" "$1" | -sed 's/^git-//' | +printf 'static struct cmdname_help command_list[] = {\n' +command_list "$1" | sort | -while read cmd tags +while read cmd category tags do - tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") + name=${cmd/git-} sed -n ' - /^NAME/,/git-'"$cmd"'/H + /^NAME/,/'"$cmd"'/H ${ x - s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", N_("\1"), '$tag'},/ + s/.*'"$cmd"' - \(.*\)/ {"'"$name"'", N_("\1"), CAT_'$category', GROUP_'${tags:-NONE}' },/ p - }' "Documentation/git-$cmd.txt" + }' "Documentation/$cmd.txt" done echo "};"
help.c +36 -6
95 lines not on this page · raw message
Signature · 1 line
2.17.0.367.g5dd2e386c3
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
generate-cmdlist.sh line 14
Quoted 3 lines · Nguyễn Thái Ngọc Duy
generate-cmdlist.sh +3
-0+category_list () { + command_list "$1" | awk '{print $2;}' | sort | uniq +}
Piping output of awk to sort/uniq, instead of processing all inside awk within the END block of the script, means that we are wasting two processes---I do not think we care too much about it, but some people might.
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 11 lines · Junio C Hamano
generate-cmdlist.sh line 14
Quoted 3 lines · Nguyễn Thái Ngọc Duy
generate-cmdlist.sh +3
-0+category_list () { + command_list "$1" | awk '{print $2;}' | sort | uniq +}Piping output of awk to sort/uniq, instead of processing all inside awk within the END block of the script, means that we are wasting two processes---I do not think we care too much about it, but some people might.
Can be written as:
command_list "$1" | awk '!seen[$2]++ {print $2}'This doesn't actually sort it, though, which I'm not sure whether is a good thing or a bad thing in this case. But it is less work, and being fast is nice for completion scripts.
Øsse
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 15 lines
Quoted 11 lines · Junio C Hamano
generate-cmdlist.sh line 14
Quoted 3 lines · Nguyễn Thái Ngọc Duy
generate-cmdlist.sh +3
-0+category_list () { + command_list "$1" | awk '{print $2;}' | sort | uniq +}Piping output of awk to sort/uniq, instead of processing all inside awk within the END block of the script, means that we are wasting two processes---I do not think we care too much about it, but some people might.
Quoted 7 lines
Can be written as:
command_list "$1" | awk '!seen[$2]++ {print $2}'This doesn't actually sort it, though, which I'm not sure whether is a good thing or a bad thing in this case. But it is less work, and being fast is nice for completion scripts.
This script is run during the build process, not during completion.
(The order wouldn't matter for completion, because the shell would sort possible completion words anyway.)
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Nguyễn Thái Ngọc DuyReview sed -n ' · line 39
Quoted 5 lines · Nguyễn Thái Ngọc Duy
(quoted diff) +1
-0@@ -23,28 +36,44 @@ sed -n ' ' "$1" printf '};\n\n' +echo "#define GROUP_NONE 0xff /* no common group */"
Some later code forgets about this value, and causes "git<ENTER>" to segfault at the end of this entire series.
Namely, here:
Review sed -n ' · line 43
Quoted 5 lines
(quoted diff) +1
-1- for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { + for (i = 0; i < nr; i++) { if (common_cmds[i].group != current_grp) { printf("\n%s\n", _(common_cmd_groups[common_cmds[i].group])); current_grp = common_cmds[i].group;
where common_cmd_groups[] gets overrun.
Here is a squash I'll queue on top to keep the tip of 'pu' at least buildable.
help.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
help.c +3 -1
@@ -242,7 +242,9 @@ void list_common_cmds_help(void)puts (_ ("These are common Git commands used in various situations:" ));for (i =0 ; i < nr; i++) { -if (common_cmds[i].group != current_grp) { +if (ARRAY_SIZE (common_cmd_groups) <= common_cmds[i].group) + ;/* skip */ +else if (common_cmds[i].group != current_grp) {printf ("\n%s\n" ,_ (common_cmd_groups[common_cmds[i].group])); current_grp = common_cmds[i].group; }
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 13 lines · Junio C Hamano
Review sed -n ' · line 39
Quoted 5 lines · Nguyễn Thái Ngọc Duy
(quoted diff) +1
-0@@ -23,28 +36,44 @@ sed -n ' ' "$1" printf '};\n\n' +echo "#define GROUP_NONE 0xff /* no common group */"Some later code forgets about this value, and causes "git<ENTER>" to segfault at the end of this entire series.
Namely, here:
Quoted 7 lines
Review sed -n ' · line 43
Quoted 5 lines
(quoted diff) +1
-1- for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { + for (i = 0; i < nr; i++) { if (common_cmds[i].group != current_grp) { printf("\n%s\n", _(common_cmd_groups[common_cmds[i].group])); current_grp = common_cmds[i].group;where common_cmd_groups[] gets overrun.
Argh!! I thought I tested everything. Sorry for the sloppy quality.
Quoted 3 lines
Here is a squash I'll queue on top to keep the tip of 'pu' at least buildable.
Thanks. It's actually interesting that we have main porcelain commands that belong to no group. I'll try to classify them so that they show up as well.
Signature · 1 line
Duy
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Nguyễn Thái Ngọc DuyQuoted 18 lines · Nguyễn Thái Ngọc Duy
common-cmds.his used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Updategenerate-cmdlist.shto keep all the information. The extra info will be used shortly.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- generate-cmdlist.sh | 61 +++++++++++++++++++++++++++++++++------------ help.c | 42 ++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 22 deletions(-)generate-cmdlist.sh +0
-1-printf 'static struct cmdname_help common_cmds[] = {\n'
generate-cmdlist.sh sed -n ' · line 70
Quoted 10 lines
generate-cmdlist.sh +4
-4-grep -f "$match" "$1" | -sed 's/^git-//' | +printf 'static struct cmdname_help command_list[] = {\n' +command_list "$1" | sort | -while read cmd tags +while read cmd category tags do - tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") + name=${cmd/git-}
There are two issues with this line:
- This is a "regular" shell script, therefore it must not use pattern substitution.
- The pattern substitution would remove the string "git-" in the middle of the variable as well; I suspect this is undesired.
I think that the remove matching prefix pattern substitution should be used here.
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
Quoted 32 lines · SZEDER Gábor
Quoted 18 lines · Nguyễn Thái Ngọc Duy
common-cmds.his used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Updategenerate-cmdlist.shto keep all the information. The extra info will be used shortly.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- generate-cmdlist.sh | 61 +++++++++++++++++++++++++++++++++------------ help.c | 42 ++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 22 deletions(-)generate-cmdlist.sh +0
-1-printf 'static struct cmdname_help common_cmds[] = {\n'generate-cmdlist.sh sed -n ' · line 70
Quoted 10 lines
generate-cmdlist.sh +4
-4-grep -f "$match" "$1" | -sed 's/^git-//' | +printf 'static struct cmdname_help command_list[] = {\n' +command_list "$1" | sort | -while read cmd tags +while read cmd category tags do - tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") + name=${cmd/git-}There are two issues with this line:
Quoted 8 lines
- This is a "regular" shell script, therefore it must not use pattern substitution.
- The pattern substitution would remove the string "git-" in the middle of the variable as well; I suspect this is undesired.
I think that the remove matching prefix pattern substitution should be used here.
This also, apparently, doesn't work with dash. On cygwin, which has bash as /bin/sh, this builds common-cmds.h just fine. On linux, which has dash as /bin/sh, this fails, leaving a truncated file:
$ bash generate-cmdlist.sh command-list.txt >zzz
$ tail -3 zzz
{"gitweb", N_("Git web interface (web frontend to Git repositories)"), CAT_ancillaryinterrogators, GROUP_NONE },
{"workflows", N_("An overview of recommended workflows with Git"), CAT_guide, GROUP_NONE },
};$ dash generate-cmdlist.sh command-list.txt >zzz generate-cmdlist.sh: 73: generate-cmdlist.sh: Bad substitution $ tail -3 zzz
static struct cmdname_help command_list[] = {
};
$ This leads to a very broken 'git help'.
ATB,
Ramsay Jones
Re: [PATCH v2 3/6] generate-cmdlist.sh: keep all information in common-cmds.h
In reply to SZEDER GáborQuoted 9 lines · SZEDER Gábor
generate-cmdlist.sh sed -n ' · line 70
Quoted 4 lines
generate-cmdlist.sh +2
-1+while read cmd category tags do - tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g") + name=${cmd/git-}There are two issues with this line:
- This is a "regular" shell script, therefore it must not use pattern substitution.
Oops. I missed that. Thanks.
Quoted 6 lines
- The pattern substitution would remove the string "git-" in the middle of the variable as well; I suspect this is undesired.
I think that the remove matching prefix pattern substitution should be used here.
PATCH v2 4/6 git.c: implement --list-cmds=porcelain
In reply to Nguyễn Thái Ngọc DuyThis is useful for git-completion.bash because it needs this set of commands. Right now we have to maintain a separate command category in there.
--- contrib/completion/git-completion.bash | 94 ++------------------------ git.c | 2 + help.c | 12 ++++ help.h | 1 + t/t9902-completion.sh | 4 +- 5 files changed, 20 insertions(+), 93 deletions(-)
contrib/completion/git-completion.bash +4 -90
@@ -839,14 +839,15 @@ __git_commands () { then printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" else - git --list-cmds=all + git --list-cmds=$1 fi } __git_list_all_commands () { local i IFS=" "$'\n' - for i in $(__git_commands) + local category=${1-all} + for i in $(__git_commands $category) do case $i in *--*) : helper pattern;;
@@ -862,98 +863,11 @@ __git_compute_all_commands () __git_all_commands=$(__git_list_all_commands) } -__git_list_porcelain_commands () -{ - local i IFS=" "$'\n' - __git_compute_all_commands - for i in $__git_all_commands - do - case $i in - *--*) : helper pattern;; - applymbox) : ask gittus;; - applypatch) : ask gittus;; - archimport) : import;; - cat-file) : plumbing;; - check-attr) : plumbing;; - check-ignore) : plumbing;; - check-mailmap) : plumbing;; - check-ref-format) : plumbing;; - checkout-index) : plumbing;; - column) : internal helper;; - commit-tree) : plumbing;; - count-objects) : infrequent;; - credential) : credentials;; - credential-*) : credentials helper;; - cvsexportcommit) : export;; - cvsimport) : import;; - cvsserver) : daemon;; - daemon) : daemon;; - diff-files) : plumbing;; - diff-index) : plumbing;; - diff-tree) : plumbing;; - fast-import) : import;; - fast-export) : export;; - fsck-objects) : plumbing;; - fetch-pack) : plumbing;; - fmt-merge-msg) : plumbing;; - for-each-ref) : plumbing;; - hash-object) : plumbing;; - http-*) : transport;; - index-pack) : plumbing;; - init-db) : deprecated;; - local-fetch) : plumbing;; - ls-files) : plumbing;; - ls-remote) : plumbing;; - ls-tree) : plumbing;; - mailinfo) : plumbing;; - mailsplit) : plumbing;; - merge-*) : plumbing;; - mktree) : plumbing;; - mktag) : plumbing;; - pack-objects) : plumbing;; - pack-redundant) : plumbing;; - pack-refs) : plumbing;; - parse-remote) : plumbing;; - patch-id) : plumbing;; - prune) : plumbing;; - prune-packed) : plumbing;; - quiltimport) : import;; - read-tree) : plumbing;; - receive-pack) : plumbing;; - remote-*) : transport;; - rerere) : plumbing;; - rev-list) : plumbing;; - rev-parse) : plumbing;; - runstatus) : plumbing;; - sh-setup) : internal;; - shell) : daemon;; - show-ref) : plumbing;; - send-pack) : plumbing;; - show-index) : plumbing;; - ssh-*) : transport;; - stripspace) : plumbing;; - symbolic-ref) : plumbing;; - unpack-file) : plumbing;; - unpack-objects) : plumbing;; - update-index) : plumbing;; - update-ref) : plumbing;; - update-server-info) : daemon;; - upload-archive) : plumbing;; - upload-pack) : plumbing;; - write-tree) : plumbing;; - var) : infrequent;; - verify-pack) : infrequent;; - verify-tag) : plumbing;; - *) echo $i;; - esac - done -} - __git_porcelain_commands= __git_compute_porcelain_commands () { test -n "$__git_porcelain_commands" || - __git_porcelain_commands=$(__git_list_porcelain_commands) + __git_porcelain_commands=$(__git_list_all_commands porcelain) } # Lists all set config variables starting with the given section prefix,
git.c +2 -0
@@ -230,6 +230,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (NO_PARSEOPT ,' ' ); else if (!strcmp(cmd, "all"))list_all_cmds (); + else if (!strcmp(cmd, "porcelain")) +list_porcelain_cmds (); else die("unsupported command listing type '%s'", cmd);exit (0 );
help.c +12 -0
@@ -272,6 +272,18 @@ void list_all_cmds(void)clean_cmdnames (&other_cmds); } +void list_porcelain_cmds (void ) +{ +int i, nr =ARRAY_SIZE (command_list); +struct cmdname_help *cmds = command_list; + +for (i =0 ; i < nr; i++) { +if (cmds[i].category != CAT_mainporcelain) +continue ; +puts (cmds[i].name); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -18,6 +18,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds (void ); +extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
t/t9902-completion.sh +1 -3
@@ -1208,8 +1208,6 @@ test_expect_success 'basic' ' grep -q "^add \$" out && # script grep -q "^filter-branch \$" out && - # plumbing - ! grep -q "^ls-files \$" out && run_completion "git f" && ! grep -q -v "^f" out
@@ -1272,7 +1270,7 @@ test_expect_success 'general options' ' test_completion "git --no-r" "--no-replace-objects " ' -test_expect_success 'general options plus command' ' +test_expect_failure 'general options plus command' ' test_completion "git --version check" "checkout " && test_completion "git --paginate check" "checkout " && test_completion "git --git-dir=foo check" "checkout " &&
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v2 5/6 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 | 69 ++++++++++++++++++++++++++++++++++++++ help.h | 1 + 4 files changed, 80 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 +69 -0
75 lines not on this page · raw message
help.h +1 -0
@@ -17,6 +17,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_all_cmds (void );extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd);
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v2 6/6 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 lists guides in git.txt, but I'll leave that for now.
--- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- builtin/help.c | 32 -------------------------------- command-list.txt | 8 ++++++++ generate-cmdlist.sh | 6 +++++- help.c | 22 ++++++++++++++++++++++ help.h | 1 + 8 files changed, 39 insertions(+), 36 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 --------
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 +8 -0
@@ -149,3 +149,11 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +giteveryday guide +gitglossary guide +gitignore guide +gitmodules guide +gitrevisions guide +gittutorial guide +gitworkflows guide
generate-cmdlist.sh +5 -1
@@ -67,7 +67,11 @@ command_list "$1" | sort | while read cmd category tags do - name=${cmd/git-} + if [ "$category" = guide ]; then + name=${cmd/git} + else + name=${cmd/git-} + fi sed -n ' /^NAME/,/'"$cmd"'/H ${
help.c +22 -0
@@ -313,6 +313,28 @@ static void list_commands_by_category(int cat, struct cmdname_help *cmds, } } +void list_common_guides_help (void ) +{ +int i, longest =0 ; +int nr =ARRAY_SIZE (command_list); +struct cmdname_help *cmds = command_list; + +QSORT (cmds, nr, cmd_category_cmp); + +for (i =0 ; i < nr; i++) { +struct cmdname_help *cmd = cmds + i; + +if (cmd->category != CAT_guide) +continue ; +if (longest <strlen (cmd->name)) + longest =strlen (cmd->name); + } + +puts (_ ("The common Git guides are:\n" )); +list_commands_by_category (CAT_guide, cmds, nr, longest); +putchar ('\n' ); +} +void list_all_cmds_help (void ) {int i, longest =0 ;
help.h +1 -0
@@ -18,6 +18,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_cmds (void );extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd);
Signature · 1 line
2.17.0.367.g5dd2e386c3
v3 cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc DuyChanges:
- remove the deprecated column in command-list.txt. My change break it anyway if anyone uses it.
- fix up failed tests that I marked in the RFC and kinda forgot about it.
- fix bashisms in generate-cmdlist.sh
- fix segfaul in "git help"
Nguyễn Thái Ngọc Duy (6):
git.c: convert --list-*builtins to --list-cmds=*
git.c: implement --list-cmds=all and use it in git-completion.bash generate-cmdlist.sh: keep all information in common-cmds.h git.c: implement --list-cmds=porcelain
help: add "-a --verbose" to list all commands with synopsis
help: use command-list.txt for the source of guides
Documentation/git-help.txt | 4 +- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- builtin/help.c | 39 ++---- command-list.txt | 10 +- contrib/completion/git-completion.bash | 108 ++-------------- generate-cmdlist.sh | 57 ++++++--- git.c | 16 ++- help.c | 164 ++++++++++++++++++++++++- help.h | 4 + t/t0012-help.sh | 11 +- t/t9902-completion.sh | 6 +- 13 files changed, 263 insertions(+), 162 deletions(-)
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v3 1/6 git.c: convert --list-*builtins to --list-cmds=*
Even if these are hidden options, let's make them a bit more generic since we're introducing more listing types shortly.
--- contrib/completion/git-completion.bash | 2 +- git.c | 12 +++++++----- t/t0012-help.sh | 2 +- 3 files changed, 9 insertions(+), 7 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 +7 -5
@@ -223,11 +223,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 ,' ' ); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"builtins" )) +list_builtins (0 ,'\n' ); +else if (!strcmp (cmd,"parseopt" )) +list_builtins (NO_PARSEOPT ,' ' ); +else +die ("unsupported command listing type '%s'" , cmd);exit (0 ); }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);
t/t0012-help.sh +1 -1
@@ -50,7 +50,7 @@ test_expect_success "--help does not work for guides" " " test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v3 2/6 git.c: implement --list-cmds=all and use it in git-completion.bash
In reply to Nguyễn Thái Ngọc Duy--- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 18 ++++++++++++++++++ help.h | 1 + 4 files changed, 22 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=all fi }
git.c +2 -0
@@ -228,6 +228,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (0 ,'\n' ); else if (!strcmp(cmd, "parseopt"))list_builtins (NO_PARSEOPT ,' ' ); + else if (!strcmp(cmd, "all")) +list_all_cmds (); else die("unsupported command listing type '%s'", cmd);exit (0 );
help.c +18 -0
@@ -228,6 +228,24 @@ void list_common_cmds_help(void) } } +void list_all_cmds (void ) +{ +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++) +puts (main_cmds.names[i]->name); +for (i =0 ; i < other_cmds.cnt; i++) +puts (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 +1 -0
@@ -17,6 +17,7 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds (void );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.367.g5dd2e386c3
Re: [PATCH v3 2/6] git.c: implement --list-cmds=all and use it in git-completion.bash
Quoted 1 line · Nguyễn Thái Ngọc Duy
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>
Oh, look, an empty commit message! :)
So what does this option do and why use it in the completion script?
PATCH v3 3/6 generate-cmdlist.sh: keep all information in common-cmds.h
In reply to Nguyễn Thái Ngọc Duycommon-cmds.h is used to extract the list of common commands (by group) and a one-line summary of each command. Some information is dropped, for example command category or summary of other commands. Update generate-cmdlist.sh to keep all the information. The extra info will be used shortly.
The "deprecated" column is dropped from command-list.txt since it's not really used and the new parsing code can't deal with it. When we do need deprecated attribute, we could add it back and adjust generate-cmdlist.sh at the same time.
--- command-list.txt | 2 +- generate-cmdlist.sh | 53 +++++++++++++++++++++++++++++++-------------- help.c | 43 +++++++++++++++++++++++++++++++----- 3 files changed, 75 insertions(+), 23 deletions(-)
command-list.txt +1 -1
@@ -9,7 +9,7 @@ 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 name category [common] git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators
generate-cmdlist.sh +37 -16
82 lines not on this page · raw message
help.c +37 -6
96 lines not on this page · raw message
Signature · 1 line
2.17.0.367.g5dd2e386c3
PATCH v3 4/6 git.c: implement --list-cmds=porcelain
In reply to Nguyễn Thái Ngọc DuyThis is useful for git-completion.bash because it needs this set of commands. Right now we have to maintain a separate command category in there.
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.
--- contrib/completion/git-completion.bash | 106 +++---------------------- git.c | 2 + help.c | 12 +++ help.h | 1 + t/t9902-completion.sh | 6 +- 5 files changed, 31 insertions(+), 96 deletions(-)
contrib/completion/git-completion.bash +12 -94
@@ -835,18 +835,23 @@ __git_complete_strategy () } __git_commands () { - if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" + if test -n "$GIT_TESTING_COMPLETION" then - printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" + case "$1" in + porcelain) + printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST";; + all) + printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST";; + esac else - git --list-cmds=all + git --list-cmds=$1 fi } -__git_list_all_commands () +__git_list_commands () { local i IFS=" "$'\n' - for i in $(__git_commands) + for i in $(__git_commands $1) do case $i in *--*) : helper pattern;;
@@ -859,101 +864,14 @@ __git_all_commands= __git_compute_all_commands () { test -n "$__git_all_commands" || - __git_all_commands=$(__git_list_all_commands) -} - -__git_list_porcelain_commands () -{ - local i IFS=" "$'\n' - __git_compute_all_commands - for i in $__git_all_commands - do - case $i in - *--*) : helper pattern;; - applymbox) : ask gittus;; - applypatch) : ask gittus;; - archimport) : import;; - cat-file) : plumbing;; - check-attr) : plumbing;; - check-ignore) : plumbing;; - check-mailmap) : plumbing;; - check-ref-format) : plumbing;; - checkout-index) : plumbing;; - column) : internal helper;; - commit-tree) : plumbing;; - count-objects) : infrequent;; - credential) : credentials;; - credential-*) : credentials helper;; - cvsexportcommit) : export;; - cvsimport) : import;; - cvsserver) : daemon;; - daemon) : daemon;; - diff-files) : plumbing;; - diff-index) : plumbing;; - diff-tree) : plumbing;; - fast-import) : import;; - fast-export) : export;; - fsck-objects) : plumbing;; - fetch-pack) : plumbing;; - fmt-merge-msg) : plumbing;; - for-each-ref) : plumbing;; - hash-object) : plumbing;; - http-*) : transport;; - index-pack) : plumbing;; - init-db) : deprecated;; - local-fetch) : plumbing;; - ls-files) : plumbing;; - ls-remote) : plumbing;; - ls-tree) : plumbing;; - mailinfo) : plumbing;; - mailsplit) : plumbing;; - merge-*) : plumbing;; - mktree) : plumbing;; - mktag) : plumbing;; - pack-objects) : plumbing;; - pack-redundant) : plumbing;; - pack-refs) : plumbing;; - parse-remote) : plumbing;; - patch-id) : plumbing;; - prune) : plumbing;; - prune-packed) : plumbing;; - quiltimport) : import;; - read-tree) : plumbing;; - receive-pack) : plumbing;; - remote-*) : transport;; - rerere) : plumbing;; - rev-list) : plumbing;; - rev-parse) : plumbing;; - runstatus) : plumbing;; - sh-setup) : internal;; - shell) : daemon;; - show-ref) : plumbing;; - send-pack) : plumbing;; - show-index) : plumbing;; - ssh-*) : transport;; - stripspace) : plumbing;; - symbolic-ref) : plumbing;; - unpack-file) : plumbing;; - unpack-objects) : plumbing;; - update-index) : plumbing;; - update-ref) : plumbing;; - update-server-info) : daemon;; - upload-archive) : plumbing;; - upload-pack) : plumbing;; - write-tree) : plumbing;; - var) : infrequent;; - verify-pack) : infrequent;; - verify-tag) : plumbing;; - *) echo $i;; - esac - done + __git_all_commands=$(__git_list_commands all) } __git_porcelain_commands= __git_compute_porcelain_commands () { test -n "$__git_porcelain_commands" || - __git_porcelain_commands=$(__git_list_porcelain_commands) + __git_porcelain_commands=$(__git_list_commands porcelain) } # Lists all set config variables starting with the given section prefix,
git.c +2 -0
@@ -230,6 +230,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (NO_PARSEOPT ,' ' ); else if (!strcmp(cmd, "all"))list_all_cmds (); + else if (!strcmp(cmd, "porcelain")) +list_porcelain_cmds (); else die("unsupported command listing type '%s'", cmd);exit (0 );
help.c +12 -0
@@ -273,6 +273,18 @@ void list_all_cmds(void)clean_cmdnames (&other_cmds); } +void list_porcelain_cmds (void ) +{ +int i, nr =ARRAY_SIZE (command_list); +struct cmdname_help *cmds = command_list; + +for (i =0 ; i < nr; i++) { +if (cmds[i].category != CAT_mainporcelain) +continue ; +puts (cmds[i].name); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -18,6 +18,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds (void ); +extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd); extern void load_command_list(const char *prefix, struct cmdnames *main_cmds,
t/t9902-completion.sh +4 -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,9 @@ 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_COMPLETION=t +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.367.g5dd2e386c3
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 3 lines · Nguyễn Thái Ngọc Duy
This is useful for git-completion.bash because it needs this set of commands. Right now we have to maintain a separate command category in there.
I don't really understand this paragraph, in particular its second sentence. I would have described this change like this:
To get the list of commands offered after 'git <TAB>', the completion script filters out plumbing commands from the list of all git commands. To do so, it contains a long hard-coded list of the names of all known plumbing commands, which is redundant with the categorization in 'command-list.txt', is a maintenance burden, and tends to get out-of-sync when new plumbing commands are added.
Implement 'git --list-cmds=porcelain' to list only commands categorized as porcelains, so we can get rid of that long hard-coded command list from the completion script.
But then I noticed that it's not an accurate description of the current situation, because there is a wide grey area between porcelains and plumbing, and the completion script doesn't "filter out plumbing commands", but rather filters out commands that can be considered too low-level to be useful for "general" usage. Consequently, after 'git <TAB>' we also list:
- some 'ancillaryinterrogators': blame, annotate, difftool, fsck, help
- some 'ancillarymanipulators': config, mergetool, remote
- some 'foreignscminterface': p4, request-pull, svn, send-email
- even some plumbing: apply, name-rev (though 'name-rev' could be omitted; we have 'git describe')
- and also all "unknown" 'git-foo' commands that can be found in $PATH, which can be the user's own git scripts or other git-related tools ('git-annex', Git LFS, etc.).
With this change we wouldn't list any of the above commands, but only those that are explicitly categorized as 'mainporcelain'. I'd much prefer the current behaviour.
Quoted 36 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.
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- contrib/completion/git-completion.bash | 106 +++---------------------- git.c | 2 + help.c | 12 +++ help.h | 1 + t/t9902-completion.sh | 6 +- 5 files changed, 31 insertions(+), 96 deletions(-)contrib/completion/git-completion.bash +0
-12@@ -859,101 +864,14 @@ __git_all_commands= __git_compute_all_commands () { test -n "$__git_all_commands" || - __git_all_commands=$(__git_list_all_commands) -} - -__git_list_porcelain_commands () -{ - local i IFS=" "$'\n' - __git_compute_all_commands - for i in $__git_all_commands - do - case $i in - *--*) : helper pattern;; - applymbox) : ask gittus;;
<...>
Quoted 1 line
- verify-tag) : plumbing;;
I will be glad to see this enormous list go.
Quoted 5 lines
contrib/completion/git-completion.bash +1
-3- *) echo $i;; - esac - done + __git_all_commands=$(__git_list_commands all) }
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 17 lines · SZEDER Gábor
But then I noticed that it's not an accurate description of the current situation, because there is a wide grey area between porcelains and plumbing, and the completion script doesn't "filter out plumbing commands", but rather filters out commands that can be considered too low-level to be useful for "general" usage. Consequently, after 'git <TAB>' we also list:
- some 'ancillaryinterrogators': blame, annotate, difftool, fsck, help
- some 'ancillarymanipulators': config, mergetool, remote
- some 'foreignscminterface': p4, request-pull, svn, send-email
- even some plumbing: apply, name-rev (though 'name-rev' could be omitted; we have 'git describe')
- and also all "unknown" 'git-foo' commands that can be found in $PATH, which can be the user's own git scripts or other git-related tools ('git-annex', Git LFS, etc.).
Quoted 3 lines
With this change we wouldn't list any of the above commands, but only those that are explicitly categorized as 'mainporcelain'. I'd much prefer the current behaviour.
Yeah I noticed this (kinda) with filter-branch but I did not look further to see all this. It's good that you review this series then :)
For the first group (known commands), how about we add a new category "completion" in command-list.txt? Each command may belong to multiple categories (and my updated script has to deal with that [1]). For the second group, we could also have a special "external" category that is produced at run time, not specified in command-list.txt. --list-cmds option either has to accept multiple values, or we accept multiple --list-cmds=<category> options.
git-completion.bash will be updated to ask git "give me the commands in the mainporcelain, completable or external category". This also addresses another thing that bugs me: I wanted an option to let me complete all commands instead of just porcelain. This approach kinda generalizes that and it would be easy to let the user choose what category they want to complete.
[1] which also means I could bring "deprecated" category back.
Signature · 1 line
Duy
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 6 lines · Duy Nguyen
git-completion.bash will be updated to ask git "give me the commands in the mainporcelain, completable or external category". This also addresses another thing that bugs me: I wanted an option to let me complete all commands instead of just porcelain. This approach kinda generalizes that and it would be easy to let the user choose what category they want to complete.
To complete this: there could also be yet another special category "custom", where --list-cmds=custom simply returns a list of commands specified in config file. With this the user can pick the "custom" category to have total control of what command shows up at "git <tab>" if they are not satisfied with the predefined categories.
Signature · 1 line
Duy
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 8 lines · Duy Nguyen
Quoted 6 lines · Duy Nguyen
git-completion.bash will be updated to ask git "give me the commands in the mainporcelain, completable or external category". This also addresses another thing that bugs me: I wanted an option to let me complete all commands instead of just porcelain. This approach kinda generalizes that and it would be easy to let the user choose what category they want to complete.
Quoted 5 lines
To complete this: there could also be yet another special category "custom", where --list-cmds=custom simply returns a list of commands specified in config file. With this the user can pick the "custom" category to have total control of what command shows up at "git <tab>" if they are not satisfied with the predefined categories.
Note that config settings can be repository-specific, which might cause surprises if the user sets a custom command list in one repository's config file, but not (or a different one!) in others. Then the list of completed commands will depend on where the user happened to be when first hitting 'git <TAB>'. Unless you forgo caching the list of commands and run 'git --list-cmds=...' every time the user hits 'git <TAB>', but that will add the overhead of fork()ing a subshell and a git command.
Once upon a time I toyed with the idea of introducing environment variables like $GIT_COMPLETION_EXCLUDE_COMMANDS and $GIT_COMPLETION_INCLUDE_COMMANDS, to exclude and include commands from 'git <TAB>'. I wanted to exclude 'git cherry', because I have never ever used it but it's always in the way when I want to cherry-pick. And I wanted to include 'git for-each-ref' back when I was running it frequently while working on speeding up refs completion, but it wouldn't have brought that much benefits, because I have a 'git for-each-commit' script, too.
Never really pursued it, though, just patched the long list in __git_list_porcelain_commands() in my git clone :)
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 15 lines · SZEDER Gábor
Quoted 8 lines · Duy Nguyen
Quoted 6 lines · Duy Nguyen
git-completion.bash will be updated to ask git "give me the commands in the mainporcelain, completable or external category". This also addresses another thing that bugs me: I wanted an option to let me complete all commands instead of just porcelain. This approach kinda generalizes that and it would be easy to let the user choose what category they want to complete.
Quoted 5 lines
To complete this: there could also be yet another special category "custom", where --list-cmds=custom simply returns a list of commands specified in config file. With this the user can pick the "custom" category to have total control of what command shows up at "git <tab>" if they are not satisfied with the predefined categories.
Quoted 5 lines
Note that config settings can be repository-specific, which might cause surprises if the user sets a custom command list in one repository's config file, but not (or a different one!) in others. Then the list of completed commands will depend on where the user happened to be when first hitting 'git <TAB>'.
I think that is expected when the word "config file" is mentioned. It's no different than aliases, which could also be repo specific and affects completion.
Quoted 4 lines
Unless you forgo
caching the list of commands and run 'git --list-cmds=...' every time the user hits 'git <TAB>', but that will add the overhead of fork()ing a subshell and a git command.
This is a good point. I'd rather forgo caching iff the "custom" strategy is used (technically we could still cache if we know the source if $HOME/.gitconfig or higher but it's not worth the effort). Just make it clear to the user that if they go with "custom" strategy then they may hit some performance hit.
Quoted 11 lines
Once upon a time I toyed with the idea of introducing environment variables like $GIT_COMPLETION_EXCLUDE_COMMANDS and $GIT_COMPLETION_INCLUDE_COMMANDS, to exclude and include commands from 'git <TAB>'. I wanted to exclude 'git cherry', because I have never ever used it but it's always in the way when I want to cherry-pick. And I wanted to include 'git for-each-ref' back when I was running it frequently while working on speeding up refs completion, but it wouldn't have brought that much benefits, because I have a 'git for-each-commit' script, too.
Never really pursued it, though, just patched the long list in__git_list_porcelain_commands()in my git clone :)
I'm tempted to support "delta custom list" (e.g. "+cherry-pick" in the config variable means "add that command on the existing list", or "-blame" means exclude it) but that's probably too much work.
Signature · 1 line
Duy
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
In reply to Nguyễn Thái Ngọc Duycontrib/completion/git-completion.bash __git_complete_strategy () · line 836
Quoted 7 lines · Nguyễn Thái Ngọc Duy
contrib/completion/git-completion.bash +1
-0@@ -835,18 +835,23 @@ __git_complete_strategy () +__git_list_commands ()
Please add a comment before this function to mention its mandatory argument and that is should correspond to a category in 'command-list.txt'
contrib/completion/git-completion.bash __git_complete_strategy () · line 838
Quoted 3 lines
contrib/completion/git-completion.bash +0
-2-__git_list_all_commands () -__git_list_porcelain_commands ()
Users can have their own completion scriptlets for their own git commands, and these should be able to rely on helper functions in git-completion.bash to do things like refs completion and what not. Therefore, we tend not to remove or alter those helper functions in a backwards incompatible way, because we don't want to break those completion scriptlets.
Your patch removes these two functions. At first I let it slide, because first I thought that anyone who needs the list of all git commands is better off calling __git_compute_all_commands() and then using $__git_all_commands (same goes for porcelains), because it involves less fork()ed subshells and external processes. Then I thought why would anyone possibly need the list of git commands in a custom completion scriptlet in the first place... what for?!
Well, it turns out that there is at least one completion script out there that does rely on __git_list_all_commands() [1].
Please keep these two functions as a thin wrapper around __git_list_commands().
[1] And in a rather curious way at that:
https://github.com/github/hub/blob/master/etc/hub.bash_completion.sh#L12
Re: [PATCH v3 4/6] git.c: implement --list-cmds=porcelain
Quoted 10 lines · SZEDER Gábor
Review
Quoted 3 lines
(quoted diff) +0
-2-__git_list_all_commands () -__git_list_porcelain_commands ()Users can have their own completion scriptlets for their own git commands, and these should be able to rely on helper functions in git-completion.bash to do things like refs completion and what not. Therefore, we tend not to remove or alter those helper functions in a backwards incompatible way, because we don't want to break those completion scriptlets.
What kind of "API" guarantee do we provide here? I don't mind adding the wrappers, but for me it's hard for new contributors (like me) to see which one should be stable and which one is internal.
Signature · 1 line
Duy
PATCH v3 5/6 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 | 69 ++++++++++++++++++++++++++++++++++++++ help.h | 1 + t/t0012-help.sh | 9 +++++ 5 files changed, 89 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 +69 -0
75 lines not on this page · raw message
help.h +1 -0
@@ -17,6 +17,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_all_cmds (void );extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd);
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.367.g5dd2e386c3
PATCH v3 6/6 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 lists guides in git.txt, but I'll leave that for now.
--- Documentation/gitattributes.txt | 2 +- Documentation/gitmodules.txt | 2 +- Documentation/gitrevisions.txt | 2 +- builtin/help.c | 32 -------------------------------- command-list.txt | 8 ++++++++ generate-cmdlist.sh | 6 +++++- help.c | 22 ++++++++++++++++++++++ help.h | 1 + 8 files changed, 39 insertions(+), 36 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 --------
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 +8 -0
@@ -149,3 +149,11 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +giteveryday guide +gitglossary guide +gitignore guide +gitmodules guide +gitrevisions guide +gittutorial guide +gitworkflows guide
generate-cmdlist.sh +5 -1
@@ -58,7 +58,11 @@ command_list "$1" | sort | while read cmd category tags do - prefix=git- + if [ "$category" = guide ]; then + prefix=git + else + prefix=git- + fi name=$(echo $cmd | sed "s/^${prefix}//") sed -n ' /^NAME/,/'"$cmd"'/H
help.c +22 -0
@@ -314,6 +314,28 @@ static void list_commands_by_category(int cat, struct cmdname_help *cmds, } } +void list_common_guides_help (void ) +{ +int i, longest =0 ; +int nr =ARRAY_SIZE (command_list); +struct cmdname_help *cmds = command_list; + +QSORT (cmds, nr, cmd_category_cmp); + +for (i =0 ; i < nr; i++) { +struct cmdname_help *cmd = cmds + i; + +if (cmd->category != CAT_guide) +continue ; +if (longest <strlen (cmd->name)) + longest =strlen (cmd->name); + } + +puts (_ ("The common Git guides are:\n" )); +list_commands_by_category (CAT_guide, cmds, nr, longest); +putchar ('\n' ); +} +void list_all_cmds_help (void ) {int i, longest =0 ;
help.h +1 -0
@@ -18,6 +18,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_cmds (void );extern void list_porcelain_cmds (void );extern const char *help_unknown_cmd (const char *cmd);
Signature · 1 line
2.17.0.367.g5dd2e386c3
Re: [PATCH v3 6/6] help: use command-list.txt for the source of guides
generate-cmdlist.sh command_list "$1" | · line 59
Quoted 13 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 lists guides in git.txt, but I'll leave that for now.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +1
-1@@ -58,7 +58,11 @@ command_list "$1" | do - prefix=git- + if [ "$category" = guide ]; then
Style:
if test "$category" = guide
then
...
Quoted 4 lines
generate-cmdlist.sh +4
-0+ prefix=git + else + prefix=git- + fi
Quoted 7 lines · Nguyễn Thái Ngọc Duy
Changes:
- remove the deprecated column in command-list.txt. My change break it anyway if anyone uses it.
- fix up failed tests that I marked in the RFC and kinda forgot about it.
- fix bashisms ingenerate-cmdlist.sh
- fix segfaul in "git help"
Sorry I forgot the interdiff
command-list.txt +1 -1
@@ -9,7 +9,7 @@ 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 name category [common] git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators
contrib/completion/git-completion.bash +11 -7
@@ -835,19 +835,23 @@ __git_complete_strategy () } __git_commands () { - if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" + if test -n "$GIT_TESTING_COMPLETION" then - printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" + case "$1" in + porcelain) + printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST";; + all) + printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST";; + esac else git --list-cmds=$1 fi } -__git_list_all_commands () +__git_list_commands () { local i IFS=" "$'\n' - local category=${1-all} - for i in $(__git_commands $category) + for i in $(__git_commands $1) do case $i in *--*) : helper pattern;;
@@ -860,14 +864,14 @@ __git_all_commands= __git_compute_all_commands () { test -n "$__git_all_commands" || - __git_all_commands=$(__git_list_all_commands) + __git_all_commands=$(__git_list_commands all) } __git_porcelain_commands= __git_compute_porcelain_commands () { test -n "$__git_porcelain_commands" || - __git_porcelain_commands=$(__git_list_all_commands porcelain) + __git_porcelain_commands=$(__git_list_commands porcelain) } # Lists all set config variables starting with the given section prefix,
generate-cmdlist.sh +4 -12
@@ -36,7 +36,7 @@ sed -n ' ' "$1" printf '};\n\n' -echo "#define GROUP_NONE 0xff /* no common group */" +echo "#define GROUP_NONE 0xff" n=0 while read grp do
@@ -45,15 +45,6 @@ do done <"$grps" echo -echo '/*' -printf 'static const char *cmd_categories[] = {\n' -category_list "$1" | -while read category; do - printf '\t\"'$category'\",\n' -done -printf '\tNULL\n};\n\n' -echo '*/' - n=0 category_list "$1" | while read category; do
@@ -68,10 +59,11 @@ sort | while read cmd category tags do if [ "$category" = guide ]; then - name=${cmd/git} + prefix=git else - name=${cmd/git-} + prefix=git- fi + name=$(echo $cmd | sed "s/^${prefix}//") sed -n ' /^NAME/,/'"$cmd"'/H ${
help.c +2 -1
@@ -201,7 +201,8 @@ static void extract_common_cmds(struct cmdname_help **p_common_cmds,for (i =0 ; i <ARRAY_SIZE (command_list); i++) {const struct cmdname_help *cmd = command_list + i; -if (cmd->category != CAT_mainporcelain) +if (cmd->category != CAT_mainporcelain || + cmd->group ==GROUP_NONE )continue ; common_cmds[nr++] = *cmd;
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 &&
t/t9902-completion.sh +7 -3
@@ -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,9 @@ 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_COMPLETION=t +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"
@@ -1208,6 +1210,8 @@ test_expect_success 'basic' ' grep -q "^add \$" out && # script grep -q "^filter-branch \$" out && + # plumbing + ! grep -q "^ls-files \$" out && run_completion "git f" && ! grep -q -v "^f" out
@@ -1270,7 +1274,7 @@ test_expect_success 'general options' ' test_completion "git --no-r" "--no-replace-objects " ' -test_expect_failure 'general options plus command' ' +test_expect_success 'general options plus command' ' test_completion "git --version check" "checkout " && test_completion "git --paginate check" "checkout " && test_completion "git --git-dir=foo check" "checkout " &&
Quoted 11 lines · Duy Nguyen
Quoted 7 lines · Nguyễn Thái Ngọc Duy
Changes:
- remove the deprecated column in command-list.txt. My change break it anyway if anyone uses it.
- fix up failed tests that I marked in the RFC and kinda forgot about it.
- fix bashisms ingenerate-cmdlist.sh
- fix segfaul in "git help"Sorry I forgot the interdiff
[snip]
Quoted 7 lines
t/t0012-help.sh +0
-0@@ -25,6 +25,15 @@ test_expect_success "setup" ' EOF '
t/t0012-help.sh test_expect_success "setup" ' · line 36
Quoted 10 lines
t/t0012-help.sh +9
-0+# 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 +' +
I think you need to try a little harder than this! ;-)
This test would not have noticed the recent failure (what annoyed me was that git build without error and then the test-suite sailed through with nary a squeak of complaint). Viz:
$ ./git help
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]These are common Git commands used in various situations:
'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.
$ echo $? 0 $
$ ./git help -g The common Git guides are:
'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.
$ echo $? 0 $
$ ./git help -av Main Porcelain Commands
Ancillary Commands / Manipulators
Ancillary Commands / Interrogators
Interacting with Others
Low-level Commands / Manipulators
Low-level Commands / Interrogators
Low-level Commands / Synching Repositories
Low-level Commands / Internal Helpers
$ echo $? 0 $
I started to add some tests, like so:
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index fd2a7f27d..7e10c2862 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -49,6 +49,22 @@ 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 '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'
These tests, while not rigorous, did at least correctly catch the bad build for me. I was about to add the obvious one for 'git help -av', when I decided to catch the problem 'at source', viz:
diff --git a/help.c b/help.c
index a47f7e2c4..13790bb54 100644
--- a/help.c
+++ b/help.c
@@ -196,6 +196,9 @@ static void extract_common_cmds(struct cmdname_help **p_common_cmds,
int i, nr = 0;
struct cmdname_help *common_cmds;
+ if (ARRAY_SIZE(command_list) == 0)
+ BUG("empty command_list");
+
ALLOC_ARRAY(common_cmds, ARRAY_SIZE(command_list)); for (i = 0; i < ARRAY_SIZE(command_list); i++) {
@@ -279,6 +282,9 @@ void list_porcelain_cmds(void)
int i, nr = ARRAY_SIZE(command_list);
struct cmdname_help *cmds = command_list; + if (nr == 0)
+ BUG("empty command_list");
+
for (i = 0; i < nr; i++) {
if (cmds[i].category != CAT_mainporcelain)
continue;
@@ -321,6 +327,9 @@ void list_common_guides_help(void)
int nr = ARRAY_SIZE(command_list);
struct cmdname_help *cmds = command_list;
+ if (nr == 0)
+ BUG("empty command_list");
+
QSORT(cmds, nr, cmd_category_cmp); for (i = 0; i < nr; i++) {
@@ -343,6 +352,9 @@ void list_all_cmds_help(void)
int nr = ARRAY_SIZE(command_list);
struct cmdname_help *cmds = command_list; + if (nr == 0)
+ BUG("empty command_list");
+
for (i = 0; i < nr; i++) {
struct cmdname_help *cmd = cmds + i;This had a very dramatic effect on the test-suite, since every single test file failed while sourcing 'test-lib.sh'. [The test for having built git ('"$GIT_BUILD_DIR/git" >/dev/null') tries to output help, because you haven't given a command, and hits BUG - core dump!]
I haven't tried this patch series yet (I will hopefully find some time tonight), but it looks like it will fix the problem.
ATB,
Ramsay Jones
Quoted 24 lines · Ramsay Jones
Quoted 11 lines · Duy Nguyen
Quoted 7 lines · Nguyễn Thái Ngọc Duy
Changes:
- remove the deprecated column in command-list.txt. My change break it anyway if anyone uses it.
- fix up failed tests that I marked in the RFC and kinda forgot about it.
- fix bashisms ingenerate-cmdlist.sh
- fix segfaul in "git help"Sorry I forgot the interdiff
[snip]
Quoted 8 lines
t/t0012-help.sh +0
-0@@ -25,6 +25,15 @@ test_expect_success "setup" ' EOF '
Quoted 10 lines
t/t0012-help.sh test_expect_success "setup" ' · line 36
Quoted 9 lines
t/t0012-help.sh +9
-0+# 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 +' +I think you need to try a little harder than this! ;-)
Yeah. I did think about grepping the output but decided not to because of gettext poison stuff and column output in "git help". If we do want to test this, how about I extend --list-cmds= option to take a few more parameters? --list-cmds=common would output all common commands, --list-cmds=<category> does the same for other command category. This way we can verify without worrying about text formatting, paging or translation.
Signature · 1 line
Duy
Quoted 37 lines · Duy Nguyen
Quoted 24 lines · Ramsay Jones
Quoted 11 lines · Duy Nguyen
Quoted 7 lines · Nguyễn Thái Ngọc Duy
Changes:
- remove the deprecated column in command-list.txt. My change break it anyway if anyone uses it.
- fix up failed tests that I marked in the RFC and kinda forgot about it.
- fix bashisms ingenerate-cmdlist.sh
- fix segfaul in "git help"Sorry I forgot the interdiff
[snip]
Quoted 8 lines
t/t0012-help.sh +0
-0@@ -25,6 +25,15 @@ test_expect_success "setup" ' EOF 'Quoted 10 lines
t/t0012-help.sh test_expect_success "setup" ' · line 36
Quoted 9 lines
t/t0012-help.sh +9
-0+# 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 +' +I think you need to try a little harder than this! ;-)
Quoted 7 lines
Yeah. I did think about grepping the output but decided not to because of gettext poison stuff and column output in "git help". If we do want to test this, how about I extend --list-cmds= option to take a few more parameters? --list-cmds=common would output all common commands, --list-cmds=<category> does the same for other command category. This way we can verify without worrying about text formatting, paging or translation.
Hmm, my immediate reaction would be to prefer my simple tests. Yes, they are not exactly rigorous and they would be affected by changing the help formatting, but they are effective. ;-)
[I don't think the formatting would change that often, or at all - whoever submits that patch would get to update the tests!]
What did you think about adding the BUG() checks?
ATB,
Ramsay Jones
Quoted 10 lines · Ramsay Jones
Quoted 9 lines
Quoted 1 line
I think you need to try a little harder than this! ;-)
Yeah. I did think about grepping the output but decided not to because of gettext poison stuff and column output in "git help". If we do want to test this, how about I extend --list-cmds= option to take a few more parameters? --list-cmds=common would output all common commands, --list-cmds=<category> does the same for other command category. This way we can verify without worrying about text formatting, paging or translation.
Quoted 6 lines
Hmm, my immediate reaction would be to prefer my simple tests. Yes, they are not exactly rigorous and they would be affected by changing the help formatting, but they are effective. ;-)
[I don't think the formatting would change that often, or at all - whoever submits that patch would get to update the tests!]
Hmm.. for non-column output that's true. "git help" with column output should probably fine as well because even though we add more and more commands every month, these are not marked common (and unlikely so). So yeah I agree.
Quoted 1 line
What did you think about adding the
BUG()checks?
I was thinking if there was a way to fail the build after running ./generate-cmds.sh and generating empty output but it does not sound easy to do. So yeah, BUG() checks sound good.
Signature · 1 line
Duy
Quoted 24 lines · Duy Nguyen
Quoted 10 lines · Ramsay Jones
Quoted 9 lines
Quoted 1 line
I think you need to try a little harder than this! ;-)
Yeah. I did think about grepping the output but decided not to because of gettext poison stuff and column output in "git help". If we do want to test this, how about I extend --list-cmds= option to take a few more parameters? --list-cmds=common would output all common commands, --list-cmds=<category> does the same for other command category. This way we can verify without worrying about text formatting, paging or translation.
Quoted 6 lines
Hmm, my immediate reaction would be to prefer my simple tests. Yes, they are not exactly rigorous and they would be affected by changing the help formatting, but they are effective. ;-)
[I don't think the formatting would change that often, or at all - whoever submits that patch would get to update the tests!]
Hmm.. for non-column output that's true. "git help" with column output should probably fine as well because even though we add more and more commands every month, these are not marked common (and unlikely so). So yeah I agree.
Quoted 5 lines
Quoted 1 line
What did you think about adding the
BUG()checks?I was thinking if there was a way to fail the build after running ./generate-cmds.sh and generating empty output but it does not sound easy to do. So yeah,
BUG()checks sound good.
Yeah, failing the build would be preferable, but I didn't get that far. ;-)
[BTW, I just applied your patch series to the 'next' branch (I just couldn't be bothered to revert your last series from the 'pu' branch, etc.) and, as expected, everything built OK, passed the test-suite and 'git help' is working just fine.]
Thanks!
ATB,
Ramsay Jones
cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc DuyThis is not exactly v4 and likely broken. But I've made several debatable changes and would like your opinions before making even more changes in this direction.
In 03/12 I made a format change in command-list.txt. The group description is no longer in this file but in help.c instead. This simplifies the format. However it may be harder for people to know what category means what (but then it's already so for a lot more categories).
In 11/12 I added the new "complete" category to command-list.txt so that we could replace the giant list in git-completion.bash. This is really questionable because several commands will NOT be completable anymore. These are listed there so we can discuss.
Another thing I wonder is, whether I should tag "nocomplete" instead of "complete" in command-list.txt, similar to parseopt's nocomplete
strategy: commands are completable by default then we just exclude some of them. The "complete" tag goes the opposite direction, we only show ones that are either external, "complete" or mainporcelain.
I think we would go with whitelist than blacklist though to avoid helper commands showing up by default...
Also in 02/12 I moved to fixed column format. Strictly speaking I do not need that (but it makes the code slightly more complex). If you are really against fixed column format, speak up now.
Nguyễn Thái Ngọc Duy (12):
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-*builtins to --list-cmds=*
git: accept multiple --list-cmds options
completion: implement and use --list-cmds=all
git: support --list-cmds=<category>
help: add "-a --verbose" to list all commands with synopsis
help: use command-list.txt for the source of guides command-list.txt: add new category "complete"
completion: let git provide the completable command list
.gitignore | 2 +- 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 | 55 ++++---- contrib/completion/git-completion.bash | 121 +++------------- generate-cmdlist.sh | 128 +++++++++++------ git.c | 19 ++- help.c | 186 +++++++++++++++++++++---- help.h | 4 + t/t0012-help.sh | 11 +- t/t9902-completion.sh | 5 +- 15 files changed, 344 insertions(+), 252 deletions(-)
Signature · 1 line
2.17.0.519.gb89679a4aa
PATCH 1/12 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 | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
generate-cmdlist.sh +13 -7
@@ -1,5 +1,17 @@ #!/bin/sh +get_synopsis () { + local cmd="$1" + + sed -n ' + /^NAME/,/'"$cmd"'/H + ${ + x + s/.*'"$cmd"' - \(.*\)/N_("\1")/ + p + }' "Documentation/$cmd.txt" +} + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { char name[16];
@@ -39,12 +51,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.519.gb89679a4aa
Re: [PATCH v4/wip 01/12] generate-cmds.sh: factor out synopsis extract code
generate-cmdlist.sh line 2
Quoted 9 lines · Nguyễn Thái Ngọc Duy
This makes it easier to reuse the same code in another place (very soon).
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +2
-0@@ -1,5 +1,17 @@ +get_synopsis () { + local cmd="$1"
'local' is a Bash-ism, isn't it?
Quoted 26 lines
generate-cmdlist.sh +10
-7+ sed -n ' + /^NAME/,/'"$cmd"'/H + ${ + x + s/.*'"$cmd"' - \(.*\)/N_("\1")/ + p + }' "Documentation/$cmd.txt" +} + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { char name[16];@@ -39,12 +51,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 "};"
Re: [PATCH v4/wip 01/12] generate-cmds.sh: factor out synopsis extract code
Quoted 5 lines · Eric Sunshine
Quoted 3 lines · Nguyễn Thái Ngọc Duy
This makes it easier to reuse the same code in another place (very soon).
Quoted 8 lines
generate-cmdlist.sh line 2
Quoted 6 lines
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +2
-0@@ -1,5 +1,17 @@ +get_synopsis () { + local cmd="$1"'local' is a Bash-ism, isn't it?
Well, strictly speaking it isn't, because many shells support it besides Bash.
I don't remember seeing any complaints about 01d3a526ad (t0000: check whether the shell supports the "local" keyword, 2017-10-26), but we only have that commit for a couple or months / two releases, so it's still too early to start using 'local' in build scripts.
PATCH 2/12 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.519.gb89679a4aa
Re: [PATCH v4/wip 02/12] generate-cmds.sh: export all commands to command-list.h
Quoted 12 lines · Nguyễn Thái Ngọc Duy
The current
generate-cmds.shgenerates 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:[...]Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +1
-0@@ -12,14 +34,51 @@ get_synopsis () { +define_categories() {
generate-cmdlist.sh get_synopsis () { · line 44
Quoted 10 lines
generate-cmdlist.sh +10
-0+ echo + echo "/* Command categories */" + bit=0 + category_list "$1" | + while read cat + do + echo "#define CAT_$cat (1UL << $bit)" + bit=$(($bit+1)) + done + test "$bit" -gt 32 && die "Urgh.. too many categories?"
Should this be '-ge' rather than '-gt'?
Quoted 1 line
generate-cmdlist.sh +1
-0+}
Re: [PATCH v4/wip 02/12] generate-cmds.sh: export all commands to command-list.h
Quoted 18 lines · Eric Sunshine
Quoted 16 lines · Nguyễn Thái Ngọc Duy
The current
generate-cmds.shgenerates 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:[...]Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
generate-cmdlist.sh +5
-0@@ -12,14 +34,51 @@ get_synopsis () { +define_categories() { + echo + echo "/* Command categories */" + bit=0 + category_list "$1" |
Quoted 8 lines
generate-cmdlist.sh get_synopsis () { · line 47
Quoted 6 lines
generate-cmdlist.sh +6
-0+ while read cat + do + echo "#define CAT_$cat (1UL << $bit)" + bit=$(($bit+1)) + done + test "$bit" -gt 32 && die "Urgh.. too many categories?"Should this be '-ge' rather than '-gt'?
After we print "1UL << 31" we increment it to 32 and exit the loop, then it's still within limits, -ge would incorrectly complain
Signature · 1 line
Duy
PATCH 3/12 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 | 135 ++++++++++++++++++++++++++++++++------------ 4 files changed, 103 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() {
@@ -67,7 +67,7 @@ echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { const char *name; const char *help; - uint32_t group; + uint32_t category; }; " if [ -z "$2" ]
help.c +99 -36
182 lines not on this page · raw message
Signature · 1 line
2.17.0.519.gb89679a4aa
PATCH 4/12 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.519.gb89679a4aa
PATCH 5/12 git.c: convert --list-*builtins 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.
--- contrib/completion/git-completion.bash | 2 +- git.c | 12 +++++++----- t/t0012-help.sh | 2 +- 3 files changed, 9 insertions(+), 7 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 +7 -5
@@ -223,11 +223,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 ,' ' ); + }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { +if (!strcmp (cmd,"builtins" )) +list_builtins (0 ,'\n' ); +else if (!strcmp (cmd,"parseopt" )) +list_builtins (NO_PARSEOPT ,' ' ); +else +die ("unsupported command listing type '%s'" , cmd);exit (0 ); }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);
t/t0012-help.sh +1 -1
@@ -50,7 +50,7 @@ test_expect_success "--help does not work for guides" " " test_expect_success 'generate builtin list' ' - git --list-builtins >builtins + git --list-cmds=builtins >builtins ' while read builtin
Signature · 1 line
2.17.0.519.gb89679a4aa
PATCH 6/12 git: accept multiple --list-cmds options
In reply to Nguyễn Thái Ngọc DuyLater on we may support non-overlapping command groups to --list-cmds. Allow the user to execute just one "git" process and get multiple groups. This may matter for git-completion.bash on Windows because we don't want the user to way for long when TAB-ing and Windows is slow on launching new processes.
--- git.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
git.c +4 -1
@@ -64,6 +64,7 @@ void setup_auto_pager(const char *cmd, int def)static int handle_options (const char ***argv,int *argc,int *envchanged) {const char **orig_argv = *argv; +int commands_listed =0 ;while (*argc >0 ) {const char *cmd = (*argv)[0 ];
@@ -230,7 +231,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (NO_PARSEOPT ,' ' ); else die("unsupported command listing type '%s'", cmd); -exit (0 ); + commands_listed++; }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);usage (git_usage_string);
@@ -239,6 +240,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argv)++; (*argc)--; } +if (commands_listed) +exit (0 );return (*argv) - orig_argv; }
Signature · 1 line
2.17.0.519.gb89679a4aa
Re: [PATCH v4/wip 06/12] git: accept multiple --list-cmds options
Quoted 4 lines · Nguyễn Thái Ngọc Duy
Later on we may support non-overlapping command groups to --list-cmds. Allow the user to execute just one "git" process and get multiple groups. This may matter for git-completion.bash on Windows because we don't want the user to way for long when TAB-ing and
s/way/wait/
Quoted 3 lines
Windows is slow on launching new processes.
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>
PATCH 7/12 completion: implement and use --list-cmds=all
In reply to Nguyễn Thái Ngọc DuyInstead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow, make git provide the list in machine-friendly form.
--- contrib/completion/git-completion.bash | 2 +- git.c | 2 ++ help.c | 18 ++++++++++++++++++ help.h | 1 + 4 files changed, 22 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=all fi }
git.c +2 -0
@@ -229,6 +229,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)list_builtins (0 ,'\n' ); else if (!strcmp(cmd, "parseopt"))list_builtins (NO_PARSEOPT ,' ' ); + else if (!strcmp(cmd, "all")) +list_all_cmds (); else die("unsupported command listing type '%s'", cmd); commands_listed++;
help.c +18 -0
@@ -287,6 +287,24 @@ void list_common_cmds_help(void)print_cmd_by_category (common_categories); } +void list_all_cmds (void ) +{ +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++) +puts (main_cmds.names[i]->name); +for (i =0 ; i < other_cmds.cnt; i++) +puts (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 +1 -0
@@ -17,6 +17,7 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_cmds (void );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.519.gb89679a4aa
PATCH 8/12 git: support --list-cmds=<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 | 2 +- help.c | 19 +++++++++++++++++++ help.h | 1 + 4 files changed, 38 insertions(+), 1 deletion(-)
generate-cmdlist.sh +17 -0
@@ -47,6 +47,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[] = {"
@@ -72,4 +87,6 @@ struct cmdname_help { " define_categories "$1" echo +define_category_names "$1" +echo print_command_list "$1"
git.c +1 -1
@@ -232,7 +232,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)else if (!strcmp (cmd,"all" ))list_all_cmds ();else -die ("unsupported command listing type '%s'" , cmd); +list_cmds_by_category (cmd); commands_listed++; }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);
help.c +19 -0
@@ -305,6 +305,25 @@ void list_all_cmds(void)clean_cmdnames (&other_cmds); } +void list_cmds_by_category (const char *cat) +{ +int i; +int cat_id =0 ; + +for (i =0 ; category_names[i]; i++) { +if (!strcmp (cat, category_names[i])) { + cat_id =1 << i; +break ; + } + } +if (!cat_id) +die ("unsupported command listing type '%s'" , cat); + +for (i =0 ; command_list[i].name; i++) +if (command_list[i].category & cat_id) +puts (command_list[i].name); +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -18,6 +18,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_cmds (void ); +extern void list_cmds_by_category (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.519.gb89679a4aa
Re: [PATCH v4/wip 08/12] git: support --list-cmds=<category>
Quoted 12 lines · Nguyễn Thái Ngọc Duy
This 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.
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>---
help.c void list_all_cmds(void) · line 308
Quoted 4 lines
help.c +4
-0@@ -305,6 +305,25 @@ void list_all_cmds(void) +void list_cmds_by_category (const char *cat) +{ +int i; +int cat_id =0 ;
Should 'cat_id' be unsigned...
help.c void list_all_cmds(void) · line 315
Quoted 4 lines
help.c +4
-0+ +for (i =0 ; category_names[i]; i++) { +if (!strcmp (cat, category_names[i])) { + cat_id =1 << i;
...since you're shifting it here?
Quoted 10 lines
help.c +10
-0+break ; + } + } +if (!cat_id) +die ("unsupported command listing type '%s'" , cat); + +for (i =0 ; command_list[i].name; i++) +if (command_list[i].category & cat_id) +puts (command_list[i].name); +}
PATCH 9/12 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 | 1 + t/t0012-help.sh | 9 +++++++++ 5 files changed, 36 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 void extract_cmds (struct cmdname_help **p_cmds,uint32_t mask) {
@@ -324,6 +335,11 @@ void list_cmds_by_category(const char *cat)puts (command_list[i].name); } +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 +1 -0
@@ -17,6 +17,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_all_cmds (void );extern void list_cmds_by_category (const char *category);extern const char *help_unknown_cmd (const char *cmd);
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.519.gb89679a4aa
PATCH 10/12 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 lists 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 | 8 ++++++++ help.c | 14 +++++++++++++- help.h | 1 + 8 files changed, 26 insertions(+), 37 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 +8 -0
@@ -139,3 +139,11 @@ gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators git-worktree mainporcelain git-write-tree plumbingmanipulators +gitattributes guide +giteveryday guide +gitglossary guide +gitignore guide +gitmodules guide +gitrevisions guide +gittutorial guide +gitworkflows guide
help.c +13 -1
@@ -55,7 +55,9 @@ static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask) cmds[nr] = *cmd; -if (skip_prefix (cmd->name,"git-" , &name)) +if (skip_prefix (cmd->name,"git-" , &name) || + (mask == CAT_guide && +skip_prefix (cmd->name,"git" , &name))) cmds[nr].name = name; nr++;
@@ -335,6 +337,16 @@ void list_cmds_by_category(const char *cat)puts (command_list[i].name); } +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
@@ -18,6 +18,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_cmds (void );extern void list_cmds_by_category (const char *category);extern const char *help_unknown_cmd (const char *cmd);
Signature · 1 line
2.17.0.519.gb89679a4aa
Re: [PATCH v4/wip 10/12] help: use command-list.txt for the source of guides
Quoted 4 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 lists guides in git.txt, but I'll leave that for
s/lists/list/
Quoted 3 lines
now.
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>
PATCH 11/12 command-list.txt: add new category "complete"
In reply to Nguyễn Thái Ngọc DuyThis category, combined with 'external' and 'mainporcelain', is intended to replace the "porcelain command list" in git-completion.bash. In other words, these are the commands that will show up by default when you type "git <tab>".
Compared to the current list in git-completion.bash (which is basically "git help -a" with a black list), the following commands no longer show up:
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used
- get-tar-commit-id not often used
- imap-send not often used
- instaweb does anybody still run this interactively?
- interpreter-trailers not an interactive command
- lost-found obsolete - mergetool ??? - p4 too short to complete? - peek-remote not often used?? - svn ??? - tar-tree obsolete, use archive instead - verify-commit not often used
--- command-list.txt | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-)
command-list.txt +17 -16
@@ -3,11 +3,11 @@ git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +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
@@ -17,7 +17,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
@@ -25,7 +25,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
@@ -39,7 +39,7 @@ 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
@@ -48,13 +48,13 @@ git-filter-branch ancillarymanipulators 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-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
@@ -80,7 +80,7 @@ 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-pack-objects plumbingmanipulators
@@ -96,28 +96,29 @@ 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
@@ -136,7 +137,7 @@ git-verify-commit ancillaryinterrogators 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
Signature · 1 line
2.17.0.519.gb89679a4aa
PATCH 12/12 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.
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.
--- contrib/completion/git-completion.bash | 119 +++++-------------------- t/t9902-completion.sh | 5 +- 2 files changed, 25 insertions(+), 99 deletions(-)
contrib/completion/git-completion.bash +22 -97
@@ -835,18 +835,30 @@ __git_complete_strategy () } __git_commands () { - if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" - then - printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" - else - git --list-cmds=all - fi + case "$1" in + porcelain) + if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + then + printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + else + git --list-cmds=mainporcelain --list-cmds=complete + fi + ;; + all) + if test -n "$GIT_TESTING_ALL_COMMAND_LIST" + then + printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST";; + else + git --list-cmds=all + fi + ;; + esac } -__git_list_all_commands () +__git_list_commands () { local i IFS=" "$'\n' - for i in $(__git_commands) + for i in $(__git_commands $1) do case $i in *--*) : helper pattern;;
@@ -859,101 +871,14 @@ __git_all_commands= __git_compute_all_commands () { test -n "$__git_all_commands" || - __git_all_commands=$(__git_list_all_commands) -} - -__git_list_porcelain_commands () -{ - local i IFS=" "$'\n' - __git_compute_all_commands - for i in $__git_all_commands - do - case $i in - *--*) : helper pattern;; - applymbox) : ask gittus;; - applypatch) : ask gittus;; - archimport) : import;; - cat-file) : plumbing;; - check-attr) : plumbing;; - check-ignore) : plumbing;; - check-mailmap) : plumbing;; - check-ref-format) : plumbing;; - checkout-index) : plumbing;; - column) : internal helper;; - commit-tree) : plumbing;; - count-objects) : infrequent;; - credential) : credentials;; - credential-*) : credentials helper;; - cvsexportcommit) : export;; - cvsimport) : import;; - cvsserver) : daemon;; - daemon) : daemon;; - diff-files) : plumbing;; - diff-index) : plumbing;; - diff-tree) : plumbing;; - fast-import) : import;; - fast-export) : export;; - fsck-objects) : plumbing;; - fetch-pack) : plumbing;; - fmt-merge-msg) : plumbing;; - for-each-ref) : plumbing;; - hash-object) : plumbing;; - http-*) : transport;; - index-pack) : plumbing;; - init-db) : deprecated;; - local-fetch) : plumbing;; - ls-files) : plumbing;; - ls-remote) : plumbing;; - ls-tree) : plumbing;; - mailinfo) : plumbing;; - mailsplit) : plumbing;; - merge-*) : plumbing;; - mktree) : plumbing;; - mktag) : plumbing;; - pack-objects) : plumbing;; - pack-redundant) : plumbing;; - pack-refs) : plumbing;; - parse-remote) : plumbing;; - patch-id) : plumbing;; - prune) : plumbing;; - prune-packed) : plumbing;; - quiltimport) : import;; - read-tree) : plumbing;; - receive-pack) : plumbing;; - remote-*) : transport;; - rerere) : plumbing;; - rev-list) : plumbing;; - rev-parse) : plumbing;; - runstatus) : plumbing;; - sh-setup) : internal;; - shell) : daemon;; - show-ref) : plumbing;; - send-pack) : plumbing;; - show-index) : plumbing;; - ssh-*) : transport;; - stripspace) : plumbing;; - symbolic-ref) : plumbing;; - unpack-file) : plumbing;; - unpack-objects) : plumbing;; - update-index) : plumbing;; - update-ref) : plumbing;; - update-server-info) : daemon;; - upload-archive) : plumbing;; - upload-pack) : plumbing;; - write-tree) : plumbing;; - var) : infrequent;; - verify-pack) : infrequent;; - verify-tag) : plumbing;; - *) echo $i;; - esac - done + __git_all_commands=$(__git_list_commands all) } __git_porcelain_commands= __git_compute_porcelain_commands () { test -n "$__git_porcelain_commands" || - __git_porcelain_commands=$(__git_list_porcelain_commands) + __git_porcelain_commands=$(__git_list_commands porcelain) } # Lists all set config variables starting with the given section prefix,
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.519.gb89679a4aa
v5 cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc DuyI think v5 is getting close to what I wanted to achieve from the RFC version (I skip v4 since I sent out v4/wip and another v4 may confuse people).
Interdiff is too large to be helpful, but the summary of changes compared to v3 is:
- common-cmds.h is renamed to command-list.h
- the common group description is moved from command-list.txt to help.c to simplify command-list.txt format
- generate-cmds.sh supports multiple categories per command, a new one "complete" is added to aid git-completion.bash
- multiple --list-cmds options is replaced with --list-cmds=<type>[,<type>...]. This allows easier group customization in git-completion.bash (not happens yet)
- __git_list_all_commands() and __git_list_porcelain_commands() for backward compatibility
- "git help <tab>" completion also makes use of guide list in command-list.txt
- better tests from Ramsay
There is one sticky point yet about the guides. I'll pull Phillip in and explain more in the relevant patch.
Nguyễn Thái Ngọc Duy (10):
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-*builtins to --list-cmds=*
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
completion: let git provide the completable command list
.gitignore | 2 +- 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 | 67 ++++---- contrib/completion/git-completion.bash | 134 +++++----------- generate-cmdlist.sh | 126 ++++++++++----- git.c | 38 ++++- help.c | 209 +++++++++++++++++++++---- help.h | 5 + t/t0012-help.sh | 26 ++- t/t9902-completion.sh | 5 +- 15 files changed, 426 insertions(+), 251 deletions(-)
Signature · 1 line
2.17.0.664.g8924eee37a
PATCH v5 1/10 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.664.g8924eee37a
PATCH v5 2/10 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 \
@@ -1940,6 +1940,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):\
@@ -2150,7 +2155,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.
@@ -2529,7 +2534,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"; \
@@ -2777,7 +2782,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.664.g8924eee37a
PATCH v5 3/10 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
@@ -1916,9 +1916,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 [ -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.664.g8924eee37a
PATCH v5 4/10 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 \
@@ -1916,9 +1916,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)"' \
@@ -1937,11 +1937,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)
@@ -2155,7 +2150,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.
@@ -2534,7 +2529,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"; \
@@ -2782,7 +2777,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.664.g8924eee37a
PATCH v5 5/10 git.c: convert --list-*builtins 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.
This also allows combining multiple listing types, which is usually now (for combining parseopt and builtins) but future types will benefit from this.
--- contrib/completion/git-completion.bash | 2 +- git.c | 27 ++++++++++++++++++++------ t/t0012-help.sh | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-)
contrib/completion/git-completion.bash +1 -1
@@ -3044,7 +3044,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 +21 -6
@@ -38,6 +38,25 @@ static int use_pager = -1;static void list_builtins (unsigned int exclude_option,char sep); +static int list_cmds (const char *spec) +{ +while (*spec) { +const char *sep =strchrnul (spec,',' ); +int len = sep - spec; + +if (len ==8 && !strncmp (spec,"builtins" ,8 )) +list_builtins (0 ,'\n' ); +else if (len ==8 && !strncmp (spec,"parseopt" ,8 )) +list_builtins (NO_PARSEOPT ,' ' ); +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 +242,8 @@ 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)) { +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.664.g8924eee37a
PATCH v5 6/10 completion: implement and use --list-cmds=main,others
In reply to Nguyễn Thái Ngọc DuyInstead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow, make git provide the list in a machine-friendly form. This adds two separate listing types, main and others, instead of just "all" for more flexibility.
--- contrib/completion/git-completion.bash | 2 +- git.c | 4 ++++ help.c | 32 ++++++++++++++++++++++++++ help.h | 2 ++ 4 files changed, 39 insertions(+), 1 deletion(-)
contrib/completion/git-completion.bash +1 -1
@@ -834,7 +834,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
@@ -48,6 +48,10 @@ static int list_cmds(const char *spec)list_builtins (0 ,'\n' ); else if (len == 8 && !strncmp(spec, "parseopt", 8))list_builtins (NO_PARSEOPT ,' ' ); + else if (len == 4 && !strncmp(spec, "main", 4)) +list_all_main_cmds (); + else if (len == 6 && !strncmp(spec, "others", 6)) +list_all_other_cmds (); 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 (void ) +{ +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++) +puts (main_cmds.names[i]->name); + +clean_cmdnames (&main_cmds); +clean_cmdnames (&other_cmds); +} + +void list_all_other_cmds (void ) +{ +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++) +puts (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 +2 -0
@@ -17,6 +17,8 @@ static inline void mput_char(char c, unsigned int num) }extern void list_common_cmds_help (void ); +extern void list_all_main_cmds (void ); +extern void list_all_other_cmds (void );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.664.g8924eee37a
PATCH v5 7/10 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 | 22 ++++++++++++++++++++++ help.h | 1 + 4 files changed, 47 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
@@ -52,6 +52,13 @@ static int list_cmds(const char *spec)list_all_main_cmds (); else if (len == 6 && !strncmp(spec, "others", 6))list_all_other_cmds (); + else if (len > 5 && !strncmp(spec, "list-", 5)) { +struct strbuf sb =STRBUF_INIT ; + +strbuf_add (&sb, spec +5 , len -5 ); +list_cmds_by_category (sb.buf); +strbuf_release (&sb); + } else die(_("unsupported command listing type '%s'"), spec); spec += len;
help.c +22 -0
@@ -329,6 +329,28 @@ void list_all_other_cmds(void)clean_cmdnames (&other_cmds); } +void list_cmds_by_category (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) +puts (drop_prefix (cmd->name)); + } +} +int is_in_cmdlist (struct cmdnames *c,const char *s) {int i;
help.h +1 -0
@@ -19,6 +19,7 @@ static inline void mput_char(char c, unsigned int num)extern void list_common_cmds_help (void );extern void list_all_main_cmds (void );extern void list_all_other_cmds (void ); +extern void list_cmds_by_category (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.664.g8924eee37a
PATCH v5 8/10 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 | 1 + t/t0012-help.sh | 9 +++++++++ 5 files changed, 36 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) {
@@ -351,6 +362,11 @@ void list_cmds_by_category(const char *cat) } } +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 +1 -0
@@ -17,6 +17,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_all_main_cmds (void );extern void list_all_other_cmds (void );extern void list_cmds_by_category (const char *category);
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.664.g8924eee37a
PATCH v5 9/10 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 | 18 ++++++++++++--- help.h | 1 + t/t0012-help.sh | 6 +++++ 10 files changed, 52 insertions(+), 44 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
@@ -1939,7 +1939,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
@@ -1570,6 +1570,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
@@ -1579,11 +1586,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 +15 -3
@@ -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,10 +360,20 @@ void list_cmds_by_category(const char *cat)struct cmdname_help *cmd = command_list + i;if (cmd->category & cat_id) -puts (drop_prefix (cmd->name)); +puts (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
@@ -18,6 +18,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 (void );extern void list_all_other_cmds (void );extern void list_cmds_by_category (const char *category);
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.664.g8924eee37a
Re: [PATCH v5 09/10] help: use command-list.txt for the source of guides
Phillip (and others) the changes in this patch make "git help -g" now lists a lot more guides than just the "common" one as advertised (see below for the exact list). The man page for "git help -g" also mentions that it would list "useful" guides, not all guides. But we have no way to list all guides as far as I can tell.
I guess we have two options forward:
- keep "help -g" to common guide (we can tag common guides in command-list.txt) and add a new option to list all guides ("help -ag"?)
- reword the man page to make "help -g" list all guides
I'm ok with either direction. What's your preference?
For comparison, this is the new output
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 namespaces Git namespaces repository-layout Git Repository Layout revisions Specifying revisions and ranges for Git tutorial A tutorial introduction to Git tutorial-2 A tutorial introduction to Git: part two workflows An overview of recommended workflows with Git
compared to the old version
The common Git guides are:
attributes Defining attributes per path everyday Everyday Git With 20 Commands Or So glossary A Git glossary ignore Specifies intentionally untracked files to ignore modules Defining submodule properties revisions Specifying revisions and ranges for Git tutorial A tutorial introduction to Git (for version 1.5.1 or
newer)
workflows An overview of recommended workflows with Git
Quoted 255 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 | 18 ++++++++++++--- help.h | 1 + t/t0012-help.sh | 6 +++++ 10 files changed, 52 insertions(+), 44 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@@ -1939,7 +1939,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@@ -1570,6 +1570,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@@ -1579,11 +1586,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 +15
-3@@ -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,10 +360,20 @@ void list_cmds_by_category(const char *cat)struct cmdname_help *cmd = command_list + i;if (cmd->category & cat_id) -puts (drop_prefix (cmd->name)); +puts (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@@ -18,6 +18,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 (void );extern void list_all_other_cmds (void );extern void list_cmds_by_category (const char *category);t/t0012-help.sh +6
-1@@ -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 --2.17.0.664.g8924eee37a
Signature · 1 line
Duy
PATCH v5 10/10 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 are not part of neither list-mainporcelain nor list-complete and as a result no longer completes:
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - lost-found obsolete - p4 too short and probably not often used (*) - peek-remote deprecated - svn same category as p4 (*) - tar-tree obsolete - verify-commit not often used
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.
(*) 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 should include them.
--- command-list.txt | 37 ++++---- contrib/completion/git-completion.bash | 117 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 48 insertions(+), 111 deletions(-)
command-list.txt +19 -18
@@ -3,11 +3,11 @@ git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +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
@@ -17,7 +17,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
@@ -25,7 +25,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
@@ -39,7 +39,7 @@ 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
@@ -48,20 +48,20 @@ git-filter-branch ancillarymanipulators 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-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-index-pack plumbingmanipulators git-init mainporcelain init -git-instaweb ancillaryinterrogators +git-instaweb ancillaryinterrogators complete git-interpret-trailers purehelpers gitk mainporcelain git-log mainporcelain info
@@ -75,12 +75,12 @@ 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-pack-objects plumbingmanipulators
@@ -96,28 +96,29 @@ 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
@@ -136,7 +137,7 @@ git-verify-commit ancillaryinterrogators 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 +26 -91
139 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.664.g8924eee37a
This is probably scope creep for this series, but do you guys think we should do the same for config variables completion? We currently maintain a giant list at the end of _git_config(). Extracting the list from Documentation/config.txt to keep it in a C array does not look super hard. There will be some special handling for advice.* or color.<slot>... but overall I still think it's a net gain.
Listing all recognizable config variables from "git config" (or "git help") would be lovely, but I don't think it helps unless we could print a short summary line each variable, but this info is not available anywhere.
--
Duy
v6 cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc Duyv6 is now "feature complete". v6 adds
- documentation in command-list.txt so people know how to update it
- support for config key completion.commands, which consists of extra commands. It could also be used for excluding some commands.
Interdiff
command-list.txt +44 -0
@@ -1,3 +1,47 @@ +# 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. +# +# While not true commands, 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
contrib/completion/git-completion.bash +35 -0
@@ -38,6 +38,38 @@ # # 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 defaults add some extra commands specified +# in the configuration variable completion.commands [1] with +# +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,others,list-complete,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. +# +# [1] Note that completion.commands should not be per-repository +# since the command list is generated once and cached. +# +# completion.commands could be used to exclude commands as +# well. If a command in this list begins with '-', then it +# will be excluded from the list of commands gathered by the +# groups specified before "config" in +# $GIT_COMPLETION_CMD_GROUPS. case "$COMP_WORDBREAKS" in *:*) : great ;;
@@ -840,6 +872,9 @@ __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 fi
git.c +27 -10
@@ -36,27 +36,30 @@ 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 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 (len ==8 && !strncmp (spec,"builtins" ,8 )) -list_builtins (0 ,'\n' ); -else if (len ==8 && !strncmp (spec,"parseopt" ,8 )) -list_builtins (NO_PARSEOPT ,' ' ); +list_builtins (&list,0 );else if (len ==4 && !strncmp (spec,"main" ,4 )) -list_all_main_cmds (); +list_all_main_cmds (&list);else if (len ==6 && !strncmp (spec,"others" ,6 )) -list_all_other_cmds (); +list_all_other_cmds (&list); +else if (len ==6 && !strncmp (spec,"config" ,6 )) +list_cmds_by_config (&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 (sb.buf); +list_cmds_by_category (&list, sb.buf);strbuf_release (&sb); }else
@@ -65,6 +68,9 @@ static int list_cmds(const char *spec)if (*spec ==',' ) spec++; } +for (i =0 ; i < list.nr; i++) +puts (list.items[i].string); +string_list_clear (&list,0 );return 0 ; }
@@ -254,7 +260,18 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argv)++; (*argc)--; }else if (skip_prefix (cmd,"--list-cmds=" , &cmd)) { -exit (list_cmds (cmd)); +if (!strcmp (cmd,"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)); + } }else {fprintf (stderr,_ ("unknown option: %s\n" ), cmd);usage (git_usage_string);
@@ -534,14 +551,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); } }
help.c +42 -7
83 lines not on this page · raw message
help.h +8 -3
@@ -1,6 +1,8 @@ #ifndef HELP_H #define HELP_H +struct string_list; + struct cmdnames { int alloc; int cnt;
@@ -19,9 +21,12 @@ 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 (void ); -extern void list_all_other_cmds (void ); -extern void list_cmds_by_category (const char *category); + +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,
Nguyễn Thái Ngọc Duy (13):
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: allow to customize the completable command list
.gitignore | 2 +- 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 | 111 ++++++++--- contrib/completion/git-completion.bash | 169 ++++++++--------- generate-cmdlist.sh | 126 ++++++++----- git.c | 61 ++++++- help.c | 244 ++++++++++++++++++++++--- help.h | 10 + t/t0012-help.sh | 26 ++- t/t9902-completion.sh | 5 +- 15 files changed, 565 insertions(+), 254 deletions(-)
Signature · 1 line
2.17.0.705.g3525833791
PATCH v6 1/13 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 v6 2/13 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
Re: [PATCH v6 02/13] generate-cmds.sh: export all commands to command-list.h
Quoted 20 lines · Nguyễn Thái Ngọc Duy
The current
generate-cmds.shgenerates 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 offcommon-cmds.hbuild rules and generation code (and also delete duplicate content incommand-list.hwhich we keep for now to not messgenerate-cmds.shup too much).
Quoted 4 lines
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.
---
Missing sign-off.
Quoted 7 lines
generate-cmdlist.sh +0
-0@@ -1,5 +1,27 @@ #!/bin/sh
generate-cmdlist.sh line 12
Quoted 10 lines
generate-cmdlist.sh +10
-0+die () { + echo "$@" >&2 + exit 1 +} + +command_list () { + sed '1,/^### command list/d;/^#/d' "$1" +} + +get_categories() {
Here and define_categories() below lack SP before (), and all others do. Be consistent.
Quoted 16 lines
generate-cmdlist.sh +12
-0+ tr ' ' '\n'| + grep -v '^$' | + sort | + uniq +} + +category_list () { + command_list "$1" | + cut -c 40- | + get_categories +} + get_synopsis () { sed -n ' /^NAME/,/'"$1"'/H
generate-cmdlist.sh get_synopsis () { · line 41
Quoted 10 lines
generate-cmdlist.sh +6
-0@@ -10,14 +32,51 @@ get_synopsis () { }' "Documentation/$1.txt" } +define_categories() { + echo + echo "/* Command categories */" +... }; +" +if [ -z "$2" ]
if test -z "$2"
PATCH v6 3/13 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 [ -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 v6 4/13 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 v6 5/13 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 | 30 ++++++++++++++++++++------ t/t0012-help.sh | 2 +- 3 files changed, 26 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 +24 -6
@@ -38,6 +38,23 @@ static int use_pager = -1;static void list_builtins (unsigned int exclude_option,char sep); +static int list_cmds (const char *spec) +{ +while (*spec) { +const char *sep =strchrnul (spec,',' ); +int len = sep - spec; + +if (len ==8 && !strncmp (spec,"builtins" ,8 )) +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 +240,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
Re: [PATCH v6 05/13] git.c: convert --list-* to --list-cmds=*
Quoted 8 lines · Nguyễn Thái Ngọc Duy
Even 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.
---
Missing sign-off.
git.c static int use_pager = -1; · line 48
Quoted 8 lines
git.c +8
-0+static int list_cmds (const char *spec) +{ +while (*spec) { +const char *sep =strchrnul (spec,',' ); +int len = sep - spec; + +if (len ==8 && !strncmp (spec,"builtins" ,8 )) +list_builtins (0 ,'\n' );
This is the origin of ugliness we see in later steps that follow the same
if (len == strlen(constS) && !strncmp(spec, constS, strlen(constS))
pattern added here. Could we have a small helper that takes len, spec, and constS to abstract "8" away?
PATCH v6 6/13 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,22 +36,28 @@ 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 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 (len ==8 && !strncmp (spec,"builtins" ,8 )) -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 ; }
@@ -242,7 +248,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));
@@ -526,14 +538,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 v6 7/13 completion: implement and use --list-cmds=main,others
In reply to Nguyễn Thái Ngọc DuyInstead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow, make git provide the list in a machine-friendly form. This adds two separate listing types, main and others, instead of just "all" for more flexibility.
--- 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
@@ -49,6 +49,10 @@ static int list_cmds(const char *spec)if (len ==8 && !strncmp (spec,"builtins" ,8 ))list_builtins (&list,0 ); +else if (len ==4 && !strncmp (spec,"main" ,4 )) +list_all_main_cmds (&list); +else if (len ==6 && !strncmp (spec,"others" ,6 )) +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 v6 8/13 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
@@ -53,6 +53,13 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (len == 6 && !strncmp(spec, "others", 6))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
Re: [PATCH v6 08/13] git: support --list-cmds=list-<category>
Quoted 8 lines · Nguyễn Thái Ngọc Duy
This 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.
---
Missing sign-off.
generate-cmdlist.sh define_categories() { · line 48
Quoted 10 lines
generate-cmdlist.sh +1
-0@@ -45,6 +45,21 @@ define_categories() { test "$bit" -gt 32 && die "Urgh.. too many categories?" } +define_category_names() {
Style.
generate-cmdlist.sh define_categories() { · line 63
Quoted 1 line
generate-cmdlist.sh +0
-0print_command_list() {
Ditto (but needs fixing in an earlier step).
git.c static int list_cmds(const char *spec) · line 56
Quoted 9 lines
git.c +1
-0@@ -53,6 +53,13 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (len == 6 && !strncmp(spec, "others", 6))list_all_other_cmds (&list); + else if (len > 5 && !strncmp(spec, "list-", 5)) {
Earlier I asked to have a small helper to avoid the constant length that has to go together with a constant string, e.g.
has_prefix(spec, len, "others")
but this new one may make it a bit tricky.
else if (has_prefix(spec, len, "others")
...
else if (has_prefix(spec, len, "list-") &&
spec[strlen("list-")] != '\0' ) {
...does look a bit ugly. Others may be able to help with better ideas.
Thansk.
PATCH v6 9/13 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 v6 10/13 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 v6 10/13] help: use command-list.txt for the source of guides
Quoted 6 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.
---
Nice.
Missing sign-off.
PATCH v6 11/13 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 | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
command-list.txt +44 -0
@@ -1,3 +1,47 @@ +# 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. +# +# While not true commands, 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
Re: [PATCH v6 11/13] command-list.txt: documentation and guide line
Hi Duy,
From: "Nguyễn Thái Ngọc Duy" <[email protected]> : Monday, May 07, 2018
Quoted 44 lines
This 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 | 44 ++++++++++++++++++++++++++++++++++++++++++++1 file changed, 44 insertions(+)command-list.txt +33
-0@@ -1,3 +1,47 @@ +# 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
command-list.txt line 43
Quoted 10 lines
command-list.txt +10
-0+# 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. +# +# While not true commands, guides are also specified here, which can +# only have "guide" attribute and nothing else.
While the file is called ~ "Command List", the list is here as a support to the Help function, and ultimately to the user's reading of the man pages, including the man(5/7) guides, so I'd view the man page guides as first class citizens.
Perhaps:
# 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.
--
Philip
Quoted 8 lines
command-list.txt +1
-0+# ### 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 v6 12/13 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 are not part of neither list-mainporcelain nor list-complete and as a result no longer completes:
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - lost-found obsolete - p4 too short and probably not often used (*) - peek-remote deprecated - svn same category as p4 (*) - tar-tree obsolete - verify-commit not often used
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.
(*) 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 should include them.
--- command-list.txt | 37 ++++---- contrib/completion/git-completion.bash | 117 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 48 insertions(+), 111 deletions(-)
command-list.txt +19 -18
@@ -47,11 +47,11 @@ git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +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
@@ -61,7 +61,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
@@ -69,7 +69,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
@@ -83,7 +83,7 @@ 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
@@ -92,20 +92,20 @@ git-filter-branch ancillarymanipulators 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-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-index-pack plumbingmanipulators git-init mainporcelain init -git-instaweb ancillaryinterrogators +git-instaweb ancillaryinterrogators complete git-interpret-trailers purehelpers gitk mainporcelain git-log mainporcelain info
@@ -119,12 +119,12 @@ 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-pack-objects plumbingmanipulators
@@ -140,28 +140,29 @@ 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
@@ -180,7 +181,7 @@ git-verify-commit ancillaryinterrogators 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 +26 -91
139 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 v6 13/13 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
--- contrib/completion/git-completion.bash | 35 ++++++++++++++++++++++++++ git.c | 2 ++ help.c | 33 ++++++++++++++++++++++++ help.h | 1 + 4 files changed, 71 insertions(+)
contrib/completion/git-completion.bash +35 -0
@@ -38,6 +38,38 @@ # # 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 defaults add some extra commands specified +# in the configuration variable completion.commands [1] with +# +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,others,list-complete,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. +# +# [1] Note that completion.commands should not be per-repository +# since the command list is generated once and cached. +# +# completion.commands could be used to exclude commands as +# well. If a command in this list begins with '-', then it +# will be excluded from the list of commands gathered by the +# groups specified before "config" in +# $GIT_COMPLETION_CMD_GROUPS. case "$COMP_WORDBREAKS" in *:*) : great ;;
@@ -840,6 +872,9 @@ __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 fi
git.c +2 -0
@@ -53,6 +53,8 @@ static int list_cmds(const char *spec)list_all_main_cmds (&list); else if (len == 6 && !strncmp(spec, "others", 6))list_all_other_cmds (&list); + else if (len == 6 && !strncmp(spec, "config", 6)) +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
v7 cover Keep all info in command-list.txt in git binary
In reply to Nguyễn Thái Ngọc Duyv7 is mostly code cleanup plus one more change:
git-completion.bash now always checks completion.commands config key. This makes it much more convenient to customize the command complete list. You only have to fall back to setting $GIT_COMPLETION_CMD_GROUPS when you have very special needs.
Interdiff
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 a 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 +4 -13
@@ -50,10 +50,10 @@ # # GIT_COMPLETION_CMD_GROUPS=main,others # -# Or you could go with defaults add some extra commands specified -# in the configuration variable completion.commands [1] with +# Or you could go with main porcelain only and extra commands in +# the configuration variable completion.commands with # -# GIT_COMPLETION_CMD_GROUPS=mainporcelain,others,list-complete,config +# GIT_COMPLETION_CMD_GROUPS=mainporcelain,config # # Or go completely custom group with #
@@ -61,15 +61,6 @@ # # Or you could even play with other command categories found in # command-list.txt. -# -# [1] Note that completion.commands should not be per-repository -# since the command list is generated once and cached. -# -# completion.commands could be used to exclude commands as -# well. If a command in this list begins with '-', then it -# will be excluded from the list of commands gathered by the -# groups specified before "config" in -# $GIT_COMPLETION_CMD_GROUPS. case "$COMP_WORDBREAKS" in *:*) : great ;;
@@ -876,7 +867,7 @@ __git_commands () { 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)
generate-cmdlist.sh +4 -4
@@ -9,7 +9,7 @@ command_list () { grep -v '^#' "$1" } -get_categories() { +get_categories () { tr ' ' '\n'| grep -v '^$' | sort |
@@ -32,7 +32,7 @@ get_synopsis () { }' "Documentation/$1.txt" } -define_categories() { +define_categories () { echo echo "/* Command categories */" bit=0
@@ -45,7 +45,7 @@ define_categories() { test "$bit" -gt 32 && die "Urgh.. too many categories?" } -define_category_names() { +define_category_names () { echo echo "/* Category names */" echo "static const char *category_names[] = {"
@@ -60,7 +60,7 @@ define_category_names() { echo "};" } -print_command_list() { +print_command_list () { echo "static struct cmdname_help command_list[] = {" command_list "$1" |
git.c +11 -4
@@ -38,6 +38,13 @@ static int use_pager = -1;static void list_builtins (struct string_list *list,unsigned int exclude_option); +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) {struct string_list list =STRING_LIST_INIT_DUP ;
@@ -47,13 +54,13 @@ static int list_cmds(const char *spec)const char *sep =strchrnul (spec,',' );int len = sep - spec; -if (len ==8 && !strncmp (spec,"builtins" ,8 )) +if (match_token (spec, len,"builtins" ))list_builtins (&list,0 ); -else if (len ==4 && !strncmp (spec,"main" ,4 )) +else if (match_token (spec, len,"main" ))list_all_main_cmds (&list); -else if (len ==6 && !strncmp (spec,"others" ,6 )) +else if (match_token (spec, len,"others" ))list_all_other_cmds (&list); -else if (len ==6 && !strncmp (spec,"config" ,6 )) +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 ;
Nguyễn Thái Ngọc Duy (13):
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: 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 | 111 ++++++++--- contrib/completion/git-completion.bash | 160 +++++++--------- 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, 573 insertions(+), 254 deletions(-)
Signature · 1 line
2.17.0.705.g3525833791
PATCH v7 1/13 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 v7 2/13 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 v7 3/13 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 v7 4/13 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 v7 5/13 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 v7 6/13 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 v7 7/13 completion: implement and use --list-cmds=main,others
In reply to Nguyễn Thái Ngọc DuyInstead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow, make git provide the list in a machine-friendly form. This adds two separate listing types, main and others, instead of just "all" for more flexibility.
--- 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
Re: [PATCH v7 07/13] completion: implement and use --list-cmds=main,others
Quoted 2 lines · Nguyễn Thái Ngọc Duy
Instead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow,
Is it tricky? It seems rather straightforward.
Is it slow? Well, there is a pipe and an egrep, sure, but thanks to caching it's only run once, so basically doesn't matter.
OTOH you don't mention the most important reason, namely that the completion script contains a long hard-coded list of the names of all known plumbing commands to filter out, which is redundant with the categorization in 'command-list.txt', is a maintenance burden, and tends to get out-of-sync when new plumbing commands are added.
Quoted 108 lines
make git provide the list in a
machine-friendly form. This adds two separate listing types, main and others, instead of just "all" for more flexibility.Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- 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
-1@@ -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, --2.17.0.705.g3525833791
Re: [PATCH v7 07/13] completion: implement and use --list-cmds=main,others
Quoted 5 lines · SZEDER Gábor
OTOH you don't mention the most important reason, namely that the completion script contains a long hard-coded list of the names of all known plumbing commands to filter out, which is redundant with the categorization in 'command-list.txt', is a maintenance burden, and tends to get out-of-sync when new plumbing commands are added.
Oops, sorry, got lost among the many patches, please just forget this paragraph.
Re: [PATCH v7 07/13] completion: implement and use --list-cmds=main,others
In reply to SZEDER GáborQuoted 6 lines · SZEDER Gábor
Quoted 2 lines · Nguyễn Thái Ngọc Duy
Instead of parsing "git help -a" output, which is tricky to get right, less elegant and also slow,
Is it tricky? It seems rather straightforward.
But there are traps. [1] is a reported one. And since you're parsing what's meant for human reader, this code could easily break in the future.
[1] https://public-inbox.org/git/CAPQz56bts8zFfUHyKJqnefQoH97L5TTA-k3be=5HsdeEbcMqOA@mail.gmail.com/
Quoted 2 lines
Is it slow? Well, there is a pipe and an egrep, sure, but thanks to caching it's only run once, so basically doesn't matter.
This I agree is an exaggeration. Ultimately though I am breaking down and providing the information pieces to __git_list_porcelain_commands() and it happens to benefit this one too. Perhaps I should rephrase my commit to say this.
Signature · 1 line
Duy
PATCH v7 8/13 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 v7 9/13 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 v7 10/13 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 v7 11/13 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 | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
command-list.txt +44 -0
@@ -1,3 +1,47 @@ +# 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. +# +# While not true commands, 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 v7 12/13 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 are not part of neither list-mainporcelain nor list-complete and as a result no longer completes:
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - lost-found obsolete - p4 too short and probably not often used (*) - peek-remote deprecated - svn same category as p4 (*) - tar-tree obsolete - verify-commit not often used
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.
(*) 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 should include them.
--- command-list.txt | 37 ++++---- contrib/completion/git-completion.bash | 117 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 48 insertions(+), 111 deletions(-)
command-list.txt +19 -18
@@ -47,11 +47,11 @@ git-add mainporcelain worktree git-am mainporcelain git-annotate ancillaryinterrogators -git-apply plumbingmanipulators +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
@@ -61,7 +61,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
@@ -69,7 +69,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
@@ -83,7 +83,7 @@ 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
@@ -92,20 +92,20 @@ git-filter-branch ancillarymanipulators 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-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-index-pack plumbingmanipulators git-init mainporcelain init -git-instaweb ancillaryinterrogators +git-instaweb ancillaryinterrogators complete git-interpret-trailers purehelpers gitk mainporcelain git-log mainporcelain info
@@ -119,12 +119,12 @@ 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-pack-objects plumbingmanipulators
@@ -140,28 +140,29 @@ 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
@@ -180,7 +181,7 @@ git-verify-commit ancillaryinterrogators 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 +26 -91
139 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 v7 12/13] completion: let git provide the completable command list
Quoted 16 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.
list-complete does not recreate exactly the command list before this patch though. The following commands are not part of neither list-mainporcelain nor list-complete and as a result no longer completes:
Quoted 12 lines
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - lost-found obsolete - p4 too short and probably not often used (*) - peek-remote deprecated - svn same category as p4 (*) - tar-tree obsolete - verify-commit not often used
'git name-rev' is plumbing as well.
I think this commit should be split into two:
- first do the unequivocally beneficial thing and get rid of the long, hard-coded command list in __git_list_porcelain_commands(), while keeping its output unchanged,
- then do the arguable thing and change the list of commands.
Quoted 43 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.
(*) 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 should include them.
Signed-off-by Nguyễn Thái Ngọc Duy <[email protected]>--- command-list.txt | 37 ++++---- contrib/completion/git-completion.bash | 117 ++++++------------------- t/t9902-completion.sh | 5 +- 3 files changed, 48 insertions(+), 111 deletions(-)contrib/completion/git-completion.bash +12
-6@@ -835,18 +835,30 @@ __git_complete_strategy () } __git_commands () { - if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}" - then - printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}" - else - git --list-cmds=main,others - fi + case "$1" in + porcelain) + if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + then + printf "%s" "$GIT_TESTING_PORCELAIN_COMMAND_LIST" + else + git --list-cmds=list-mainporcelain,others,list-complete + fi + ;; + all) + if test -n "$GIT_TESTING_ALL_COMMAND_LIST" + then
contrib/completion/git-completion.bash __git_complete_strategy () · line 858
Quoted 10 lines
contrib/completion/git-completion.bash +7
-1+ printf "%s" "$GIT_TESTING_ALL_COMMAND_LIST" + else + git --list-cmds=main,others + fi + ;; + esac } -__git_list_all_commands () +__git_list_commands ()
Please add comments before these functions to document their mandatory argument.
contrib/completion/git-completion.bash __git_complete_strategy () · line 864
Quoted 7 lines
contrib/completion/git-completion.bash +1
-1{ local i IFS=" "$'\n' - for i in $(__git_commands) + for i in $(__git_commands $1) do case $i in *--*) : helper pattern;;
Is this loop to exclude helper commands with doubledash in their name still necessary?
Re: [PATCH v7 12/13] completion: let git provide the completable command list
Quoted 31 lines · SZEDER Gábor
Quoted 16 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.
list-complete does not recreate exactly the command list before this patch though. The following commands are not part of neither list-mainporcelain nor list-complete and as a result no longer completes:
Quoted 12 lines
- annotate obsolete, discouraged to use - difftool-helper not an end user command - filter-branch not often used - get-tar-commit-id not often used - imap-send not often used - interpreter-trailers not for interactive use - lost-found obsolete - p4 too short and probably not often used (*) - peek-remote deprecated - svn same category as p4 (*) - tar-tree obsolete - verify-commit not often used
Quoted 1 line
'git name-rev' is plumbing as well.
So? name-rev remains completable like before and is not mentioned in the above list. Am I missing something?
Quoted 7 lines
I think this commit should be split into two:
- first do the unequivocally beneficial thing and get rid of the long, hard-coded command list in
__git_list_porcelain_commands(), while keeping its output unchanged,- then do the arguable thing and change the list of commands.
I will. Though the first commit still changes the output slightly because there are three commands not in command-list.txt. To keep the output unchanged, I would need to add them back in command-list.txt first (and find the right group for them) only to remove those lines later (two of them deprecated, the other does not even have a man page). It's not worth the effort.
Quoted 10 lines
contrib/completion/git-completion.bash __git_complete_strategy () · line 864
Quoted 7 lines
{ local i IFS=" "$'\n'contrib/completion/git-completion.bash +1
-1- for i in $(__git_commands) + for i in $(__git_commands $1) do case $i in *--*) : helper pattern;;Is this loop to exclude helper commands with doubledash in their name still necessary?
It is needed for __git_list_all_commands() because that one still essentially grabs "git help -a", which includes command--helpers.
Signature · 1 line
Duy
PATCH v7 13/13 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 ;;
@@ -840,8 +863,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
Hello,
When running make -j$(nproc) with the current pu f9f8c1f765 (Merge branch 'hn/bisect-first-parent' into pu) I see the following error:
GIT_VERSION = 2.17.0.732.gf9f8c1f765
* new build flags
* new prefix flags
GEN common-cmds.h
* new link flags
CC ident.o
CC hex.o
CC json-writer.o
./generate-cmdlist.sh: 73: ./generate-cmdlist.sh: Bad substitution
This doesn't occur on a non-parallel build.
Regards
Simon
Signature · 3 lines
+ privacy is necessary + using gnupg http://gnupg.org + public key id: 0x92FEFDB7E44C32F9
Quoted 14 lines · Simon Ruderich
When running make -j$(nproc) with the current pu
f9f8c1f765(Merge branch 'hn/bisect-first-parent' into pu) I see the following error:
GIT_VERSION= 2.17.0.732.gf9f8c1f765
* new build flags
* new prefix flags
GENcommon-cmds.h
* new link flags
CC ident.o
CC hex.o
CC json-writer.o
./generate-cmdlist.sh: 73: ./generate-cmdlist.sh: Bad substitution
Quoted 1 line
This doesn't occur on a non-parallel build.
It does occur in non-parallel builds, too.
See:
https://public-inbox.org/git/CAM0VKjkns+AsVyMSe2fxzT8a8oqYdNX3qO8mnw2juOgFC7LHYA@mail.gmail.com/
Quoted 8 lines · SZEDER Gábor
Quoted 1 line · Simon Ruderich
This doesn't occur on a non-parallel build.
It does occur in non-parallel builds, too.
See:
https://public-inbox.org/git/CAM0VKjkns+AsVyMSe2fxzT8a8oqYdNX3qO8mnw2juOgFC7LHYA@mail.gmail.com/
Thanks for the correction. I noticed it at the beginning of make -j run and incorrectly assummed it would occur quickly in the non-parallel run as well.
Regards
Simon
Signature · 3 lines
+ privacy is necessary + using gnupg http://gnupg.org + public key id: 0x92FEFDB7E44C32F9