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 subcommandsmaint
commit
1b4d9b4512
174
builtin/reflog.c
174
builtin/reflog.c
|
@ -12,15 +12,6 @@
|
||||||
#include "reachable.h"
|
#include "reachable.h"
|
||||||
#include "worktree.h"
|
#include "worktree.h"
|
||||||
|
|
||||||
/* NEEDSWORK: switch to using parse_options */
|
|
||||||
static const char reflog_expire_usage[] =
|
|
||||||
N_("git reflog expire [--expire=<time>] "
|
|
||||||
"[--expire-unreachable=<time>] "
|
|
||||||
"[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
|
|
||||||
"[--verbose] [--all] <refs>...");
|
|
||||||
static const char reflog_delete_usage[] =
|
|
||||||
N_("git reflog delete [--rewrite] [--updateref] "
|
|
||||||
"[--dry-run | -n] [--verbose] <refs>...");
|
|
||||||
static const char reflog_exists_usage[] =
|
static const char reflog_exists_usage[] =
|
||||||
N_("git reflog exists <ref>");
|
N_("git reflog exists <ref>");
|
||||||
|
|
||||||
|
@ -29,6 +20,7 @@ static timestamp_t default_reflog_expire_unreachable;
|
||||||
|
|
||||||
struct cmd_reflog_expire_cb {
|
struct cmd_reflog_expire_cb {
|
||||||
int stalefix;
|
int stalefix;
|
||||||
|
int explicit_expiry;
|
||||||
timestamp_t expire_total;
|
timestamp_t expire_total;
|
||||||
timestamp_t expire_unreachable;
|
timestamp_t expire_unreachable;
|
||||||
int recno;
|
int recno;
|
||||||
|
@ -520,18 +512,18 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, const char *ref)
|
static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, const char *ref)
|
||||||
{
|
{
|
||||||
struct reflog_expire_cfg *ent;
|
struct reflog_expire_cfg *ent;
|
||||||
|
|
||||||
if (slot == (EXPIRE_TOTAL|EXPIRE_UNREACH))
|
if (cb->explicit_expiry == (EXPIRE_TOTAL|EXPIRE_UNREACH))
|
||||||
return; /* both given explicitly -- nothing to tweak */
|
return; /* both given explicitly -- nothing to tweak */
|
||||||
|
|
||||||
for (ent = reflog_expire_cfg; ent; ent = ent->next) {
|
for (ent = reflog_expire_cfg; ent; ent = ent->next) {
|
||||||
if (!wildmatch(ent->pattern, ref, 0)) {
|
if (!wildmatch(ent->pattern, ref, 0)) {
|
||||||
if (!(slot & EXPIRE_TOTAL))
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
|
||||||
cb->expire_total = ent->expire_total;
|
cb->expire_total = ent->expire_total;
|
||||||
if (!(slot & EXPIRE_UNREACH))
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
|
||||||
cb->expire_unreachable = ent->expire_unreachable;
|
cb->expire_unreachable = ent->expire_unreachable;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -541,29 +533,89 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
|
||||||
* If unconfigured, make stash never expire
|
* If unconfigured, make stash never expire
|
||||||
*/
|
*/
|
||||||
if (!strcmp(ref, "refs/stash")) {
|
if (!strcmp(ref, "refs/stash")) {
|
||||||
if (!(slot & EXPIRE_TOTAL))
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
|
||||||
cb->expire_total = 0;
|
cb->expire_total = 0;
|
||||||
if (!(slot & EXPIRE_UNREACH))
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
|
||||||
cb->expire_unreachable = 0;
|
cb->expire_unreachable = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing matched -- use the default value */
|
/* Nothing matched -- use the default value */
|
||||||
if (!(slot & EXPIRE_TOTAL))
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL))
|
||||||
cb->expire_total = default_reflog_expire;
|
cb->expire_total = default_reflog_expire;
|
||||||
if (!(slot & EXPIRE_UNREACH))
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH))
|
||||||
cb->expire_unreachable = default_reflog_expire_unreachable;
|
cb->expire_unreachable = default_reflog_expire_unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * reflog_expire_usage[] = {
|
||||||
|
N_("git reflog expire [--expire=<time>] "
|
||||||
|
"[--expire-unreachable=<time>] "
|
||||||
|
"[--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] "
|
||||||
|
"[--verbose] [--all] <refs>..."),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static int expire_unreachable_callback(const struct option *opt,
|
||||||
|
const char *arg,
|
||||||
|
int unset)
|
||||||
|
{
|
||||||
|
struct cmd_reflog_expire_cb *cmd = opt->value;
|
||||||
|
|
||||||
|
if (parse_expiry_date(arg, &cmd->expire_unreachable))
|
||||||
|
die(_("invalid timestamp '%s' given to '--%s'"),
|
||||||
|
arg, opt->long_name);
|
||||||
|
|
||||||
|
cmd->explicit_expiry |= EXPIRE_UNREACH;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int expire_total_callback(const struct option *opt,
|
||||||
|
const char *arg,
|
||||||
|
int unset)
|
||||||
|
{
|
||||||
|
struct cmd_reflog_expire_cb *cmd = opt->value;
|
||||||
|
|
||||||
|
if (parse_expiry_date(arg, &cmd->expire_total))
|
||||||
|
die(_("invalid timestamp '%s' given to '--%s'"),
|
||||||
|
arg, opt->long_name);
|
||||||
|
|
||||||
|
cmd->explicit_expiry |= EXPIRE_TOTAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct cmd_reflog_expire_cb cmd = { 0 };
|
struct cmd_reflog_expire_cb cmd = { 0 };
|
||||||
timestamp_t now = time(NULL);
|
timestamp_t now = time(NULL);
|
||||||
int i, status, do_all, all_worktrees = 1;
|
int i, status, do_all, all_worktrees = 1;
|
||||||
int explicit_expiry = 0;
|
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
|
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
|
||||||
|
const struct option options[] = {
|
||||||
|
OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"),
|
||||||
|
EXPIRE_REFLOGS_DRY_RUN),
|
||||||
|
OPT_BIT(0, "rewrite", &flags,
|
||||||
|
N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"),
|
||||||
|
EXPIRE_REFLOGS_REWRITE),
|
||||||
|
OPT_BIT(0, "updateref", &flags,
|
||||||
|
N_("update the reference to the value of the top reflog entry"),
|
||||||
|
EXPIRE_REFLOGS_UPDATE_REF),
|
||||||
|
OPT_BOOL(0, "verbose", &verbose, N_("print extra information on screen.")),
|
||||||
|
OPT_CALLBACK_F(0, "expire", &cmd, N_("timestamp"),
|
||||||
|
N_("prune entries older than the specified time"),
|
||||||
|
PARSE_OPT_NONEG,
|
||||||
|
expire_total_callback),
|
||||||
|
OPT_CALLBACK_F(0, "expire-unreachable", &cmd, N_("timestamp"),
|
||||||
|
N_("prune entries older than <time> that are not reachable from the current tip of the branch"),
|
||||||
|
PARSE_OPT_NONEG,
|
||||||
|
expire_unreachable_callback),
|
||||||
|
OPT_BOOL(0, "stale-fix", &cmd.stalefix,
|
||||||
|
N_("prune any reflog entries that point to broken commits")),
|
||||||
|
OPT_BOOL(0, "all", &do_all, N_("process the reflogs of all references")),
|
||||||
|
OPT_BOOL(1, "single-worktree", &all_worktrees,
|
||||||
|
N_("limits processing to reflogs from the current worktree only.")),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
default_reflog_expire_unreachable = now - 30 * 24 * 3600;
|
default_reflog_expire_unreachable = now - 30 * 24 * 3600;
|
||||||
default_reflog_expire = now - 90 * 24 * 3600;
|
default_reflog_expire = now - 90 * 24 * 3600;
|
||||||
|
@ -572,45 +624,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||||
save_commit_buffer = 0;
|
save_commit_buffer = 0;
|
||||||
do_all = status = 0;
|
do_all = status = 0;
|
||||||
|
|
||||||
|
cmd.explicit_expiry = 0;
|
||||||
cmd.expire_total = default_reflog_expire;
|
cmd.expire_total = default_reflog_expire;
|
||||||
cmd.expire_unreachable = default_reflog_expire_unreachable;
|
cmd.expire_unreachable = default_reflog_expire_unreachable;
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
argc = parse_options(argc, argv, prefix, options, reflog_expire_usage, 0);
|
||||||
const char *arg = argv[i];
|
|
||||||
|
|
||||||
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
|
|
||||||
flags |= EXPIRE_REFLOGS_DRY_RUN;
|
|
||||||
else if (skip_prefix(arg, "--expire=", &arg)) {
|
|
||||||
if (parse_expiry_date(arg, &cmd.expire_total))
|
|
||||||
die(_("'%s' is not a valid timestamp"), arg);
|
|
||||||
explicit_expiry |= EXPIRE_TOTAL;
|
|
||||||
}
|
|
||||||
else if (skip_prefix(arg, "--expire-unreachable=", &arg)) {
|
|
||||||
if (parse_expiry_date(arg, &cmd.expire_unreachable))
|
|
||||||
die(_("'%s' is not a valid timestamp"), arg);
|
|
||||||
explicit_expiry |= EXPIRE_UNREACH;
|
|
||||||
}
|
|
||||||
else if (!strcmp(arg, "--stale-fix"))
|
|
||||||
cmd.stalefix = 1;
|
|
||||||
else if (!strcmp(arg, "--rewrite"))
|
|
||||||
flags |= EXPIRE_REFLOGS_REWRITE;
|
|
||||||
else if (!strcmp(arg, "--updateref"))
|
|
||||||
flags |= EXPIRE_REFLOGS_UPDATE_REF;
|
|
||||||
else if (!strcmp(arg, "--all"))
|
|
||||||
do_all = 1;
|
|
||||||
else if (!strcmp(arg, "--single-worktree"))
|
|
||||||
all_worktrees = 0;
|
|
||||||
else if (!strcmp(arg, "--verbose"))
|
|
||||||
verbose = 1;
|
|
||||||
else if (!strcmp(arg, "--")) {
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (arg[0] == '-')
|
|
||||||
usage(_(reflog_expire_usage));
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
should_prune_fn = should_expire_reflog_ent_verbose;
|
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)
|
||||||
.dry_run = !!(flags & EXPIRE_REFLOGS_DRY_RUN),
|
.dry_run = !!(flags & EXPIRE_REFLOGS_DRY_RUN),
|
||||||
};
|
};
|
||||||
|
|
||||||
set_reflog_expiry_param(&cb.cmd, explicit_expiry, item->string);
|
set_reflog_expiry_param(&cb.cmd, item->string);
|
||||||
status |= reflog_expire(item->string, flags,
|
status |= reflog_expire(item->string, flags,
|
||||||
reflog_expiry_prepare,
|
reflog_expiry_prepare,
|
||||||
should_prune_fn,
|
should_prune_fn,
|
||||||
|
@ -667,7 +685,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||||
string_list_clear(&collected.reflogs, 0);
|
string_list_clear(&collected.reflogs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
char *ref;
|
char *ref;
|
||||||
struct expire_reflog_policy_cb cb = { .cmd = cmd };
|
struct expire_reflog_policy_cb cb = { .cmd = cmd };
|
||||||
|
|
||||||
|
@ -675,7 +693,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
||||||
status |= error(_("%s points nowhere!"), argv[i]);
|
status |= error(_("%s points nowhere!"), argv[i]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set_reflog_expiry_param(&cb.cmd, explicit_expiry, ref);
|
set_reflog_expiry_param(&cb.cmd, ref);
|
||||||
status |= reflog_expire(ref, flags,
|
status |= reflog_expire(ref, flags,
|
||||||
reflog_expiry_prepare,
|
reflog_expiry_prepare,
|
||||||
should_prune_fn,
|
should_prune_fn,
|
||||||
|
@ -696,6 +714,12 @@ static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * reflog_delete_usage[] = {
|
||||||
|
N_("git reflog delete [--rewrite] [--updateref] "
|
||||||
|
"[--dry-run | -n] [--verbose] <refs>..."),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct cmd_reflog_expire_cb cmd = { 0 };
|
struct cmd_reflog_expire_cb cmd = { 0 };
|
||||||
|
@ -703,34 +727,28 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
int verbose = 0;
|
int verbose = 0;
|
||||||
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
|
reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent;
|
||||||
|
const struct option options[] = {
|
||||||
|
OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"),
|
||||||
|
EXPIRE_REFLOGS_DRY_RUN),
|
||||||
|
OPT_BIT(0, "rewrite", &flags,
|
||||||
|
N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"),
|
||||||
|
EXPIRE_REFLOGS_REWRITE),
|
||||||
|
OPT_BIT(0, "updateref", &flags,
|
||||||
|
N_("update the reference to the value of the top reflog entry"),
|
||||||
|
EXPIRE_REFLOGS_UPDATE_REF),
|
||||||
|
OPT_BOOL(0, "verbose", &verbose, N_("print extra information on screen.")),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
for (i = 1; i < argc; i++) {
|
argc = parse_options(argc, argv, prefix, options, reflog_delete_usage, 0);
|
||||||
const char *arg = argv[i];
|
|
||||||
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
|
|
||||||
flags |= EXPIRE_REFLOGS_DRY_RUN;
|
|
||||||
else if (!strcmp(arg, "--rewrite"))
|
|
||||||
flags |= EXPIRE_REFLOGS_REWRITE;
|
|
||||||
else if (!strcmp(arg, "--updateref"))
|
|
||||||
flags |= EXPIRE_REFLOGS_UPDATE_REF;
|
|
||||||
else if (!strcmp(arg, "--verbose"))
|
|
||||||
verbose = 1;
|
|
||||||
else if (!strcmp(arg, "--")) {
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (arg[0] == '-')
|
|
||||||
usage(_(reflog_delete_usage));
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
should_prune_fn = should_expire_reflog_ent_verbose;
|
should_prune_fn = should_expire_reflog_ent_verbose;
|
||||||
|
|
||||||
if (argc - i < 1)
|
if (argc < 1)
|
||||||
return error(_("no reflog specified to delete"));
|
return error(_("no reflog specified to delete"));
|
||||||
|
|
||||||
for ( ; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
const char *spec = strstr(argv[i], "@{");
|
const char *spec = strstr(argv[i], "@{");
|
||||||
char *ep, *ref;
|
char *ep, *ref;
|
||||||
int recno;
|
int recno;
|
||||||
|
|
Loading…
Reference in New Issue