Skip to content

Commit 1b4d9b4

Browse files
committed
Merge branch 'jc/reflog-parse-options'
Use the parse-options API in "git reflog" command. * jc/reflog-parse-options: builtin/reflog.c: use parse-options api for expire, delete subcommands
2 parents 008028a + 33d7bdd commit 1b4d9b4

File tree

1 file changed

+97
-79
lines changed

1 file changed

+97
-79
lines changed

builtin/reflog.c

Lines changed: 97 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,6 @@
1212
#include "reachable.h"
1313
#include "worktree.h"
1414

15-
/* NEEDSWORK: switch to using parse_options */
16-
static const char reflog_expire_usage[] =
17-
N_("git reflog expire [--expire=<time>] "
18-
"[--expire-unreachable=<time>] "
19-
"[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
20-
"[--verbose] [--all] <refs>...");
21-
static const char reflog_delete_usage[] =
22-
N_("git reflog delete [--rewrite] [--updateref] "
23-
"[--dry-run | -n] [--verbose] <refs>...");
2415
static const char reflog_exists_usage[] =
2516
N_("git reflog exists <ref>");
2617

@@ -29,6 +20,7 @@ static timestamp_t default_reflog_expire_unreachable;
2920

3021
struct cmd_reflog_expire_cb {
3122
int stalefix;
23+
int explicit_expiry;
3224
timestamp_t expire_total;
3325
timestamp_t expire_unreachable;
3426
int recno;
@@ -520,18 +512,18 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
520512
return 0;
521513
}
522514

