summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2018-06-01 15:06:37 +0900
committerLibravatar Junio C Hamano <gitster@pobox.com>2018-06-01 15:06:37 +0900
commit2289880f784326dc955f213072164539dcaf445e (patch)
tree3e6d5465c144c76ffacde79aa33f9252b1e53a6e
parentRelNotes: remove duplicate release note (diff)
parentcompletion: allow to customize the completable command list (diff)
downloadtgif-2289880f784326dc955f213072164539dcaf445e.tar.xz
Merge branch 'nd/command-list'
The list of commands with their various attributes were spread across a few places in the build procedure, but it now is getting a bit more consolidated to allow more automation. * nd/command-list: completion: allow to customize the completable command list completion: add and use --list-cmds=alias completion: add and use --list-cmds=nohelpers Move declaration for alias.c to alias.h completion: reduce completable command list completion: let git provide the completable command list command-list.txt: documentation and guide line help: use command-list.txt for the source of guides help: add "-a --verbose" to list all commands with synopsis git: support --list-cmds=list-<category> completion: implement and use --list-cmds=main,others git --list-cmds: collect command list in a string_list git.c: convert --list-* to --list-cmds=* Remove common-cmds.h help: use command-list.h for common command list generate-cmds.sh: export all commands to command-list.h generate-cmds.sh: factor out synopsis extract code
-rw-r--r--.gitignore2
-rw-r--r--Documentation/config.txt8
-rw-r--r--Documentation/git-help.txt4
-rw-r--r--Documentation/git.txt10
-rw-r--r--Documentation/gitattributes.txt2
-rw-r--r--Documentation/gitmodules.txt2
-rw-r--r--Documentation/gitrevisions.txt2
-rw-r--r--Makefile16
-rw-r--r--alias.c22
-rw-r--r--alias.h12
-rw-r--r--builtin/help.c40
-rw-r--r--builtin/merge.c1
-rw-r--r--cache.h5
-rw-r--r--command-list.txt110
-rw-r--r--connect.c1
-rw-r--r--contrib/completion/git-completion.bash148
-rwxr-xr-xgenerate-cmdlist.sh126
-rw-r--r--git.c85
-rw-r--r--help.c244
-rw-r--r--help.h10
-rw-r--r--pager.c1
-rw-r--r--sequencer.c1
-rw-r--r--shell.c1
-rwxr-xr-xt/t0012-help.sh26
-rwxr-xr-xt/t9902-completion.sh23
25 files changed, 589 insertions, 313 deletions
diff --git a/.gitignore b/.gitignore
index b2a1ae4a1d..388cc4beee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -182,7 +182,7 @@
/gitweb/gitweb.cgi
/gitweb/static/gitweb.js
/gitweb/static/gitweb.min.*
-/common-cmds.h
+/command-list.h
*.tar.gz
*.dsc
*.deb
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7d8383433c..ab641bf5a9 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1412,6 +1412,14 @@ credential.<url>.*::
credentialCache.ignoreSIGHUP::
Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting.
+completion.commands::
+ This is only used by git-completion.bash to add or remove
+ commands from the list of completed commands. Normally only
+ porcelain commands and a few select others are completed. You
+ can add more commands, separated by space, in this
+ variable. Prefixing the command with '-' will remove it from
+ the existing list.
+
include::diff-config.txt[]
difftool.<tool>.path::
diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt
index 40d328a4b3..a40fc38d8b 100644
--- a/Documentation/git-help.txt
+++ b/Documentation/git-help.txt
@@ -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::
diff --git a/Documentation/git.txt b/Documentation/git.txt
index c662f41c1d..dba7f0c18e 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -164,6 +164,16 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
Do not perform optional operations that require locks. This is
equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`.
+--list-cmds=group[,group...]::
+ List commands by group. This is an internal/experimental
+ option and may change or be removed in the future. Supported
+ groups are: builtins, parseopt (builtin commands that use
+ parse-options), main (all commands in libexec directory),
+ others (all other commands in `$PATH` that have git- prefix),
+ list-<category> (see categories in command-list.txt),
+ nohelpers (exclude helper commands), alias and config
+ (retrieve command list from config variable completion.commands)
+
GIT COMMANDS
------------
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index b72936a885..92010b062e 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -3,7 +3,7 @@ gitattributes(5)
NAME
----
-gitattributes - defining attributes per path
+gitattributes - Defining attributes per path
SYNOPSIS
--------
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index db5d47eb19..4d63def206 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -3,7 +3,7 @@ gitmodules(5)
NAME
----
-gitmodules - defining submodule properties
+gitmodules - Defining submodule properties
SYNOPSIS
--------
diff --git a/Documentation/gitrevisions.txt b/Documentation/gitrevisions.txt
index 27dec5b91d..1f6cceaefb 100644
--- a/Documentation/gitrevisions.txt
+++ b/Documentation/gitrevisions.txt
@@ -3,7 +3,7 @@ gitrevisions(7)
NAME
----
-gitrevisions - specifying revisions and ranges for Git
+gitrevisions - Specifying revisions and ranges for Git
SYNOPSIS
--------
diff --git a/Makefile b/Makefile
index 4bca65383a..1d27f36365 100644
--- a/Makefile
+++ b/Makefile
@@ -795,7 +795,7 @@ LIB_FILE = libgit.a
XDIFF_LIB = xdiff/lib.a
VCSSVN_LIB = vcs-svn/lib.a
-GENERATED_H += common-cmds.h
+GENERATED_H += command-list.h
LIB_H = $(shell $(FIND) . \
-name .git -prune -o \
@@ -2006,9 +2006,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: 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: 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)"' \
@@ -2027,9 +2027,9 @@ $(BUILT_INS): git$X
ln -s $< $@ 2>/dev/null || \
cp $< $@
-common-cmds.h: generate-cmdlist.sh command-list.txt
+command-list.h: generate-cmdlist.sh command-list.txt
-common-cmds.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):\
@@ -2273,7 +2273,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 command-list.h
# should _not_ be included here, since they are necessary even when
# building an object for the first time.
@@ -2653,7 +2653,7 @@ sparse: $(SP_OBJ)
style:
git clang-format --style file --diff --extensions c,h
-check: common-cmds.h
+check: command-list.h
@if sparse; \
then \
echo >&2 "Use 'make sparse' instead"; \
@@ -2901,7 +2901,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 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
diff --git a/alias.c b/alias.c
index bf146e5263..a7e4e57130 100644
--- a/alias.c
+++ b/alias.c
@@ -1,9 +1,12 @@
#include "cache.h"
+#include "alias.h"
#include "config.h"
+#include "string-list.h"
struct config_alias_data {
const char *alias;
char *v;
+ struct string_list *list;
};
static int config_alias_cb(const char *key, const char *value, void *d)
@@ -11,8 +14,16 @@ static int config_alias_cb(const char *key, const char *value, void *d)
struct config_alias_data *data = d;
const char *p;
- if (skip_prefix(key, "alias.", &p) && !strcasecmp(p, data->alias))
- return git_config_string((const char **)&data->v, key, value);
+ if (!skip_prefix(key, "alias.", &p))
+ return 0;
+
+ if (data->alias) {
+ if (!strcasecmp(p, data->alias))
+ return git_config_string((const char **)&data->v,
+ key, value);
+ } else if (data->list) {
+ string_list_append(data->list, p);
+ }
return 0;
}
@@ -26,6 +37,13 @@ char *alias_lookup(const char *alias)
return data.v;
}
+void list_aliases(struct string_list *list)
+{
+ struct config_alias_data data = { NULL, NULL, list };
+
+ read_early_config(config_alias_cb, &data);
+}
+
#define SPLIT_CMDLINE_BAD_ENDING 1
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
static const char *split_cmdline_errors[] = {
diff --git a/alias.h b/alias.h
new file mode 100644
index 0000000000..79933f2457
--- /dev/null
+++ b/alias.h
@@ -0,0 +1,12 @@
+#ifndef __ALIAS_H__
+#define __ALIAS_H__
+
+struct string_list;
+
+char *alias_lookup(const char *alias);
+int split_cmdline(char *cmdline, const char ***argv);
+/* Takes a negative value returned by split_cmdline */
+const char *split_cmdline_strerror(int cmdline_errno);
+void list_aliases(struct string_list *list);
+
+#endif
diff --git a/builtin/help.c b/builtin/help.c
index 2d51071429..58e0a5507f 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -9,6 +9,7 @@
#include "run-command.h"
#include "column.h"
#include "help.h"
+#include "alias.h"
#ifndef DEFAULT_HELP_FORMAT
#define DEFAULT_HELP_FORMAT "man"
@@ -36,6 +37,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 +50,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(),
};
@@ -400,38 +403,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;
@@ -463,6 +434,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);
diff --git a/builtin/merge.c b/builtin/merge.c
index d85f99b781..6d7bbe8c9f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -35,6 +35,7 @@
#include "string-list.h"
#include "packfile.h"
#include "tag.h"
+#include "alias.h"
#define DEFAULT_TWOHEAD (1<<0)
#define DEFAULT_OCTOPUS (1<<1)
diff --git a/cache.h b/cache.h
index 08a48263b5..89a107a7f7 100644
--- a/cache.h
+++ b/cache.h
@@ -1826,11 +1826,6 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);
void overlay_tree_on_index(struct index_state *istate,
const char *tree_name, const char *prefix);
-char *alias_lookup(const char *alias);
-int split_cmdline(char *cmdline, const char ***argv);
-/* Takes a negative value returned by split_cmdline */
-const char *split_cmdline_strerror(int cmdline_errno);
-
/* setup.c */
struct startup_info {
int have_repository;
diff --git a/command-list.txt b/command-list.txt
index 835c5890be..e1c26c1bb7 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -1,23 +1,58 @@
-# 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)
-# command name category [deprecated] [common]
+# Command classification list
+# ---------------------------
+# All supported commands, builtin or external, must be described in
+# here. This info is used to list commands in various places. Each
+# command is on one line followed by one or more attributes.
+#
+# The first attribute group is mandatory and indicates the command
+# type. This group includes:
+#
+# mainporcelain
+# ancillarymanipulators
+# ancillaryinterrogators
+# foreignscminterface
+# plumbingmanipulators
+# plumbinginterrogators
+# synchingrepositories
+# synchelpers
+# purehelpers
+#
+# The type names are self explanatory. But if you want to see what
+# command belongs to what group to get a better picture, have a look
+# at "git" man page, "GIT COMMANDS" section.
+#
+# Commands of type mainporcelain can also optionally have one of these
+# attributes:
+#
+# init
+# worktree
+# info
+# history
+# remote
+#
+# These commands are considered "common" and will show up in "git
+# help" output in groups. Uncommon porcelain commands must not
+# specify any of these attributes.
+#
+# "complete" attribute is used to mark that the command should be
+# completable by git-completion.bash. Note that by default,
+# mainporcelain commands are completable so you don't need this
+# attribute.
+#
+# As part of the Git man page list, the man(5/7) guides are also
+# specified here, which can only have "guide" attribute and nothing
+# else.
+#
+### command list (do not change this line, also do not change alignment)
+# command name category [category] [category]
git-add mainporcelain worktree
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
@@ -27,7 +62,7 @@ git-check-mailmap purehelpers
git-checkout mainporcelain history
git-checkout-index plumbingmanipulators
git-check-ref-format purehelpers
-git-cherry ancillaryinterrogators
+git-cherry ancillaryinterrogators complete
git-cherry-pick mainporcelain
git-citool mainporcelain
git-clean mainporcelain
@@ -36,7 +71,7 @@ git-column purehelpers
git-commit mainporcelain history
git-commit-graph plumbingmanipulators
git-commit-tree plumbingmanipulators
-git-config ancillarymanipulators
+git-config ancillarymanipulators complete
git-count-objects ancillaryinterrogators
git-credential purehelpers
git-credential-cache purehelpers
@@ -50,7 +85,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
@@ -59,20 +94,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
@@ -86,7 +121,7 @@ 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
@@ -107,28 +142,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
@@ -147,6 +183,22 @@ 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
+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
diff --git a/connect.c b/connect.c
index 31aa9c8433..968e91b18c 100644
--- a/connect.c
+++ b/connect.c
@@ -14,6 +14,7 @@
#include "strbuf.h"
#include "version.h"
#include "protocol.h"
+#include "alias.h"
static char *server_capabilities_v1;
static struct argv_array server_capabilities_v2 = ARGV_ARRAY_INIT;
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 1491b7239b..12814e9bbf 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -989,127 +989,11 @@ __git_complete_strategy ()
return 1
}
-__git_commands () {
- if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}"
- then
- printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}"
- else
- git help -a|egrep '^ [a-zA-Z0-9]'
- fi
-}
-
-__git_list_all_commands ()
-{
- local i IFS=" "$'\n'
- for i in $(__git_commands)
- do
- case $i in
- *--*) : helper pattern;;
- *) echo $i;;
- esac
- done
-}
-
__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-graph) : plumbing;;
- 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_all_commands=$(git --list-cmds=main,others,alias,nohelpers)
}
# Lists all set config variables starting with the given section prefix,
@@ -1127,11 +1011,6 @@ __git_pretty_aliases ()
__git_get_config_variables "pretty"
}
-__git_aliases ()
-{
- __git_get_config_variables "alias"
-}
-
# __git_aliased_command requires 1 argument
__git_aliased_command ()
{
@@ -1739,13 +1618,12 @@ _git_help ()
return
;;
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
- "
+ if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
+ then
+ __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk"
+ else
+ __gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk"
+ fi
}
_git_init ()
@@ -3214,7 +3092,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 "*)
@@ -3300,8 +3178,14 @@ __git_main ()
--help
"
;;
- *) __git_compute_porcelain_commands
- __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
+ *)
+ if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ then
+ __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ else
+ __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
+ fi
+ ;;
esac
return
fi
diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh
index eeea4b67ea..8d6d8b45ce 100755
--- a/generate-cmdlist.sh
+++ b/generate-cmdlist.sh
@@ -1,50 +1,90 @@
#!/bin/sh
-echo "/* Automatically generated by generate-cmdlist.sh */
-struct cmdname_help {
- char name[16];
- char help[80];
- unsigned char group;
-};
+die () {
+ echo "$@" >&2
+ exit 1
+}
+
+command_list () {
+ grep -v '^#' "$1"
+}
-static const char *common_cmd_groups[] = {"
-
-grps=grps$$.tmp
-match=match$$.tmp
-trap "rm -f '$grps' '$match'" 0 1 2 3 15
-
-sed -n '
- 1,/^### common groups/b
- /^### command list/q
- /^#/b
- /^[ ]*$/b
- h;s/^[^ ][^ ]*[ ][ ]*\(.*\)/ N_("\1"),/p
- g;s/^\([^ ][^ ]*\)[ ].*/\1/w '$grps'
- ' "$1"
-printf '};\n\n'
-
-n=0
-substnum=
-while read grp
-do
- echo "^git-..*[ ]$grp"
- substnum="$substnum${substnum:+;}s/[ ]$grp/$n/"
- n=$(($n+1))
-done <"$grps" >"$match"
-
-printf 'static struct cmdname_help common_cmds[] = {\n'
-grep -f "$match" "$1" |
-sed 's/^git-//' |
-sort |
-while read cmd tags
-do
- tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g")
+get_categories () {
+ tr ' ' '\n'|
+ grep -v '^$' |
+ sort |
+ uniq
+}
+
+category_list () {
+ command_list "$1" |
+ cut -c 40- |
+ get_categories
+}
+
+get_synopsis () {
sed -n '
- /^NAME/,/git-'"$cmd"'/H
+ /^NAME/,/'"$1"'/H
${
x
- s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", N_("\1"), '$tag'},/
+ s/.*'"$1"' - \(.*\)/N_("\1")/
p
- }' "Documentation/git-$cmd.txt"
-done
-echo "};"
+ }' "Documentation/$1.txt"
+}
+
+define_categories () {
+ 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?"
+}
+
+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[] = {"
+
+ command_list "$1" |
+ while read cmd rest
+ do
+ printf " { \"$cmd\", $(get_synopsis $cmd), 0"
+ for cat in $(echo "$rest" | get_categories)
+ do
+ printf " | CAT_$cat"
+ done
+ echo " },"
+ done
+ echo "};"
+}
+
+echo "/* Automatically generated by generate-cmdlist.sh */
+struct cmdname_help {
+ const char *name;
+ const char *help;
+ uint32_t category;
+};
+"
+define_categories "$1"
+echo
+define_category_names "$1"
+echo
+print_command_list "$1"
diff --git a/git.c b/git.c
index 5771d62a32..c2f48d53dd 100644
--- a/git.c
+++ b/git.c
@@ -3,6 +3,7 @@
#include "exec-cmd.h"
#include "help.h"
#include "run-command.h"
+#include "alias.h"
#define RUN_SETUP (1<<0)
#define RUN_SETUP_GENTLY (1<<1)
@@ -36,7 +37,66 @@ 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 void exclude_helpers_from_list(struct string_list *list)
+{
+ int i = 0;
+
+ while (i < list->nr) {
+ if (strstr(list->items[i].string, "--"))
+ unsorted_string_list_delete_item(list, i, 0);
+ else
+ i++;
+ }
+}
+
+static int match_token(const char *spec, int len, const char *token)
+{
+ int token_len = strlen(token);
+
+ return len == token_len && !strncmp(spec, token, token_len);
+}
+
+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(&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 if (match_token(spec, len, "nohelpers"))
+ exclude_helpers_from_list(&list);
+ else if (match_token(spec, len, "alias"))
+ list_aliases(&list);
+ else if (match_token(spec, len, "config"))
+ list_cmds_by_config(&list);
+ else if (len > 5 && !strncmp(spec, "list-", 5)) {
+ 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;
+ if (*spec == ',')
+ spec++;
+ }
+ for (i = 0; i < list.nr; i++)
+ puts(list.items[i].string);
+ string_list_clear(&list, 0);
+ return 0;
+}
static void commit_pager_choice(void) {
switch (use_pager) {
@@ -223,12 +283,19 @@ 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")) {
+ 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);
@@ -511,14 +578,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);
}
}
diff --git a/help.c b/help.c
index a4feef2ffe..dd35fcc133 100644
--- a/help.c
+++ b/help.c
@@ -5,13 +5,127 @@
#include "run-command.h"
#include "levenshtein.h"
#include "help.h"
-#include "common-cmds.h"
+#include "command-list.h"
#include "string-list.h"
#include "column.h"
#include "version.h"
#include "refs.h"
#include "parse-options.h"
+struct category_description {
+ uint32_t category;
+ const char *desc;
+};
+static uint32_t common_mask =
+ CAT_init | CAT_worktree | CAT_info |
+ CAT_history | CAT_remote;
+static struct category_description common_categories[] = {
+ { CAT_init, N_("start a working area (see also: git help tutorial)") },
+ { CAT_worktree, N_("work on the current change (see also: git help everyday)") },
+ { CAT_info, N_("examine the history and state (see also: git help revisions)") },
+ { CAT_history, N_("grow, mark and tweak your common history") },
+ { 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, 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;
+
+}
+
+static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask)
+{
+ int i, nr = 0;
+ struct cmdname_help *cmds;
+
+ if (ARRAY_SIZE(command_list) == 0)
+ BUG("empty command_list[] is a sign of broken generate-cmdlist.sh");
+
+ ALLOC_ARRAY(cmds, ARRAY_SIZE(command_list) + 1);
+
+ for (i = 0; i < ARRAY_SIZE(command_list); i++) {
+ const struct cmdname_help *cmd = command_list + i;
+
+ if (!(cmd->category & mask))
+ continue;
+
+ cmds[nr] = *cmd;
+ cmds[nr].name = drop_prefix(cmd->name, cmd->category);
+
+ nr++;
+ }
+ cmds[nr].name = NULL;
+ *p_cmds = cmds;
+}
+
+static void print_command_list(const struct cmdname_help *cmds,
+ uint32_t mask, int longest)
+{
+ int i;
+
+ for (i = 0; cmds[i].name; i++) {
+ if (cmds[i].category & mask) {
+ printf(" %s ", cmds[i].name);
+ mput_char(' ', longest - strlen(cmds[i].name));
+ puts(_(cmds[i].help));
+ }
+ }
+}
+
+static int cmd_name_cmp(const void *elem1, const void *elem2)
+{
+ const struct cmdname_help *e1 = elem1;
+ const struct cmdname_help *e2 = elem2;
+
+ return strcmp(e1->name, e2->name);
+}
+
+static void print_cmd_by_category(const struct category_description *catdesc)
+{
+ struct cmdname_help *cmds;
+ int longest = 0;
+ int i, nr = 0;
+ uint32_t mask = 0;
+
+ for (i = 0; catdesc[i].desc; i++)
+ mask |= catdesc[i].category;
+
+ extract_cmds(&cmds, mask);
+
+ for (i = 0; cmds[i].name; i++, nr++) {
+ if (longest < strlen(cmds[i].name))
+ longest = strlen(cmds[i].name);
+ }
+ QSORT(cmds, nr, cmd_name_cmp);
+
+ for (i = 0; catdesc[i].desc; i++) {
+ uint32_t mask = catdesc[i].category;
+ const char *desc = catdesc[i].desc;
+
+ printf("\n%s\n", _(desc));
+ print_command_list(cmds, mask, longest);
+ }
+ free(cmds);
+}
+
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
{
struct cmdname *ent;
@@ -190,44 +304,116 @@ void list_commands(unsigned int colopts,
}
}
-static int cmd_group_cmp(const void *elem1, const void *elem2)
+void list_common_cmds_help(void)
{
- const struct cmdname_help *e1 = elem1;
- const struct cmdname_help *e2 = elem2;
+ puts(_("These are common Git commands used in various situations:"));
+ print_cmd_by_category(common_categories);
+}
- if (e1->group < e2->group)
- return -1;
- if (e1->group > e2->group)
- return 1;
- return strcmp(e1->name, e2->name);
+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_common_cmds_help(void)
+void list_all_other_cmds(struct string_list *list)
{
- int i, longest = 0;
- int current_grp = -1;
+ struct cmdnames main_cmds, other_cmds;
+ int i;
- for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
- if (longest < strlen(common_cmds[i].name))
- longest = strlen(common_cmds[i].name);
- }
+ memset(&main_cmds, 0, sizeof(main_cmds));
+ memset(&other_cmds, 0, sizeof(other_cmds));
+ load_command_list("git-", &main_cmds, &other_cmds);
- QSORT(common_cmds, ARRAY_SIZE(common_cmds), cmd_group_cmp);
+ for (i = 0; i < other_cmds.cnt; i++)
+ string_list_append(list, other_cmds.names[i]->name);
- puts(_("These are common Git commands used in various situations:"));
+ clean_cmdnames(&main_cmds);
+ 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; i < ARRAY_SIZE(common_cmds); 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;
+ 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;
- printf(" %s ", common_cmds[i].name);
- mput_char(' ', longest - strlen(common_cmds[i].name));
- puts(_(common_cmds[i].help));
+ if (!(cmd->category & cat_id))
+ continue;
+ string_list_append(list, drop_prefix(cmd->name, cmd->category));
}
}
+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[] = {
+ { 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);
+}
+
int is_in_cmdlist(struct cmdnames *c, const char *s)
{
int i;
@@ -285,6 +471,7 @@ const char *help_unknown_cmd(const char *cmd)
{
int i, n, best_similarity = 0;
struct cmdnames main_cmds, other_cmds;
+ struct cmdname_help *common_cmds;
memset(&main_cmds, 0, sizeof(main_cmds));
memset(&other_cmds, 0, sizeof(other_cmds));
@@ -299,6 +486,8 @@ const char *help_unknown_cmd(const char *cmd)
QSORT(main_cmds.names, main_cmds.cnt, cmdname_compare);
uniq(&main_cmds);
+ extract_cmds(&common_cmds, common_mask);
+
/* This abuses cmdname->len for levenshtein distance */
for (i = 0, n = 0; i < main_cmds.cnt; i++) {
int cmp = 0; /* avoid compiler stupidity */
@@ -313,10 +502,10 @@ const char *help_unknown_cmd(const char *cmd)
die(_(bad_interpreter_advice), cmd, cmd);
/* Does the candidate appear in common_cmds list? */
- while (n < ARRAY_SIZE(common_cmds) &&
+ while (common_cmds[n].name &&
(cmp = strcmp(common_cmds[n].name, candidate)) < 0)
n++;
- if ((n < ARRAY_SIZE(common_cmds)) && !cmp) {
+ if (common_cmds[n].name && !cmp) {
/* Yes, this is one of the common commands */
n++; /* use the entry from common_cmds[] */
if (starts_with(candidate, cmd)) {
@@ -329,6 +518,7 @@ const char *help_unknown_cmd(const char *cmd)
main_cmds.names[i]->len =
levenshtein(cmd, candidate, 0, 2, 1, 3) + 1;
}
+ FREE_AND_NULL(common_cmds);
QSORT(main_cmds.names, main_cmds.cnt, levenshtein_compare);
diff --git a/help.h b/help.h
index b21d7c94e8..3b38292a1b 100644
--- a/help.h
+++ b/help.h
@@ -1,6 +1,8 @@
#ifndef HELP_H
#define HELP_H
+struct string_list;
+
struct cmdnames {
int alloc;
int cnt;
@@ -17,6 +19,14 @@ 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);
+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,
diff --git a/pager.c b/pager.c
index 226828f178..a768797fcf 100644
--- a/pager.c
+++ b/pager.c
@@ -2,6 +2,7 @@
#include "config.h"
#include "run-command.h"
#include "sigchain.h"
+#include "alias.h"
#ifndef DEFAULT_PAGER
#define DEFAULT_PAGER "less"
diff --git a/sequencer.c b/sequencer.c
index 72b4d8ecae..560fc9b67d 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -27,6 +27,7 @@
#include "worktree.h"
#include "oidmap.h"
#include "oidset.h"
+#include "alias.h"
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
diff --git a/shell.c b/shell.c
index 0200d10796..40084a3013 100644
--- a/shell.c
+++ b/shell.c
@@ -3,6 +3,7 @@
#include "exec-cmd.h"
#include "strbuf.h"
#include "run-command.h"
+#include "alias.h"
#define COMMAND_DIR "git-shell-commands"
#define HELP_COMMAND COMMAND_DIR "/help"
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index 487b92a5de..bc27df7f38 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -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 &&
@@ -49,8 +58,23 @@ 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-builtins >builtins
+ git --list-cmds=builtins >builtins
'
while read builtin
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 1b6d275254..36deb0b123 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -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"
@@ -1350,17 +1351,6 @@ test_expect_success '__git_pretty_aliases' '
test_cmp expect actual
'
-test_expect_success '__git_aliases' '
- cat >expect <<-EOF &&
- ci
- co
- EOF
- test_config alias.ci commit &&
- test_config alias.co checkout &&
- __git_aliases >actual &&
- test_cmp expect actual
-'
-
test_expect_success 'basic' '
run_completion "git " &&
# built-in
@@ -1670,13 +1660,6 @@ test_expect_success 'sourcing the completion script clears cached commands' '
verbose test -z "$__git_all_commands"
'
-test_expect_success 'sourcing the completion script clears cached porcelain commands' '
- __git_compute_porcelain_commands &&
- verbose test -n "$__git_porcelain_commands" &&
- . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
- verbose test -z "$__git_porcelain_commands"
-'
-
test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
__git_compute_merge_strategies &&
verbose test -n "$__git_merge_strategies" &&