Skip to content

Commit 3d27b9b

Browse files
committed
date.c: add parse_expiry_date()
"git reflog --expire=all" tries to expire reflog entries up to the current second, because the approxidate() parser gives the current timestamp for anything it does not understand (and it does not know what time "all" means). When the user tells us to expire "all" (or set the expiration time to "now"), the user wants to remove all the reflog entries (no reflog entry should record future time). Just set it to ULONG_MAX and to let everything that is older that timestamp expire. While at it, allow "now" to be treated the same way for callers that parse expiry date timestamp with this function. Also use an error reporting version of approxidate() to report misspelled date. When the user says e.g. "--expire=mnoday" to delete entries two days or older on Wednesday, we wouldn't want the "unknown, default to now" logic to kick in. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 04a74b6 commit 3d27b9b

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

builtin/reflog.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,9 @@ static int parse_expire_cfg_value(const char *var, const char *value, unsigned l
496496
{
497497
if (!value)
498498
return config_error_nonbool(var);
499-
if (!strcmp(value, "never") || !strcmp(value, "false")) {
500-
*expire = 0;
501-
return 0;
502-
}
503-
*expire = approxidate(value);
499+
if (parse_expiry_date(value, expire))
500+
return error(_("%s' for '%s' is not a valid timestamp"),
501+
value, var);
504502
return 0;
505503
}
506504

@@ -613,11 +611,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
613611
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
614612
cb.dry_run = 1;
615613
else if (!prefixcmp(arg, "--expire=")) {
616-
cb.expire_total = approxidate(arg + 9);
614+
if (parse_expiry_date(arg + 9, &cb.expire_total))
615+
die(_("'%s' is not a valid timestamp"), arg);
617616
explicit_expiry |= EXPIRE_TOTAL;
618617
}
619618
else if (!prefixcmp(arg, "--expire-unreachable=")) {
620-
cb.expire_unreachable = approxidate(arg + 21);
619+
if (parse_expiry_date(arg + 21, &cb.expire_unreachable))
620+
die(_("'%s' is not a valid timestamp"), arg);
621621
explicit_expiry |= EXPIRE_UNREACH;
622622
}
623623
else if (!strcmp(arg, "--stale-fix"))

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ void show_date_relative(unsigned long time, int tz, const struct timeval *now,
878878
struct strbuf *timebuf);
879879
int parse_date(const char *date, char *buf, int bufsize);
880880
int parse_date_basic(const char *date, unsigned long *timestamp, int *offset);
881+
int parse_expiry_date(const char *date, unsigned long *timestamp);
881882
void datestamp(char *buf, int bufsize);
882883
#define approxidate(s) approxidate_careful((s), NULL)
883884
unsigned long approxidate_careful(const char *, int *);

date.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,28 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
705705
return 0; /* success */
706706
}
707707

708+
int parse_expiry_date(const char *date, unsigned long *timestamp)
709+
{
710+
int errors = 0;
711+
712+
if (!strcmp(date, "never") || !strcmp(date, "false"))
713+
*timestamp = 0;
714+
else if (!strcmp(date, "all") || !strcmp(date, "now"))
715+
/*
716+
* We take over "now" here, which usually translates
717+
* to the current timestamp. This is because the user
718+
* really means to expire everything she has done in
719+
* the past, and by definition reflogs are the record
720+
* of the past, and there is nothing from the future
721+
* to be kept.
722+
*/
723+
*timestamp = ULONG_MAX;
724+
else
725+
*timestamp = approxidate_careful(date, &errors);
726+
727+
return errors;
728+
}
729+
708730
int parse_date(const char *date, char *result, int maxlen)
709731
{
710732
unsigned long timestamp;

0 commit comments

Comments
 (0)