mercurial/merge.py
changeset 52055 b332ae615714
parent 52054 f5742367a279
child 52056 8b7123c8947b
equal deleted inserted replaced
52054:f5742367a279 52055:b332ae615714
  2212     When we reach the current code, the "on disk" part of the update operation
  2212     When we reach the current code, the "on disk" part of the update operation
  2213     is finished. We still assume that no other process raced that "on disk"
  2213     is finished. We still assume that no other process raced that "on disk"
  2214     part, but we want to at least prevent later file changes to alter the
  2214     part, but we want to at least prevent later file changes to alter the
  2215     contents of the file right after the update operation so quickly that the
  2215     contents of the file right after the update operation so quickly that the
  2216     same mtime is recorded for the operation.
  2216     same mtime is recorded for the operation.
  2217     To prevent such ambiguities from happenning, we will only keep the
  2217 
  2218     "file data" for files with mtimes that are strictly in the past,
  2218     To prevent such ambiguities from happenning, we will do (up to) two things:
  2219     i.e. whose mtime is strictly lower than the current time.
  2219         - wait until the filesystem clock has ticked
       
  2220         - only keep the "file data" for files with mtimes that are strictly in
       
  2221           the past, i.e. whose mtime is strictly lower than the current time.
       
  2222 
       
  2223     We only wait for the system clock to tick if using dirstate-v2, since v1
       
  2224     only has second-level granularity and waiting for a whole second is
       
  2225     too much of a penalty in the general case.
       
  2226 
       
  2227     Although we're assuming that people running dirstate-v2 on Linux
       
  2228     don't have a second-granularity FS (with the exclusion of NFS), users
       
  2229     can be surprising, and at some point in the future, dirstate-v2 will become
       
  2230     the default. To that end, we limit the wait time to 100ms and fall back
       
  2231     to the filtering method in case of a timeout.
       
  2232 
       
  2233     +------------+------+--------------+
       
  2234     |   version  | wait | filter level |
       
  2235     +------------+------+--------------+
       
  2236     |     V1     | No   | Second       |
       
  2237     |     V2     | Yes  | Nanosecond   |
       
  2238     | V2-slow-fs | No   | Second       |
       
  2239     +------------+------+--------------+
  2220 
  2240 
  2221     This protects us from race conditions from operations that could run right
  2241     This protects us from race conditions from operations that could run right
  2222     after this one, especially other Mercurial operations that could be waiting
  2242     after this one, especially other Mercurial operations that could be waiting
  2223     for the wlock to touch files contents and the dirstate.
  2243     for the wlock to touch files contents and the dirstate.
  2224 
  2244 
  2225     In an ideal world, we could only get reliable information in `getfiledata`
  2245     In an ideal world, we could only get reliable information in `getfiledata`
  2226     (from `getbatch`), however the current approach has been a successful
  2246     (from `getbatch`), however this filtering approach has been a successful
  2227     compromise for many years.
  2247     compromise for many years. A patch series of the linux kernel might change
       
  2248     this in 6.12³.
  2228 
  2249 
  2229     At the time this comment is written, not using any "cache" file data at all
  2250     At the time this comment is written, not using any "cache" file data at all
  2230     here would not be viable, as it would result is a very large amount of work
  2251     here would not be viable, as it would result is a very large amount of work
  2231     (equivalent to the previous `hg update` during the next status after an
  2252     (equivalent to the previous `hg update` during the next status after an
  2232     update).
  2253     update).
  2237 
  2258 
  2238     [2] using nano-second precision can greatly help here because it makes the
  2259     [2] using nano-second precision can greatly help here because it makes the
  2239     "different write with same mtime" issue virtually vanish. However,
  2260     "different write with same mtime" issue virtually vanish. However,
  2240     dirstate v1 cannot store such precision and a bunch of python-runtime,
  2261     dirstate v1 cannot store such precision and a bunch of python-runtime,
  2241     operating-system and filesystem parts do not provide us with such
  2262     operating-system and filesystem parts do not provide us with such
  2242     precision, so we have to operate as if it wasn't available."""
  2263     precision, so we have to operate as if it wasn't available.
       
  2264 
       
  2265     [3] https://lore.kernel.org/all/20241002-mgtime-v10-8-d1c4717f5284@kernel.org
       
  2266     """
  2243     ambiguous_mtime: FileData = {}
  2267     ambiguous_mtime: FileData = {}
  2244     now = timestamp.get_fs_now(repo.vfs)
  2268     dirstate_v2 = repo.dirstate._use_dirstate_v2
       
  2269     fs_now_result = None
       
  2270     fast_enough_fs = True
       
  2271     if dirstate_v2:
       
  2272         fstype = util.getfstype(repo.vfs.base)
       
  2273         # Exclude NFS right off the bat
       
  2274         fast_enough_fs = fstype != b'nfs'
       
  2275         if fstype is not None and fast_enough_fs:
       
  2276             fs_now_result = timestamp.wait_until_fs_tick(repo.vfs)
       
  2277 
       
  2278     if fs_now_result is None:
       
  2279         try:
       
  2280             now = timestamp.get_fs_now(repo.vfs)
       
  2281             fs_now_result = (now, False)
       
  2282         except OSError:
       
  2283             pass
       
  2284 
  2245     if fs_now_result is None:
  2285     if fs_now_result is None:
  2246         # we can't write to the FS, so we won't actually update
  2286         # we can't write to the FS, so we won't actually update
  2247         # the dirstate content anyway, no need to put cache
  2287         # the dirstate content anyway, no need to put cache
  2248         # information.
  2288         # information.
  2249         return None
  2289         return None
  2250     else:
  2290     else:
  2251         now_sec = now[0]
       
  2252         now, timed_out = fs_now_result
  2291         now, timed_out = fs_now_result
  2253         if timed_out:
  2292         if timed_out:
  2254             fast_enough_fs = False
  2293             fast_enough_fs = False
  2255         for f, m in file_data.items():
  2294         for f, m in file_data.items():
  2256             if m is not None and m[2][0] >= now_sec:
  2295             if m is not None:
  2257                 ambiguous_mtime[f] = (m[0], m[1], None)
  2296                 reliable = timestamp.make_mtime_reliable(m[2], now)
       
  2297                 if reliable is None or (
       
  2298                     reliable[2] and (not dirstate_v2 or not fast_enough_fs)
       
  2299                 ):
       
  2300                     # Either it's not reliable, or it's second ambiguous
       
  2301                     # and we're in dirstate-v1 or in a slow fs, so discard
       
  2302                     # the mtime.
       
  2303                     ambiguous_mtime[f] = (m[0], m[1], None)
       
  2304                 elif reliable[2]:
       
  2305                     # We need to remember that this time is "second ambiguous"
       
  2306                     # otherwise the next status might miss a subsecond change
       
  2307                     # if its "stat" doesn't provide nanoseconds.
       
  2308                     #
       
  2309                     # TODO make osutil.c understand nanoseconds when possible
       
  2310                     # (see timestamp.py for the same note)
       
  2311                     ambiguous_mtime[f] = (m[0], m[1], reliable)
  2258         for f, m in ambiguous_mtime.items():
  2312         for f, m in ambiguous_mtime.items():
  2259             file_data[f] = m
  2313             file_data[f] = m
  2260     return file_data
  2314     return file_data
  2261 
  2315 
  2262 
  2316