git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [BUG] minor: wrong handling of GIT_AUTHOR_DATE

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Aug 17, 2008, 04:25 UTC
Message-ID
<alpine.LFD.1.10.0808162054050.3324@nehalem.linux-foundation.org>
In-Reply-To
<7vk5egbaft.fsf@gitster.siamese.dyndns.org>
On Sat, 16 Aug 2008, Junio C Hamano wrote:
> 
> Perhaps like this.

So see in the previous email why I don't think "ignore nanoseconds" is really any better than "igore all fractions".

That said:
Show 8 quoted lines
> @@ -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;

Apart from the "compare with 9", your patch is _much_ better than mine. Using "strtoul()" was a horrible horrible thing to do, since it will match not just '+' and '-' but also spaces etc.

So my patch was definitely crap, and yours is better, but I don't much like that expectations of 9+ digits. After all, if we only worry about 9+ digits of a big number, then the "nodate()" logic already takes care of much of it.

So here's a much better version, I think.
The rules are:
 - valid days of month/mday are always single or double digits.
 - valid years are either two or four digits
   No, we don't support the year 600 _anyway_, since our encoding is based 
   on the UNIX epoch, and the day we worry about the year 10,000 is far 
   away and we can raise the limit to five digits when we get closer.
 - Other numbers (eg "600 days ago") can have any number of digits, but 
   they cannot start with a zero. Again, the only exception is for 
   two-digit numbers, since that is fairly common for dates ("Dec 01" is 
   not unheard of)

So that means that any milli- or micro-second would be thrown out just because the number of digits shows that it cannot be an interesting date.

That would make the patch look something like this...
[ Those four deleted lines I removed just because the cases had already 
  been handled, eg the ">1900" case was already handled when we checked 
  for a four-digit year, and the >70 case was handled when we checked for 
  exactly two digits ]
Hmm?
		Linus
---
 date.c |   26 ++++++++++++++++++++------
 1 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/date.c b/date.c
index 35a5257..950b88f 100644
--- a/date.c
+++ b/date.c
@@ -402,6 +402,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 +427,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;
@@ -463,6 +472,13 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
 	}
 
 	/*
+	 * Ignore lots of numerals. We took care of 4-digit years above.
+	 * Days or months must be one or two digits.
+	 */
+	if (n > 2)
+		return n;
+
+	/*
 	 * NOTE! We will give precedence to day-of-month over month or
 	 * year numbers in the 1-12 range. So 05 is always "mday 5",
 	 * unless we already have a mday..
@@ -488,10 +504,6 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
 
 	if (num > 0 && num < 32) {
 		tm->tm_mday = num;
-	} else if (num > 1900) {
-		tm->tm_year = num - 1900;
-	} else if (num > 70) {
-		tm->tm_year = num;
 	} else if (num > 0 && num < 13) {
 		tm->tm_mon = num-1;
 	}
@@ -823,7 +835,9 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
 		}
 	}
 
-	*num = number;
+	/* Accept zero-padding only for small numbers ("Dec 02", never "Dec 0002") */
+	if (date[0] != '0' || end - date <= 2)
+		*num = number;
 	return end;
 }
 
Previous: Junio C HamanoNext: Linus Torvalds
Message 6 of 10 in “[BUG] minor: wrong handling of GIT_AUTHOR_DATE”
  1. Hermann GaustererAug 16, 2008
  2. Linus TorvaldsAug 16, 2008
  3. Linus TorvaldsAug 16, 2008
  4. Junio C HamanoAug 17, 2008
  5. Junio C HamanoAug 17, 2008
  6. Linus TorvaldsAug 17, 2008
  7. Linus TorvaldsAug 17, 2008
  8. Junio C HamanoAug 17, 2008
  9. Linus TorvaldsAug 17, 2008
  10. Linus TorvaldsAug 17, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.