Skip to content
Snippets Groups Projects
Commit 3111b45a2bbf authored by Katsunori FUJIWARA's avatar Katsunori FUJIWARA
Browse files

parsers: make pack_dirstate take now in integer for consistency

On recent OS, 'stat.st_mtime' has a double precision floating point
value to represent nano seconds, but it is not wide enough for actual
file timestamp: nowadays, only 52 - 32 = 20 bit width is available for
decimal places in sec.

Therefore, casting it to 'int' may cause unexpected result. See also
changeset 13272104bb07 fixing issue4836 for detail.

For example, changed file A may be treated as "clean" unexpectedly in
steps below. "rounded now" is the value gotten by rounding via
'int(st.st_mtime)' or so.

    ---------------------+--------------------+------------------------
    "now"                |                    | timestamp of A (time_t)
    float  rounded time_t| action             | FS       dirstate
    ------ ------- ------+--------------------+-------- ---------------
    N+.nnn   N       N   |                    | ---      ---
                         | update file A      |  N
                         | dirstate.normal(A) |           N
    N+.999   N+1     N   |                    |
                         | dirstate.write()   |           N (*1)
                         |    :               |
                         | change file A      |  N
                         |    :               |
    N+1.00   N+1    N+1  |                    |
                         | "hg status" (*2)   |  N        N
    ------ ------- ------+--------------------+-------- ---------------

Timestamp N of A in dirstate isn't dropped at (*1), because "rounded
now" is N+1 at that time, even if 'st_mtime' in 'time_t' is still N.

Then, file A is unexpectedly treated as "clean" at (*2) in this case.

For consistent handling of 'stat.st_mtime', this patch makes
'pack_dirstate()' take 'now' argument not in floating point but in
integer.

This patch makes 'PyArg_ParseTuple()' in 'pack_dirstate()' use format
'i' (= checking type mismatch or overflow), even though it is ensured
that 'now' is in the range of 32bit signed integer by masking with
'_rangemask' (= 0x7fffffff) on caller side.

It should be cheaper enough than packing itself, and useful to
detect that legacy code invokes 'pack_dirstate()' with 'now' in
floating point value.
parent ae5f7be2b4ab
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment