Skip to content

Commit e3d40fb

Browse files
committed
Merge branch 'dd/bisect-helper-subcommand'
Fix a regression in the bisect-helper which mistakenly treats arguments to the command given to 'git bisect run' as arguments to the helper. * dd/bisect-helper-subcommand: bisect--helper: parse subcommand with OPT_SUBCOMMAND bisect--helper: move all subcommands into their own functions bisect--helper: remove unused options
2 parents 1107a39 + e9011b6 commit e3d40fb

File tree

3 files changed

+142
-120
lines changed

3 files changed

+142
-120
lines changed

builtin/bisect--helper.c

Lines changed: 129 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,115 +1279,144 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
12791279
return res;
12801280
}
12811281

1282+
static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)
1283+
{
1284+
if (argc > 1)
1285+
return error(_("--bisect-reset requires either no argument or a commit"));
1286+
return bisect_reset(argc ? argv[0] : NULL);
1287+
}
1288+
1289+
static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)
1290+
{
1291+
int res;
1292+
struct bisect_terms terms = { 0 };
1293+
1294+
if (argc > 1)
1295+
return error(_("--bisect-terms requires 0 or 1 argument"));
1296+
res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
1297+
free_terms(&terms);
1298+
return res;
1299+
}
1300+
1301+
static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)
1302+
{
1303+
int res;
1304+
struct bisect_terms terms = { 0 };
1305+
1306+
set_terms(&terms, "bad", "good");
1307+
res = bisect_start(&terms, argv, argc);
1308+
free_terms(&terms);
1309+
return res;
1310+
}
1311+
1312+
static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)
1313+
{
1314+
int res;
1315+
struct bisect_terms terms = { 0 };
1316+
1317+
if (argc)
1318+
return error(_("--bisect-next requires 0 arguments"));
1319+
get_terms(&terms);
1320+
res = bisect_next(&terms, prefix);
1321+
free_terms(&terms);
1322+
return res;
1323+
}
1324+
1325+
static int cmd_bisect__state(int argc, const char **argv, const char *prefix UNUSED)
1326+
{
1327+
int res;
1328+
struct bisect_terms terms = { 0 };
1329+
1330+
set_terms(&terms, "bad", "good");
1331+
get_terms(&terms);
1332+
res = bisect_state(&terms, argv, argc);
1333+
free_terms(&terms);
1334+
return res;
1335+
}
1336+
1337+
static int cmd_bisect__log(int argc, const char **argv UNUSED, const char *prefix UNUSED)
1338+
{
1339+
if (argc)
1340+
return error(_("--bisect-log requires 0 arguments"));
1341+
return bisect_log();
1342+
}
1343+
1344+
static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)
1345+
{
1346+
int res;
1347+
struct bisect_terms terms = { 0 };
1348+
1349+
if (argc != 1)
1350+
return error(_("no logfile given"));
1351+
set_terms(&terms, "bad", "good");
1352+
res = bisect_replay(&terms, argv[0]);
1353+
free_terms(&terms);
1354+
return res;
1355+
}
1356+
1357+
static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)
1358+
{
1359+
int res;
1360+
struct bisect_terms terms = { 0 };
1361+
1362+
set_terms(&terms, "bad", "good");
1363+
get_terms(&terms);
1364+
res = bisect_skip(&terms, argv, argc);
1365+
free_terms(&terms);
1366+
return res;
1367+
}
1368+
1369+
static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)
1370+
{
1371+
int res;
1372+
struct bisect_terms terms = { 0 };
1373+
1374+
get_terms(&terms);
1375+
res = bisect_visualize(&terms, argv, argc);
1376+
free_terms(&terms);
1377+
return res;
1378+
}
1379+
1380+
static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)
1381+
{
1382+
int res;
1383+
struct bisect_terms terms = { 0 };
1384+
1385+
if (!argc)
1386+
return error(_("bisect run failed: no command provided."));
1387+
get_terms(&terms);
1388+
res = bisect_run(&terms, argv, argc);
1389+
free_terms(&terms);
1390+
return res;
1391+
}
1392+
12821393
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
12831394
{
1284-
enum {
1285-
BISECT_RESET = 1,
1286-
BISECT_NEXT_CHECK,
1287-
BISECT_TERMS,
1288-
BISECT_START,
1289-
BISECT_AUTOSTART,
1290-
BISECT_NEXT,
1291-
BISECT_STATE,
1292-
BISECT_LOG,
1293-
BISECT_REPLAY,
1294-
BISECT_SKIP,
1295-
BISECT_VISUALIZE,
1296-
BISECT_RUN,
1297-
} cmdmode = 0;
1298-
int res = 0, nolog = 0;
1395+
int res = 0;
1396+
parse_opt_subcommand_fn *fn = NULL;
12991397
struct option options[] = {
1300-
OPT_CMDMODE(0, "bisect-reset", &cmdmode,
1301-
N_("reset the bisection state"), BISECT_RESET),
1302-
OPT_CMDMODE(0, "bisect-next-check", &cmdmode,
1303-
N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK),
1304-
OPT_CMDMODE(0, "bisect-terms", &cmdmode,
1305-
N_("print out the bisect terms"), BISECT_TERMS),
1306-
OPT_CMDMODE(0, "bisect-start", &cmdmode,
1307-
N_("start the bisect session"), BISECT_START),
1308-
OPT_CMDMODE(0, "bisect-next", &cmdmode,
1309-
N_("find the next bisection commit"), BISECT_NEXT),
1310-
OPT_CMDMODE(0, "bisect-state", &cmdmode,
1311-
N_("mark the state of ref (or refs)"), BISECT_STATE),
1312-
OPT_CMDMODE(0, "bisect-log", &cmdmode,
1313-
N_("list the bisection steps so far"), BISECT_LOG),
1314-
OPT_CMDMODE(0, "bisect-replay", &cmdmode,
1315-
N_("replay the bisection process from the given file"), BISECT_REPLAY),
1316-
OPT_CMDMODE(0, "bisect-skip", &cmdmode,
1317-
N_("skip some commits for checkout"), BISECT_SKIP),
1318-
OPT_CMDMODE(0, "bisect-visualize", &cmdmode,
1319-
N_("visualize the bisection"), BISECT_VISUALIZE),
1320-
OPT_CMDMODE(0, "bisect-run", &cmdmode,
1321-
N_("use <cmd>... to automatically bisect"), BISECT_RUN),
1322-
OPT_BOOL(0, "no-log", &nolog,
1323-
N_("no log for BISECT_WRITE")),
1398+
OPT_SUBCOMMAND("reset", &fn, cmd_bisect__reset),
1399+
OPT_SUBCOMMAND("terms", &fn, cmd_bisect__terms),
1400+
OPT_SUBCOMMAND("start", &fn, cmd_bisect__start),
1401+
OPT_SUBCOMMAND("next", &fn, cmd_bisect__next),
1402+
OPT_SUBCOMMAND("state", &fn, cmd_bisect__state),
1403+
OPT_SUBCOMMAND("log", &fn, cmd_bisect__log),
1404+
OPT_SUBCOMMAND("replay", &fn, cmd_bisect__replay),
1405+
OPT_SUBCOMMAND("skip", &fn, cmd_bisect__skip),
1406+
OPT_SUBCOMMAND("visualize", &fn, cmd_bisect__visualize),
1407+
OPT_SUBCOMMAND("view", &fn, cmd_bisect__visualize),
1408+
OPT_SUBCOMMAND("run", &fn, cmd_bisect__run),
13241409
OPT_END()
13251410
};
1326-
struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
1327-
13281411
argc = parse_options(argc, argv, prefix, options,
1329-
git_bisect_helper_usage,
1330-
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_UNKNOWN_OPT);
1412+
git_bisect_helper_usage, 0);
13311413

