reflog: convert to parse_options() API

Continue the work started in 33d7bdd6459 (builtin/reflog.c: use parse-options api for expire, delete subcommands, 2022-01-06) and convert the cmd_reflog() function itself to use the parse_options() API. Let's also add a test which would fail if we forgot PARSE_OPT_NO_INTERNAL_HELP here, as well as making sure that we'll still pass through "--" by supplying PARSE_OPT_KEEP_DASHDASH. For that test we need to change "test_commit()" to accept files starting with "--". The "git reflog -h" usage will now show the usage for all of the sub-commands, rather than a terse summary which wasn't correct (e.g. "git reflog exists" is not a valid command). See my 8757b35d443 (commit-graph: define common usage with a macro, 2021-08-23) for prior art. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Mar 17, 2022 at 19:08 UTC e3c3675801f6d7494ac11e772e848981d1e158b4
3 files changed +50 -9
builtin/reflog.c
+32 -8
@@ -32,6 +32,14 @@ static const char *const reflog_exists_usage[] = {
32 NULL,
33 };
34
35 +static const char *const reflog_usage[] = {
36 + N_("git reflog [show] [<log-options>] [<ref>]"),
37 + BUILTIN_REFLOG_EXPIRE_USAGE,
38 + BUILTIN_REFLOG_DELETE_USAGE,
39 + BUILTIN_REFLOG_EXISTS_USAGE,
40 + NULL
41 +};
42 +
43 static timestamp_t default_reflog_expire;
44 static timestamp_t default_reflog_expire_unreachable;
45
@@ -372,17 +380,28 @@ static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
380 * main "reflog"
381 */
382
375 -static const char reflog_usage[] =
376 -"git reflog [ show | expire | delete | exists ]";
377 -
383 int cmd_reflog(int argc, const char **argv, const char *prefix)
384 {
380 - if (argc > 1 && !strcmp(argv[1], "-h"))
381 - usage(_(reflog_usage));
385 + struct option options[] = {
386 + OPT_END()
387 + };
388 +
389 + argc = parse_options(argc, argv, prefix, options, reflog_usage,
390 + PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
391 + PARSE_OPT_KEEP_UNKNOWN |
392 + PARSE_OPT_NO_INTERNAL_HELP);
393 +
394 + /*
395 + * With "git reflog" we default to showing it. !argc is
396 + * impossible with PARSE_OPT_KEEP_ARGV0.
397 + */
398 + if (argc == 1)
399 + goto log_reflog;
400
383 - /* With no command, we default to showing it. */
384 - if (argc < 2 || *argv[1] == '-')
385 - return cmd_log_reflog(argc, argv, prefix);
401 + if (!strcmp(argv[1], "-h"))
402 + usage_with_options(reflog_usage, options);
403 + else if (*argv[1] == '-')
404 + goto log_reflog;
405
406 if (!strcmp(argv[1], "show"))
407 return cmd_log_reflog(argc - 1, argv + 1, prefix);
@@ -393,5 +412,10 @@ int cmd_reflog(int argc, const char **argv, const char *prefix)
412 else if (!strcmp(argv[1], "exists"))
413 return cmd_reflog_exists(argc - 1, argv + 1, prefix);
414
415 + /*
416 + * Fall-through for e.g. "git reflog -1", "git reflog master",
417 + * as well as the plain "git reflog" above goto above.
418 + */
419 +log_reflog:
420 return cmd_log_reflog(argc, argv, prefix);
421 }
t/t1410-reflog.sh
+17
@@ -106,6 +106,23 @@ test_expect_success setup '
106 test_line_count = 4 output
107 '
108
109 +test_expect_success 'correct usage on sub-command -h' '
110 + test_expect_code 129 git reflog expire -h >err &&
111 + grep "git reflog expire" err
112 +'
113 +
114 +test_expect_success 'pass through -- to sub-command' '
115 + test_when_finished "rm -rf repo" &&
116 + git init repo &&
117 + test_commit -C repo message --a-file contents dash-tag &&
118 +
119 + git -C repo reflog show -- --does-not-exist >out &&
120 + test_must_be_empty out &&
121 + git -C repo reflog show >expect &&
122 + git -C repo reflog show -- --a-file >actual &&
123 + test_cmp expect actual
124 +'
125 +
126 test_expect_success rewind '
127 test_tick && git reset --hard HEAD~2 &&
128 test -f C &&
t/test-lib-functions.sh
+1 -1
@@ -329,7 +329,7 @@ test_commit () {
329 else
330 $echo "${3-$1}" >"$indir$file"
331 fi &&
332 - git ${indir:+ -C "$indir"} add "$file" &&
332 + git ${indir:+ -C "$indir"} add -- "$file" &&
333 if test -z "$notick"
334 then
335 test_tick