branch: reject "--no-all" and "--no-remotes" early

As the command line parser for "git branch --all" forgets to use PARSE_OPT_NONEG, it accepted "git branch --no-all", and then passed a nonsense value to the underlying machinery, leading to a fatal error "filter_refs: invalid type". The "--remotes" option had exactly the same issue. Catch the unsupported options early in the option parser. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jul 18, 2023 at 11:27 UTC e12cb98e1e083c23a03fcfabb3a3c6a5a22ce3c5
2 files changed +22 -4
builtin/branch.c
+6 -4
@@ -726,8 +726,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
726 OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
727 OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("unset the upstream info")),
728 OPT__COLOR(&branch_use_color, N_("use colored output")),
729 - OPT_SET_INT('r', "remotes", &filter.kind, N_("act on remote-tracking branches"),
730 - FILTER_REFS_REMOTES),
729 + OPT_SET_INT_F('r', "remotes", &filter.kind, N_("act on remote-tracking branches"),
730 + FILTER_REFS_REMOTES,
731 + PARSE_OPT_NONEG),
732 OPT_CONTAINS(&filter.with_commit, N_("print only branches that contain the commit")),
733 OPT_NO_CONTAINS(&filter.no_commit, N_("print only branches that don't contain the commit")),
734 OPT_WITH(&filter.with_commit, N_("print only branches that contain the commit")),
@@ -735,8 +736,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
736 OPT__ABBREV(&filter.abbrev),
737
738 OPT_GROUP(N_("Specific git-branch actions:")),
738 - OPT_SET_INT('a', "all", &filter.kind, N_("list both remote-tracking and local branches"),
739 - FILTER_REFS_REMOTES | FILTER_REFS_BRANCHES),
739 + OPT_SET_INT_F('a', "all", &filter.kind, N_("list both remote-tracking and local branches"),
740 + FILTER_REFS_REMOTES | FILTER_REFS_BRANCHES,
741 + PARSE_OPT_NONEG),
742 OPT_BIT('d', "delete", &delete, N_("delete fully merged branch"), 1),
743 OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2),
744 OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1),
t/t3203-branch-output.sh
+16
@@ -55,9 +55,17 @@ cat >expect <<'EOF'
55 EOF
56 test_expect_success 'git branch -r shows remote branches' '
57 git branch -r >actual &&
58 + test_cmp expect actual &&
59 +
60 + git branch --remotes >actual &&
61 test_cmp expect actual
62 '
63
64 +test_expect_success 'git branch --no-remotes is rejected' '
65 + test_must_fail git branch --no-remotes 2>err &&
66 + grep "unknown option .no-remotes." err
67 +'
68 +
69 cat >expect <<'EOF'
70 branch-one
71 branch-two
@@ -68,9 +76,17 @@ cat >expect <<'EOF'
76 EOF
77 test_expect_success 'git branch -a shows local and remote branches' '
78 git branch -a >actual &&
79 + test_cmp expect actual &&
80 +
81 + git branch --all >actual &&
82 test_cmp expect actual
83 '
84
85 +test_expect_success 'git branch --no-all is rejected' '
86 + test_must_fail git branch --no-all 2>err &&
87 + grep "unknown option .no-all." err
88 +'
89 +
90 cat >expect <<'EOF'
91 two
92 one