diff --git a/builtin/reflog.c b/builtin/reflog.c index b3c9e27bde..44700f9243 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -496,11 +496,9 @@ static int parse_expire_cfg_value(const char *var, const char *value, unsigned l { if (!value) return config_error_nonbool(var); - if (!strcmp(value, "never") || !strcmp(value, "false")) { - *expire = 0; - return 0; - } - *expire = approxidate(value); + if (parse_expiry_date(value, expire)) + return error(_("%s' for '%s' is not a valid timestamp"), + value, var); return 0; } @@ -613,11 +611,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n")) cb.dry_run = 1; else if (!prefixcmp(arg, "--expire=")) { - cb.expire_total = approxidate(arg + 9); + if (parse_expiry_date(arg + 9, &cb.expire_total)) + die(_("'%s' is not a valid timestamp"), arg); explicit_expiry |= EXPIRE_TOTAL; } else if (!prefixcmp(arg, "--expire-unreachable=")) { - cb.expire_unreachable = approxidate(arg + 21); + if (parse_expiry_date(arg + 21, &cb.expire_unreachable)) + die(_("'%s' is not a valid timestamp"), arg); explicit_expiry |= EXPIRE_UNREACH; } else if (!strcmp(arg, "--stale-fix")) diff --git a/cache.h b/cache.h index 3622e18415..f43f6d94e3 100644 --- a/cache.h +++ b/cache.h @@ -878,6 +878,7 @@ void show_date_relative(unsigned long time, int tz, const struct timeval *now, struct strbuf *timebuf); int parse_date(const char *date, char *buf, int bufsize); int parse_date_basic(const char *date, unsigned long *timestamp, int *offset); +int parse_expiry_date(const char *date, unsigned long *timestamp); void datestamp(char *buf, int bufsize); #define approxidate(s) approxidate_careful((s), NULL) unsigned long approxidate_careful(const char *, int *); diff --git a/date.c b/date.c index 57331ed406..876d679b1e 100644 --- a/date.c +++ b/date.c @@ -705,6 +705,28 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset) return 0; /* success */ } +int parse_expiry_date(const char *date, unsigned long *timestamp) +{ + int errors = 0; + + if (!strcmp(date, "never") || !strcmp(date, "false")) + *timestamp = 0; + else if (!strcmp(date, "all") || !strcmp(date, "now")) + /* + * We take over "now" here, which usually translates + * to the current timestamp. This is because the user + * really means to expire everything she has done in + * the past, and by definition reflogs are the record + * of the past, and there is nothing from the future + * to be kept. + */ + *timestamp = ULONG_MAX; + else + *timestamp = approxidate_careful(date, &errors); + + return errors; +} + int parse_date(const char *date, char *result, int maxlen) { unsigned long timestamp;