523-
static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, const char *ref)
515+
static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, const char *ref)
524516
{
525517
struct reflog_expire_cfg *ent;
526518

527-
if (slot == (EXPIRE_TOTAL|EXPIRE_UNREACH))
519+
if (cb->explicit_expiry == (EXPIRE_TOTAL|EXPIRE_UNREACH))
528520
return; /* both given explicitly -- nothing to tweak */
529521

530522
for (ent = reflog_expire_cfg; ent; ent = ent->next) {
531523
if (!wildmatch(ent->pattern, ref, 0)) {
532-
if (!(slot & EXPIRE_TOTAL))
524+
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
533525
cb->expire_total = ent->expire_total;
534-
if (!(slot & EXPIRE_UNREACH))
526+
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
535527
cb->expire_unreachable = ent->expire_unreachable;
536528
return;
537529
}
@@ -541,29 +533,89 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
541533
* If unconfigured, make stash never expire
542534
*/
543535
if (!strcmp(ref, "refs/stash")) {
544-
if (!(slot & EXPIRE_TOTAL))
536+
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
545537
cb->expire_total = 0;
546-
if (!(slot & EXPIRE_UNREACH))
538+
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
547539
cb->expire_unreachable = 0;
548540
return;
549541
}
550542

551543
/* Nothing matched -- use the default value */
552-
if (!(slot & EXPIRE_TOTAL))
544+
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
553545
cb->expire_total = default_reflog_expire;
554-
if (!(slot & EXPIRE_UNREACH))
546+
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
555547
cb->expire_unreachable = default_reflog_expire_unreachable;
556548
}
557549

550+
static const char * reflog_expire_usage[] = {
551+
N_("git reflog expire [--expire=<time>] "
552+
"[--expire-unreachable=<time>] "
553+
"[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
554+
"[--verbose] [--all] <refs>..."),
555+
NULL
556+
};
557+
558+
static int expire_unreachable_callback(const struct option *opt,
559+
const char *arg,
560+
int unset)
561+
{
562+
struct cmd_reflog_expire_cb *cmd = opt->value;
563+
564+
if (parse_expiry_date(arg, &cmd->expire_unreachable))
565+
die(_("invalid timestamp '%s' given to '--%s'"),
566+
arg, opt->long_name);
567+
568+
cmd->explicit_expiry |= EXPIRE_UNREACH;
569+
return 0;
570+
}
571+
572+
static int expire_total_callback(const struct option *opt,
573+
const char *arg,
574+
int unset)
575+
{
576+
struct cmd_reflog_expire_cb *cmd = opt->value;
577+
578+
if (parse_expiry_date(arg, &cmd->expire_total))
579+
die(_("invalid timestamp '%s' given to '--%s'"),
580+
arg, opt->long_name);
581+
582+
cmd->explicit_expiry |= EXPIRE_TOTAL;
583+
return 0;
584+
}
585+
558586
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
559587
{
560588
struct cmd_reflog_expire_cb cmd = { 0 };
561589
timestamp_t now = time(NULL);
562590
int i, status, do_all, all_worktrees = 1;
563-
int explicit_expiry = 0;
564591
unsigned int flags = 0;
565592
int verbose = 0;
566593
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
594+
const struct option options[] = {
595+
OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"),
596+
EXPIRE_REFLOGS_DRY_RUN),
597+
OPT_BIT(0, "rewrite", &flags,
598+
N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"),
599+
EXPIRE_REFLOGS_REWRITE),
600+
OPT_BIT(0, "updateref", &flags,
601+
N_("update the reference to the value of the top reflog entry"),
602+
EXPIRE_REFLOGS_UPDATE_REF),
603+
OPT_BOOL(0, "verbose", &verbose, N_("print extra information on screen.")),
604+
OPT_CALLBACK_F(0, "expire", &cmd, N_("timestamp"),
605+
N_("prune entries older than the specified time"),
606+
PARSE_OPT_NONEG,
607+
expire_total_callback),
608+
OPT_CALLBACK_F(0, "expire-unreachable", &cmd, N_("timestamp"),
609+
N_("prune entries older than <time> that are not reachable from the current tip of the branch"),
610+
PARSE_OPT_NONEG,
611+
expire_unreachable_callback),
612+
OPT_BOOL(0, "stale-fix", &cmd.stalefix,
613+
N_("prune any reflog entries that point to broken commits")),
614+
OPT_BOOL(0, "all", &do_all, N_("process the reflogs of all references")),
615+
OPT_BOOL(1, "single-worktree", &all_worktrees,
616+
N_("limits processing to reflogs from the current worktree only.")),
617+
OPT_END()
618+
};
567619

568620
default_reflog_expire_unreachable = now - 30 * 24 * 3600;
569621
default_reflog_expire = now - 90 * 24 * 3600;
@@ -572,45 +624,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
572624
save_commit_buffer = 0;
573625
do_all = status = 0;
574626

627+
cmd.explicit_expiry = 0;
575628
cmd.expire_total = default_reflog_expire;
576629
cmd.expire_unreachable = default_reflog_expire_unreachable;
577630

578-
for (i = 1; i < argc; i++) {
579-
const char *arg = argv[i];
580-
581-
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
582-
flags |= EXPIRE_REFLOGS_DRY_RUN;
583-
else if (skip_prefix(arg, "--expire=", &arg)) {
584-
if (parse_expiry_date(arg, &cmd.expire_total))
585-
die(_("'%s' is not a valid timestamp"), arg);
586-
explicit_expiry |= EXPIRE_TOTAL;
587-
}
588-
else if (skip_prefix(arg, "--expire-unreachable=", &arg)) {
589-
if (parse_expiry_date(arg, &cmd.expire_unreachable))
590-
die(_("'%s' is not a valid timestamp"), arg);
591-
explicit_expiry |= EXPIRE_UNREACH;
592-
}
593-
else if (!strcmp(arg, "--stale-fix"))
594-
cmd.stalefix = 1;
595-
else if (!strcmp(arg, "--rewrite"))
596-
flags |= EXPIRE_REFLOGS_REWRITE;
597-
else if (!strcmp(arg, "--updateref"))
598-
flags |= EXPIRE_REFLOGS_UPDATE_REF;
599-
else if (!strcmp(arg, "--all"))
600-
do_all = 1;
601-
else if (!strcmp(arg, "--single-worktree"))
602-
all_worktrees = 0;
603-
else if (!strcmp(arg, "--verbose"))
604-
verbose = 1;
605-
else if (!strcmp(arg, "--")) {
606-
i++;
607-
break;
608-
}
609-
else if (arg[0] == '-')
610-
usage(_(reflog_expire_usage));
611-
else
612-
break;
613-
}
631+
argc = parse_options(argc, argv, prefix, options, reflog_expire_usage, 0);
614632

615633
if (verbose)
616634
should_prune_fn = should_expire_reflog_ent_verbose;
@@ -657,7 +675,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
657675
.dry_run = !!(flags & EXPIRE_REFLOGS_DRY_RUN),
658676
};
659677

