172 mtime_s, |
172 mtime_s, |
173 mtime_ns, |
173 mtime_ns, |
174 ) |
174 ) |
175 |
175 |
176 |
176 |
177 def pack_dirstate(map, copy_map, now): |
177 def pack_dirstate(map, copy_map): |
178 """ |
178 """ |
179 Pack `map` and `copy_map` into the dirstate v2 binary format and return |
179 Pack `map` and `copy_map` into the dirstate v2 binary format and return |
180 the bytearray. |
180 the bytearray. |
181 `now` is a timestamp of the current filesystem time used to detect race |
|
182 conditions in writing the dirstate to disk, see inline comment. |
|
183 |
181 |
184 The on-disk format expects a tree-like structure where the leaves are |
182 The on-disk format expects a tree-like structure where the leaves are |
185 written first (and sorted per-directory), going up levels until the root |
183 written first (and sorted per-directory), going up levels until the root |
186 node and writing that one to the docket. See more details on the on-disk |
184 node and writing that one to the docket. See more details on the on-disk |
187 format in `mercurial/helptext/internals/dirstate-v2`. |
185 format in `mercurial/helptext/internals/dirstate-v2`. |
282 stack = [] |
280 stack = [] |
283 current_node = Node(b"", None) |
281 current_node = Node(b"", None) |
284 stack.append(current_node) |
282 stack.append(current_node) |
285 |
283 |
286 for index, (path, entry) in enumerate(sorted_map, 1): |
284 for index, (path, entry) in enumerate(sorted_map, 1): |
287 if entry.need_delay(now): |
|
288 # The file was last modified "simultaneously" with the current |
|
289 # write to dirstate (i.e. within the same second for file- |
|
290 # systems with a granularity of 1 sec). This commonly happens |
|
291 # for at least a couple of files on 'update'. |
|
292 # The user could change the file without changing its size |
|
293 # within the same second. Invalidate the file's mtime in |
|
294 # dirstate, forcing future 'status' calls to compare the |
|
295 # contents of the file if the size is the same. This prevents |
|
296 # mistakenly treating such files as clean. |
|
297 entry.set_possibly_dirty() |
|
298 nodes_with_entry_count += 1 |
285 nodes_with_entry_count += 1 |
299 if path in copy_map: |
286 if path in copy_map: |
300 nodes_with_copy_source_count += 1 |
287 nodes_with_copy_source_count += 1 |
301 current_folder = get_folder(path) |
288 current_folder = get_folder(path) |
302 current_node = move_to_correct_node_in_tree( |
289 current_node = move_to_correct_node_in_tree( |