Note: if you need to delay the commit in a very distant future, Git 2.13.x / Git 2.14 (Q3 2017) will satisfy your needs.
Git source code refers to timestamps as unsigned long.
On 32-bit platforms, as on Windows, the unsigned long is not large enough to capture dates that are "absurd in the future."
Of course, by the C standard, this is completely true for long data type to refer to 32-bit integers. This is why the time_t data type exists: so it can be 64-bit, even if long 32-bit.
Git source code just uses the wrong data type for timestamps, that’s it.
See commit 28f4aee , commit 1e65a98 , commit dddbad7 (April 26, 2017), commit cb71f8b , commit 1aeb7e7 (April 21, 2017) and commit efac8ac , commit a07fb05 , commit e467dc1 (April 20, 2017) Johannes Schindelin ( dscho )
See commit 3f78971 (May 08, 2017) by Ramsey Jones ('') .
(Merged by Junio C Hamano - [TG44] - in commit b15667b , 16 May 2017)
use uintmax_t for timestamps
Earlier we used unsigned long for timestamps. This was just a good choice on Linux, where we implicitly know that unsigned long is what is used for time_t .
However, we want to use a different data type for timestamps for two reasons:
there is nothing that says that the unsigned long must be the same data type as time_t , and indeed, for example, in 64-bit Windows it is not:
unsigned long is 32-bit, but time_t is 64-bit.
even on 32-bit Linux, where the unsigned long (and therefore time_t ) is 32-bit, we want to be able to encode timestamps in Git, which are currently absurd in the future, even if the system library is not able to format these timestamps in date strings.
So let's just switch to the maximum available integer type, which should be at least 64-bit for all practical purposes these days. This, of course, could not be worse than an unsigned long , so ...
This is based on commit dddbad7 (part of this patch):
timestamp_t : new data type for timestamps
Git source code assumes unsigned long is at least as accurate as time_t . Which is wrong and causes a lot of problems, in particular where the unsigned long is only 32-bit (especially on Windows, even in the 64-bit version).
So let's just use a more appropriate data type.
In preparation for this, we are introducing a new timestamp_t data type.
Since we will use a data type that is not necessarily identical to time_t , we must be very careful to use time_t whenever we interact with system functions and timestamp_t everywhere.
Please note that prior to Git 2.24 (Q4 2019) this new type of timestamp_t had flaws.
See the commit 2e09c01 (September 24, 2019) from SZEDER Gábor ( szeder ) .
Assistant: Johannes Sixt ( j6t ) .
(Merged by Junio C Hamano - [TG425] - in commit 0b4fae5 , 09 Oct 2019)
name-rev : avoid clipping timestamp
When ' git name-rev ' is called with commit-ish parameters, it tries to save some work and does not visit commits older than the commit date of the oldest given commit minus a one-day decline.
Since our ' timestamp_t ' is an unsigned type, this leads to the loss of the timestamp when the date of adoption of the oldest given commit is within the day of the UNIX era.
As a result, the cutoff timestamp ends very far in the future, and “ git name-rev ” does not visit any commits, and calls each given commit as “undefined”.
Check if subtracting the deviation from the oldest committer date will result in insufficient overflow, in which case do not use clipping.
We do not have the TIME_MIN constant, dddbad7 ( timestamp_t : new data type for timestamps, 2017-04-26, Git v2.14.0-rc0) did not add it, so do it now.
Note that the type of cutoff timestamp variable used to sign up to 5589e87 ( name-rev : change the long variable to timestamp_t , 2017-05-20, Git v2. 14.0-RC0).
The behavior remained the same even then, but the flaw did not occur when subtracting the deviation from the oldest committer date, but when comparing the signed clipping timestamp with dates without a signature in name_rev() .
IOW, this error is not as old as git name-rev .