t0051: test GIT_TRACE to a windows named pipe
[gitweb.git] / git.c
diff --git a/git.c b/git.c
index bab6bbfded0a66c9577bf37e0b87cd640c8c50be..c2f48d53dd4aaba0752aa5f2e6633242d320b248 100644 (file)
--- 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)
@@ -25,7 +26,7 @@ struct cmd_struct {
 const char git_usage_string[] =
        N_("git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
           "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-          "           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+          "           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
           "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
           "           <command> [<args>]");
 
@@ -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) {
@@ -99,7 +159,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        exit(0);
                } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
                        use_pager = 1;
-               } else if (!strcmp(cmd, "--no-pager")) {
+               } else if (!strcmp(cmd, "-P") || !strcmp(cmd, "--no-pager")) {
                        use_pager = 0;
                        if (envchanged)
                                *envchanged = 1;
@@ -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);
        }
 }