660-
set_reflog_expiry_param(&cb.cmd, explicit_expiry, item->string);
678+
set_reflog_expiry_param(&cb.cmd, item->string);
661679
status |= reflog_expire(item->string, flags,
662680
reflog_expiry_prepare,
663681
should_prune_fn,
@@ -667,15 +685,15 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
667685
string_list_clear(&collected.reflogs, 0);
668686
}
669687

670-
for (; i < argc; i++) {
688+
for (i = 0; i < argc; i++) {
671689
char *ref;
672690
struct expire_reflog_policy_cb cb = { .cmd = cmd };
673691

674692
if (!dwim_log(argv[i], strlen(argv[i]), NULL, &ref)) {
675693
status |= error(_("%s points nowhere!"), argv[i]);
676694
continue;
677695
}
678-
set_reflog_expiry_param(&cb.cmd, explicit_expiry, ref);
696+
set_reflog_expiry_param(&cb.cmd, ref);
679697
status |= reflog_expire(ref, flags,
680698
reflog_expiry_prepare,
681699
should_prune_fn,
@@ -696,41 +714,41 @@ static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
696714
return 0;
697715
}
698716

717+
static const char * reflog_delete_usage[] = {
718+
N_("git reflog delete [--rewrite] [--updateref] "
719+
"[--dry-run | -n] [--verbose] <refs>..."),
720+
NULL
721+
};
722+
699723
static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
700724
{
701725
struct cmd_reflog_expire_cb cmd = { 0 };
702726
int i, status = 0;
703727
unsigned int flags = 0;
704728
int verbose = 0;
705729
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
706-
707-
for (i = 1; i < argc; i++) {
708-
const char *arg = argv[i];
709-
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
710-
flags |= EXPIRE_REFLOGS_DRY_RUN;
711-
else if (!strcmp(arg, "--rewrite"))
712-
flags |= EXPIRE_REFLOGS_REWRITE;
713-
else if (!strcmp(arg, "--updateref"))
714-
flags |= EXPIRE_REFLOGS_UPDATE_REF;
715-
else if (!strcmp(arg, "--verbose"))
716-
verbose = 1;
717-
else if (!strcmp(arg, "--")) {
718-
i++;
719-
break;
720-
}
721-
else if (arg[0] == '-')
722-
usage(_(reflog_delete_usage));
723-
else
724-
break;
725-
}
730+
const struct option options[] = {
731+
OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"),
732+
EXPIRE_REFLOGS_DRY_RUN),
733+
OPT_BIT(0, "rewrite", &flags,
734+
N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"),
735+
EXPIRE_REFLOGS_REWRITE),
736+
OPT_BIT(0, "updateref", &flags,
737+
N_("update the reference to the value of the top reflog entry"),
738+
EXPIRE_REFLOGS_UPDATE_REF),
739+
OPT_BOOL(0, "verbose", &verbose, N_("print extra information on screen.")),
740+
OPT_END()
741+
};
742+
743+
argc = parse_options(argc, argv, prefix, options, reflog_delete_usage, 0);
726744

727745
if (verbose)
728746
should_prune_fn = should_expire_reflog_ent_verbose;
729747

730-
if (argc - i < 1)
748+
if (argc < 1)
731749
return error(_("no reflog specified to delete"));
732750

733-
for ( ; i < argc; i++) {
751+
for (i = 0; i < argc; i++) {
734752
const char *spec = strstr(argv[i], "@{");
735753
char *ep, *ref;
736754
int recno;

0 commit comments

Comments
 (0)