Junio C Hamano <gitster@xxxxxxxxx> writes: > You've taught people here and on the kernel list that the "date" can use > any non-digit-non-word as a word separator, and "git log --since 2.days" > is something you often do. > > People who followed that advice would have gotten used to this already, e.g. > > $ git reflog delete master@{07.04.2005.15:15:00.-0700} > > should not be broken. > > I think your first hunk needs to distinguish between "very-long-precision > posint" (in which case we ignore because it is likely to be nanoseconds > fraction) and others. Perhaps like this. -- >8 -- From: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Date: Sat, 16 Aug 2008 16:17:50 -0700 Subject: [PATCH] date parsing: do not mistake fractional nanosecond that follow HH:MM:SS Some program output nanosecond fractional after the usual HH:MM:SS format. If the fraction is large enough, it can be interpreted as the seconds since epoch, and can overwrite the already parsed date/time. We also make sure we use the seconds since epoch interpretation only when we have not seen any other date/time data in the input yet. Note that we cannot unconditionally drop anything that follows '.'; people have been taught that we allow '.' as a word separator and have got used to formats like "--since 2.days" and "2008.08.16.01:23:45.-0700" to work. Noticed-by: Hermann Gausterer Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- date.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletions(-) diff --git a/date.c b/date.c index 35a5257..b2c5a8b 100644 --- a/date.c +++ b/date.c @@ -363,6 +363,11 @@ static int match_multi_number(unsigned long num, char c, const char *date, char tm->tm_hour = num; tm->tm_min = num2; tm->tm_sec = num3; + if (*end == '.') { + num = strspn(end+1, "0123456789"); + if (9 <= num) + end += num + 1; + } break; } return 0; @@ -402,6 +407,15 @@ static int match_multi_number(unsigned long num, char c, const char *date, char return end - date; } +/* Have we filled in any part of the time/date yet? */ +static inline int nodate(struct tm *tm) +{ + return tm->tm_year < 0 && + tm->tm_mon < 0 && + tm->tm_mday < 0 && + !(tm->tm_hour | tm->tm_min | tm->tm_sec); +} + /* * We've seen a digit. Time? Year? Date? */ @@ -418,7 +432,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt * more than 8 digits. This is because we don't want to rule out * numbers like 20070606 as a YYYYMMDD date. */ - if (num >= 100000000) { + if (num >= 100000000 && nodate(tm)) { time_t time = num; if (gmtime_r(&time, tm)) { *tm_gmt = 1; -- 1.6.0.rc3.17.gc14c8 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html