test-lib: fail if invalid options are passed
[gitweb.git] / builtin-show-branch.c
index c8e9b3c723cb733e1d6b4cd2036f165f0a088970..94338119569b6af85c9d121daa2134818f7d321e 100644 (file)
@@ -3,11 +3,13 @@
 #include "refs.h"
 #include "builtin.h"
 #include "color.h"
+#include "parse-options.h"
 
-static const char show_branch_usage[] =
-"git show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base ] [--topics] [<refs>...] | --reflog[=n[,b]] <branch>";
-static const char show_branch_usage_reflog[] =
-"--reflog is incompatible with --all, --remotes, --independent or --merge-base";
+static const char* show_branch_usage[] = {
+    "git show-branch [--sparse] [--current] [--all] [--remotes] [--topo-order] [--more=count | --list | --independent | --merge-base] [--topics] [--color] [<refs>...]",
+    "--reflog[=n[,b]] [--list] [--color] <branch>",
+    NULL
+};
 
 static int showbranch_use_color = -1;
 static char column_colors[][COLOR_MAXLEN] = {
@@ -601,18 +603,25 @@ static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
        return 0;
 }
 
-static void parse_reflog_param(const char *arg, int *cnt, const char **base)
+static int reflog = 0;
+
+static int parse_reflog_param(const struct option *opt, const char *arg,
+                             int unset)
 {
        char *ep;
-       *cnt = strtoul(arg, &ep, 10);
+       const char **base = (const char **)opt->value;
+       if (!arg)
+               arg = "";
+       reflog = strtoul(arg, &ep, 10);
        if (*ep == ',')
                *base = ep + 1;
        else if (*ep)
-               die("unrecognized reflog param '%s'", arg);
+               return error("unrecognized reflog param '%s'", arg);
        else
                *base = NULL;
-       if (*cnt <= 0)
-               *cnt = DEFAULT_REFLOG;
+       if (reflog <= 0)
+               reflog = DEFAULT_REFLOG;
+       return 0;
 }
 
 int cmd_show_branch(int ac, const char **av, const char *prefix)
@@ -638,8 +647,44 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
        int head_at = -1;
        int topics = 0;
        int dense = 1;
-       int reflog = 0;
        const char *reflog_base = NULL;
+       struct option builtin_show_branch_options[] = {
+               OPT_BOOLEAN('a', "all", &all_heads,
+                           "show remote-tracking and local branches"),
+               OPT_BOOLEAN('r', "remotes", &all_remotes,
+                           "show remote-tracking branches"),
+               OPT_BOOLEAN(0, "color", &showbranch_use_color,
+                           "color '*!+-' corresponding to the branch"),
+               { OPTION_INTEGER, 0, "more", &extra, "n",
+                           "show <n> more commits after the common ancestor",
+                           PARSE_OPT_OPTARG | PARSE_OPT_LASTARG_DEFAULT,
+                           NULL, (intptr_t)1 },
+               OPT_SET_INT(0, "list", &extra, "synonym to more=-1", -1),
+               OPT_BOOLEAN(0, "no-name", &no_name, "suppress naming strings"),
+               OPT_BOOLEAN(0, "current", &with_current_branch,
+                           "include the current branch"),
+               OPT_BOOLEAN(0, "sha1-name", &sha1_name,
+                           "name commits with their object names"),
+               OPT_BOOLEAN(0, "merge-base", &merge_base,
+                           "act like git merge-base -a"),
+               OPT_BOOLEAN(0, "independent", &independent,
+                           "show refs unreachable from any other ref"),
+               OPT_BOOLEAN(0, "topo-order", &lifo,
+                           "show commits in topological order"),
+               OPT_BOOLEAN(0, "topics", &topics,
+                           "show only commits not on the first branch"),
+               OPT_SET_INT(0, "sparse", &dense,
+                           "show merges reachable from only one tip", 0),
+               OPT_SET_INT(0, "date-order", &lifo,
+                           "show commits where no parent comes before its "
+                           "children", 0),
+               { OPTION_CALLBACK, 'g', "reflog", &reflog_base, "<n>[,<base>]",
+                           "show <n> most recent ref-log entries starting at "
+                           "base",
+                           PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP,
+                           parse_reflog_param },
+               OPT_END()
+       };
 
        git_config(git_show_branch_config, NULL);
 
@@ -652,63 +697,18 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                av = default_arg - 1; /* ick; we would not address av[0] */
        }
 
-       while (1 < ac && av[1][0] == '-') {
-               const char *arg = av[1];
-               if (!strcmp(arg, "--")) {
-                       ac--; av++;
-                       break;
-               }
-               else if (!strcmp(arg, "--all") || !strcmp(arg, "-a"))
-                       all_heads = all_remotes = 1;
-               else if (!strcmp(arg, "--remotes") || !strcmp(arg, "-r"))
-                       all_remotes = 1;
-               else if (!strcmp(arg, "--more"))
-                       extra = 1;
-               else if (!strcmp(arg, "--list"))
-                       extra = -1;
-               else if (!strcmp(arg, "--no-name"))
-                       no_name = 1;
-               else if (!strcmp(arg, "--current"))
-                       with_current_branch = 1;
-               else if (!strcmp(arg, "--sha1-name"))
-                       sha1_name = 1;
-               else if (!prefixcmp(arg, "--more="))
-                       extra = atoi(arg + 7);
-               else if (!strcmp(arg, "--merge-base"))
-                       merge_base = 1;
-               else if (!strcmp(arg, "--independent"))
-                       independent = 1;
-               else if (!strcmp(arg, "--topo-order"))
-                       lifo = 1;
-               else if (!strcmp(arg, "--topics"))
-                       topics = 1;
-               else if (!strcmp(arg, "--sparse"))
-                       dense = 0;
-               else if (!strcmp(arg, "--date-order"))
-                       lifo = 0;
-               else if (!strcmp(arg, "--reflog") || !strcmp(arg, "-g")) {
-                       reflog = DEFAULT_REFLOG;
-               }
-               else if (!prefixcmp(arg, "--reflog="))
-                       parse_reflog_param(arg + 9, &reflog, &reflog_base);
-               else if (!prefixcmp(arg, "-g="))
-                       parse_reflog_param(arg + 3, &reflog, &reflog_base);
-               else if (!strcmp(arg, "--color"))
-                       showbranch_use_color = 1;
-               else if (!strcmp(arg, "--no-color"))
-                       showbranch_use_color = 0;
-               else
-                       usage(show_branch_usage);
-               ac--; av++;
-       }
-       ac--; av++;
+       ac = parse_options(ac, av, prefix, builtin_show_branch_options,
+                          show_branch_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+       if (all_heads)
+               all_remotes = 1;
 
        if (extra || reflog) {
                /* "listing" mode is incompatible with
                 * independent nor merge-base modes.
                 */
                if (independent || merge_base)
-                       usage(show_branch_usage);
+                       usage_with_options(show_branch_usage,
+                                          builtin_show_branch_options);
                if (reflog && ((0 < extra) || all_heads || all_remotes))
                        /*
                         * Asking for --more in reflog mode does not
@@ -716,7 +716,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
                         *
                         * Also --all and --remotes do not make sense either.
                         */
-                       usage(show_branch_usage_reflog);
+                       die("--reflog is incompatible with --all, --remotes, "
+                           "--independent or --merge-base");
        }
 
        /* If nothing is specified, show all branches by default */