|
|
|
@ -12,15 +12,6 @@
@@ -12,15 +12,6 @@
|
|
|
|
|
#include "reachable.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[] = |
|
|
|
|
N_("git reflog exists <ref>"); |
|
|
|
|
|
|
|
|
@ -29,6 +20,7 @@ static timestamp_t default_reflog_expire_unreachable;
@@ -29,6 +20,7 @@ static timestamp_t default_reflog_expire_unreachable;
|
|
|
|
|
|
|
|
|
|
struct cmd_reflog_expire_cb { |
|
|
|
|
int stalefix; |
|
|
|
|
int explicit_expiry; |
|
|
|
|
timestamp_t expire_total; |
|
|
|
|
timestamp_t expire_unreachable; |
|
|
|
|
int recno; |
|
|
|
@ -520,18 +512,18 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
@@ -520,18 +512,18 @@ static int reflog_expire_config(const char *var, const char *value, void *cb)
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
if (slot == (EXPIRE_TOTAL|EXPIRE_UNREACH)) |
|
|
|
|
if (cb->explicit_expiry == (EXPIRE_TOTAL|EXPIRE_UNREACH)) |
|
|
|
|
return; /* both given explicitly -- nothing to tweak */ |
|
|
|
|
|
|
|
|
|
for (ent = reflog_expire_cfg; ent; ent = ent->next) { |
|
|
|
|
if (!wildmatch(ent->pattern, ref, 0)) { |
|
|
|
|
if (!(slot & EXPIRE_TOTAL)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL)) |
|
|
|
|
cb->expire_total = ent->expire_total; |
|
|
|
|
if (!(slot & EXPIRE_UNREACH)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH)) |
|
|
|
|
cb->expire_unreachable = ent->expire_unreachable; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -541,29 +533,89 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c
@@ -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 (!strcmp(ref, "refs/stash")) { |
|
|
|
|
if (!(slot & EXPIRE_TOTAL)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL)) |
|
|
|
|
cb->expire_total = 0; |
|
|
|
|
if (!(slot & EXPIRE_UNREACH)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH)) |
|
|
|
|
cb->expire_unreachable = 0; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Nothing matched -- use the default value */ |
|
|
|
|
if (!(slot & EXPIRE_TOTAL)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_TOTAL)) |
|
|
|
|
cb->expire_total = default_reflog_expire; |
|
|
|
|
if (!(slot & EXPIRE_UNREACH)) |
|
|
|
|
if (!(cb->explicit_expiry & EXPIRE_UNREACH)) |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
struct cmd_reflog_expire_cb cmd = { 0 }; |
|
|
|
|
timestamp_t now = time(NULL); |
|
|
|
|
int i, status, do_all, all_worktrees = 1; |
|
|
|
|
int explicit_expiry = 0; |
|
|
|
|
unsigned int flags = 0; |
|
|
|
|
int verbose = 0; |
|
|
|
|
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 = now - 90 * 24 * 3600; |
|
|
|
@ -572,45 +624,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
@@ -572,45 +624,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|
|
|
|
save_commit_buffer = 0; |
|
|
|
|
do_all = status = 0; |
|
|
|
|
|
|
|
|
|
cmd.explicit_expiry = 0; |
|
|
|
|
cmd.expire_total = default_reflog_expire; |
|
|
|
|
cmd.expire_unreachable = default_reflog_expire_unreachable; |
|
|
|
|
|
|
|
|
|
for (i = 1; i < argc; i++) { |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
argc = parse_options(argc, argv, prefix, options, reflog_expire_usage, 0); |
|
|
|
|
|
|
|
|
|
if (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)
@@ -657,7 +675,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|
|
|
|
.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, |
|
|
|
|
reflog_expiry_prepare, |
|
|
|
|
should_prune_fn, |
|
|
|
@ -667,7 +685,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
@@ -667,7 +685,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|
|
|
|
string_list_clear(&collected.reflogs, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (; i < argc; i++) { |
|
|
|
|
for (i = 0; i < argc; i++) { |
|
|
|
|
char *ref; |
|
|
|
|
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)
@@ -675,7 +693,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|
|
|
|
status |= error(_("%s points nowhere!"), argv[i]); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
set_reflog_expiry_param(&cb.cmd, explicit_expiry, ref); |
|
|
|
|
set_reflog_expiry_param(&cb.cmd, ref); |
|
|
|
|
status |= reflog_expire(ref, flags, |
|
|
|
|
reflog_expiry_prepare, |
|
|
|
|
should_prune_fn, |
|
|
|
@ -696,6 +714,12 @@ static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
@@ -696,6 +714,12 @@ static int count_reflog_ent(struct object_id *ooid, struct object_id *noid,
|
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
struct cmd_reflog_expire_cb cmd = { 0 }; |
|
|
|
@ -703,34 +727,28 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
@@ -703,34 +727,28 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
|
|
|
|
|
unsigned int flags = 0; |
|
|
|
|
int verbose = 0; |
|
|
|
|
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++) { |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
argc = parse_options(argc, argv, prefix, options, reflog_delete_usage, 0); |
|
|
|
|
|
|
|
|
|
if (verbose) |
|
|
|
|
should_prune_fn = should_expire_reflog_ent_verbose; |
|
|
|
|
|
|
|
|
|
if (argc - i < 1) |
|
|
|
|
if (argc < 1) |
|
|
|
|
return error(_("no reflog specified to delete")); |
|
|
|
|
|
|
|
|
|
for ( ; i < argc; i++) { |
|
|
|
|
for (i = 0; i < argc; i++) { |
|
|
|
|
const char *spec = strstr(argv[i], "@{"); |
|
|
|
|
char *ep, *ref; |
|
|
|
|
int recno; |
|
|
|
|