mercurial/dirstateutils/timestamp.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 24 Nov 2021 05:00:28 +0100
changeset 48451 ca42667c8d26
parent 48446 111098af6356
child 48468 000130cfafb6
permissions -rw-r--r--
status: keep second-ambiguous mtimes during fixup Now that we support the feature, we can keep "second ambiguous" mtime during the fixup phase. These are the mtime that would be ambiguous if we did not had sub-second précions. See the v2 format documentation for details. Differential Revision: https://phab.mercurial-scm.org/D11847
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     1
# Copyright Mercurial Contributors
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     2
#
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     4
# GNU General Public License version 2 or any later version.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     5
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     6
from __future__ import absolute_import
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
     7
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
     8
import functools
48427
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
     9
import os
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    10
import stat
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    11
48445
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    12
from .. import error
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    13
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    14
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    15
rangemask = 0x7FFFFFFF
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    16
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    17
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    18
@functools.total_ordering
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    19
class timestamp(tuple):
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    20
    """
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    21
    A Unix timestamp with optional nanoseconds precision,
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    22
    modulo 2**31 seconds.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    23
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    24
    A 2-tuple containing:
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    25
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    26
    `truncated_seconds`: seconds since the Unix epoch,
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    27
    truncated to its lower 31 bits
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    28
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    29
    `subsecond_nanoseconds`: number of nanoseconds since `truncated_seconds`.
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    30
    When this is zero, the sub-second precision is considered unknown.
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    31
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    32
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    33
    def __new__(cls, value):
48446
111098af6356 dirstate-item: add a "second_ambiguous` flag in the mtime tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48445
diff changeset
    34
        truncated_seconds, subsec_nanos, second_ambiguous = value
111098af6356 dirstate-item: add a "second_ambiguous` flag in the mtime tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48445
diff changeset
    35
        value = (truncated_seconds & rangemask, subsec_nanos, second_ambiguous)
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    36
        return super(timestamp, cls).__new__(cls, value)
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    37
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    38
    def __eq__(self, other):
48445
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    39
        raise error.ProgrammingError(
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    40
            'timestamp should never be compared directly'
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    41
        )
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    42
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    43
    def __gt__(self, other):
48445
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    44
        raise error.ProgrammingError(
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    45
            'timestamp should never be compared directly'
8d585aa9becf dirstate: drop comparison primitive on the timestamp class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48443
diff changeset
    46
        )
48273
68bb472aee9c dirstate: ignore sub-second component when either is zero in mtime
Simon Sapin <simon.sapin@octobus.net>
parents: 48271
diff changeset
    47
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    48
48427
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    49
def get_fs_now(vfs):
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    50
    """return a timestamp for "now" in the current vfs
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    51
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    52
    This will raise an exception if no temporary files could be created.
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    53
    """
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    54
    tmpfd, tmpname = vfs.mkstemp()
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    55
    try:
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    56
        return mtime_of(os.fstat(tmpfd))
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    57
    finally:
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    58
        os.close(tmpfd)
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    59
        vfs.unlink(tmpname)
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    60
08b060abd658 dirstate: move "get fs now" in the timestamp utility module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48274
diff changeset
    61
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    62
def zero():
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    63
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    64
    Returns the `timestamp` at the Unix epoch.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    65
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    66
    return tuple.__new__(timestamp, (0, 0))
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    67
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    68
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    69
def mtime_of(stat_result):
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    70
    """
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    71
    Takes an `os.stat_result`-like object and returns a `timestamp` object
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    72
    for its modification time.
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    73
    """
48274
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    74
    try:
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    75
        # TODO: add this attribute to `osutil.stat` objects,
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    76
        # see `mercurial/cext/osutil.c`.
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    77
        #
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    78
        # This attribute is also not available on Python 2.
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    79
        nanos = stat_result.st_mtime_ns
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    80
    except AttributeError:
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    81
        # https://docs.python.org/2/library/os.html#os.stat_float_times
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    82
        # "For compatibility with older Python versions,
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    83
        #  accessing stat_result as a tuple always returns integers."
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    84
        secs = stat_result[stat.ST_MTIME]
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    85
48274
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    86
        subsec_nanos = 0
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    87
    else:
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    88
        billion = int(1e9)
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    89
        secs = nanos // billion
83d0bd45b662 dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents: 48273
diff changeset
    90
        subsec_nanos = nanos % billion
48271
269ff8978086 dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
    91
48446
111098af6356 dirstate-item: add a "second_ambiguous` flag in the mtime tuple
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48445
diff changeset
    92
    return timestamp((secs, subsec_nanos, False))
48443
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    93
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    94
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    95
def reliable_mtime_of(stat_result, present_mtime):
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    96
    """same as `mtime_of`, but return None if the date might be ambiguous
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    97
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    98
    A modification time is reliable if it is older than "present_time" (or
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
    99
    sufficiently in the futur).
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   100
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   101
    Otherwise a concurrent modification might happens with the same mtime.
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   102
    """
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   103
    file_mtime = mtime_of(stat_result)
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   104
    file_second = file_mtime[0]
48451
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   105
    file_ns = file_mtime[1]
48443
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   106
    boundary_second = present_mtime[0]
48451
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   107
    boundary_ns = present_mtime[1]
48443
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   108
    # If the mtime of the ambiguous file is younger (or equal) to the starting
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   109
    # point of the `status` walk, we cannot garantee that another, racy, write
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   110
    # will not happen right after with the same mtime and we cannot cache the
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   111
    # information.
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   112
    #
48451
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   113
    # However if the mtime is far away in the future, this is likely some
48443
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   114
    # mismatch between the current clock and previous file system operation. So
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   115
    # mtime more than one days in the future are considered fine.
48451
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   116
    if boundary_second == file_second:
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   117
        if file_ns and boundary_ns:
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   118
            if file_ns < boundary_ns:
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   119
                return timestamp((file_second, file_ns, True))
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   120
        return None
ca42667c8d26 status: keep second-ambiguous mtimes during fixup
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48446
diff changeset
   121
    elif boundary_second < file_second < (3600 * 24 + boundary_second):
48443
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   122
        return None
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   123
    else:
9ae0353c9f5d status: move the boundary comparison logic within the timestamp module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48427
diff changeset
   124
        return file_mtime