1332-
if (!cmdmode)
1414+
if (!fn)
13331415
usage_with_options(git_bisect_helper_usage, options);
1416+
argc--;
1417+
argv++;
13341418

1335-
switch (cmdmode) {
1336-
case BISECT_RESET:
1337-
if (argc > 1)
1338-
return error(_("--bisect-reset requires either no argument or a commit"));
1339-
res = bisect_reset(argc ? argv[0] : NULL);
1340-
break;
1341-
case BISECT_TERMS:
1342-
if (argc > 1)
1343-
return error(_("--bisect-terms requires 0 or 1 argument"));
1344-
res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
1345-
break;
1346-
case BISECT_START:
1347-
set_terms(&terms, "bad", "good");
1348-
res = bisect_start(&terms, argv, argc);
1349-
break;
1350-
case BISECT_NEXT:
1351-
if (argc)
1352-
return error(_("--bisect-next requires 0 arguments"));
1353-
get_terms(&terms);
1354-
res = bisect_next(&terms, prefix);
1355-
break;
1356-
case BISECT_STATE:
1357-
set_terms(&terms, "bad", "good");
1358-
get_terms(&terms);
1359-
res = bisect_state(&terms, argv, argc);
1360-
break;
1361-
case BISECT_LOG:
1362-
if (argc)
1363-
return error(_("--bisect-log requires 0 arguments"));
1364-
res = bisect_log();
1365-
break;
1366-
case BISECT_REPLAY:
1367-
if (argc != 1)
1368-
return error(_("no logfile given"));
1369-
set_terms(&terms, "bad", "good");
1370-
res = bisect_replay(&terms, argv[0]);
1371-
break;
1372-
case BISECT_SKIP:
1373-
set_terms(&terms, "bad", "good");
1374-
get_terms(&terms);
1375-
res = bisect_skip(&terms, argv, argc);
1376-
break;
1377-
case BISECT_VISUALIZE:
1378-
get_terms(&terms);
1379-
res = bisect_visualize(&terms, argv, argc);
1380-
break;
1381-
case BISECT_RUN:
1382-
if (!argc)
1383-
return error(_("bisect run failed: no command provided."));
1384-
get_terms(&terms);
1385-
res = bisect_run(&terms, argv, argc);
1386-
break;
1387-
default:
1388-
BUG("unknown subcommand %d", cmdmode);
1389-
}
1390-
free_terms(&terms);
1419+
res = fn(argc, argv, prefix);
13911420

13921421
/*
13931422
* Handle early success

git-bisect.sh

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,11 @@ case "$#" in
5757
case "$cmd" in
5858
help)
5959
git bisect -h ;;
60-
start)
61-
git bisect--helper --bisect-start "$@" ;;
6260
bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
63-
git bisect--helper --bisect-state "$cmd" "$@" ;;
64-
skip)
65-
git bisect--helper --bisect-skip "$@" || exit;;
66-
next)
67-
# Not sure we want "next" at the UI level anymore.
68-
git bisect--helper --bisect-next "$@" || exit ;;
69-
visualize|view)
70-
git bisect--helper --bisect-visualize "$@" || exit;;
71-
reset)
72-
git bisect--helper --bisect-reset "$@" ;;
73-
replay)
74-
git bisect--helper --bisect-replay "$@" || exit;;
61+
git bisect--helper state "$cmd" "$@" ;;
7562
log)
76-
git bisect--helper --bisect-log || exit ;;
77-
run)
78-
git bisect--helper --bisect-run "$@" || exit;;
79-
terms)
80-
git bisect--helper --bisect-terms "$@" || exit;;
63+
git bisect--helper log || exit ;;
8164
*)
82-
usage ;;
65+
git bisect--helper "$cmd" "$@" ;;
8366
esac
8467
esac

t/t6030-bisect-porcelain.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,16 @@ test_expect_success '"git bisect run" simple case' '
266266
git bisect reset
267267
'
268268

269+
# We want to make sure no arguments has been eaten
270+
test_expect_success '"git bisect run" simple case' '
271+
git bisect start &&
272+
git bisect good $HASH1 &&
273+
git bisect bad $HASH4 &&
274+
git bisect run printf "%s %s\n" reset --bisect-skip >my_bisect_log.txt &&
275+
grep -e "reset --bisect-skip" my_bisect_log.txt &&
276+
git bisect reset
277+
'
278+
269279
# We want to automatically find the commit that
270280
# added "Ciao" into hello.
271281
test_expect_success '"git bisect run" with more complex "git bisect start"' '

0 commit comments

Comments
 (0)