370 that represent files tracked in the working directory. |
370 that represent files tracked in the working directory. |
371 (For example, `hg rm` makes a file untracked.) |
371 (For example, `hg rm` makes a file untracked.) |
372 This counter is used to implement `has_tracked_dir`. |
372 This counter is used to implement `has_tracked_dir`. |
373 |
373 |
374 * Offset 30: |
374 * Offset 30: |
375 Some boolean values packed as bits of a single byte. |
375 A single `flags` byte that packs some boolean values as bits. |
376 Starting from least-significant, bit masks are:: |
376 Starting from least-significant, bit masks are:: |
377 |
377 |
378 WDIR_TRACKED = 1 << 0 |
378 WDIR_TRACKED = 1 << 0 |
379 P1_TRACKED = 1 << 1 |
379 P1_TRACKED = 1 << 1 |
380 P2_INFO = 1 << 2 |
380 P2_INFO = 1 << 2 |
381 HAS_MODE_AND_SIZE = 1 << 3 |
381 HAS_MODE_AND_SIZE = 1 << 3 |
382 HAS_MTIME = 1 << 4 |
382 HAS_MTIME = 1 << 4 |
383 MODE_EXEC_PERM = 1 << 5 |
383 MODE_EXEC_PERM = 1 << 5 |
384 MODE_IS_SYMLINK = 1 << 7 |
384 MODE_IS_SYMLINK = 1 << 6 |
385 |
385 |
386 |
386 The meaning of each bit is described below. |
387 Other bits are unset. The meaning of these bits are: |
387 Other bits are unset. |
388 |
388 |
389 `WDIR_TRACKED` |
389 * Offset 31: |
390 Set if the working directory contains a tracked file at this node’s path. |
390 A `size` field described below, as a 32-bit integer. |
391 This is typically set and unset by `hg add` and `hg rm`. |
391 Unlike in dirstate-v1, negative values are not used. |
392 |
392 |
393 `P1_TRACKED` |
393 * Offset 35: |
394 set if the working directory’s first parent changeset |
394 The seconds component of an `mtime` field described below, |
395 (whose node identifier is found in tree metadata) |
395 as a 32-bit integer. |
396 contains a tracked file at this node’s path. |
396 Unlike in dirstate-v1, negative values are not used. |
397 This is a cache to reduce manifest lookups. |
397 |
398 |
398 * Offset 39: |
399 `P2_INFO` |
399 The nanoseconds component of an `mtime` field described below, |
400 Set if the file has been involved in some merge operation. |
400 as a 32-bit integer. |
401 Either because it was actually merged, |
|
402 or because the version in the second parent p2 version was ahead, |
|
403 or because some rename moved it there. |
|
404 In either case `hg status` will want it displayed as modified. |
|
405 |
|
406 Files that would be mentioned at all in the `dirstate-v1` file format |
|
407 have a node with at least one of the above three bits set in `dirstate-v2`. |
|
408 Let’s call these files "tracked anywhere", |
|
409 and "untracked" the nodes with all three of these bits unset. |
|
410 Untracked nodes are typically for directories: |
|
411 they hold child nodes and form the tree structure. |
|
412 Additional untracked nodes may also exist. |
|
413 Although implementations should strive to clean up nodes |
|
414 that are entirely unused, other untracked nodes may also exist. |
|
415 For example, a future version of Mercurial might in some cases |
|
416 add nodes for untracked files or/and ignored files in the working directory |
|
417 in order to optimize `hg status` |
|
418 by enabling it to skip `readdir` in more cases. |
|
419 |
|
420 When a node is for a file tracked anywhere: |
|
421 - If `HAS_MODE_AND_SIZE` is set, the file is expected |
|
422 to be a symbolic link or a normal file based on `MODE_IS_SYMLINK`. |
|
423 - If `HAS_MODE_AND_SIZE` is set, the file’s owner is expected |
|
424 to have execute permission or not based on `MODE_EXEC_PERM`. |
|
425 - If `HAS_MODE_AND_SIZE` is unset, |
|
426 the expected type of file and permission are unknown. |
|
427 The rest of the node data is three fields: |
|
428 |
|
429 * Offset 31: |
|
430 4 unused bytes, set to zero |
|
431 |
|
432 * Offset 35: |
|
433 If `HAS_MODE_AND_SIZE` is unset, four zero bytes. |
|
434 Otherwise, a 32-bit integer for expected size of the file |
|
435 truncated to its 31 least-significant bits. |
|
436 Unlike in dirstate-v1, negative values are not used. |
|
437 |
|
438 * Offset 39: |
|
439 If `HAS_MTIME` is unset, four zero bytes. |
|
440 Otherwise, a 32-bit integer for expected modified time of the file |
|
441 (as in `stat_result.st_mtime`), |
|
442 truncated to its 31 least-significant bits. |
|
443 Unlike in dirstate-v1, negative values are not used. |
|
444 |
|
445 If an untracked node `HAS_MTIME` *unset*, this space is unused: |
|
446 |
|
447 * Offset 31: |
|
448 12 unused bytes, set to zero |
|
449 |
|
450 If an untracked node `HAS_MTIME` *set*, |
|
451 what follows is the modification time of a directory |
|
452 represented similarly to the C `timespec` struct: |
|
453 |
|
454 * Offset 31: |
|
455 4 unused bytes, set to zero |
|
456 |
|
457 * Offset 35: |
|
458 The number of seconds elapsed since the Unix epoch, |
|
459 truncated to its lower 31 bits, |
|
460 as a 32-bit integer. |
|
461 |
|
462 * Offset 39: |
|
463 The sub-second number of nanoseconds elapsed since the Unix epoch, |
|
464 as 32-bit integer. |
|
465 Always greater than or equal to zero, and strictly less than a billion. |
|
466 |
|
467 The presence of a directory modification time means that at some point, |
|
468 this path in the working directory was observed: |
|
469 |
|
470 - To be a directory |
|
471 - With the given modification time |
|
472 - That time was already strictly in the past when observed, |
|
473 meaning that later changes cannot happen in the same clock tick |
|
474 and must cause a different modification time |
|
475 (unless the system clock jumps back and we get unlucky, |
|
476 which is not impossible but deemed unlikely enough). |
|
477 - All direct children of this directory |
|
478 (as returned by `std::fs::read_dir`) |
|
479 either have a corresponding dirstate node, |
|
480 or are ignored by ignore patterns whose hash is in tree metadata. |
|
481 |
|
482 This means that if `std::fs::symlink_metadata` later reports |
|
483 the same modification time |
|
484 and ignored patterns haven’t changed, |
|
485 a run of status that is not listing ignored files |
|
486 can skip calling `std::fs::read_dir` again for this directory, |
|
487 and iterate child dirstate nodes instead. |
|
488 |
|
489 |
401 |
490 * (Offset 43: end of this node) |
402 * (Offset 43: end of this node) |
|
403 |
|
404 The meaning of the boolean values packed in `flags` is: |
|
405 |
|
406 `WDIR_TRACKED` |
|
407 Set if the working directory contains a tracked file at this node’s path. |
|
408 This is typically set and unset by `hg add` and `hg rm`. |
|
409 |
|
410 `P1_TRACKED` |
|
411 Set if the working directory’s first parent changeset |
|
412 (whose node identifier is found in tree metadata) |
|
413 contains a tracked file at this node’s path. |
|
414 This is a cache to reduce manifest lookups. |
|
415 |
|
416 `P2_INFO` |
|
417 Set if the file has been involved in some merge operation. |
|
418 Either because it was actually merged, |
|
419 or because the version in the second parent p2 version was ahead, |
|
420 or because some rename moved it there. |
|
421 In either case `hg status` will want it displayed as modified. |
|
422 |
|
423 Files that would be mentioned at all in the `dirstate-v1` file format |
|
424 have a node with at least one of the above three bits set in `dirstate-v2`. |
|
425 Let’s call these files "tracked anywhere", |
|
426 and "untracked" the nodes with all three of these bits unset. |
|
427 Untracked nodes are typically for directories: |
|
428 they hold child nodes and form the tree structure. |
|
429 Additional untracked nodes may also exist. |
|
430 Although implementations should strive to clean up nodes |
|
431 that are entirely unused, other untracked nodes may also exist. |
|
432 For example, a future version of Mercurial might in some cases |
|
433 add nodes for untracked files or/and ignored files in the working directory |
|
434 in order to optimize `hg status` |
|
435 by enabling it to skip `readdir` in more cases. |
|
436 |
|
437 `HAS_MODE_AND_SIZE` |
|
438 Must be unset for untracked nodes. |
|
439 For files tracked anywhere, if this is set: |
|
440 - The `size` field is the expected file size, |
|
441 in bytes truncated its lower to 31 bits, |
|
442 for the file to be clean. |
|
443 - The expected execute permission for the file’s owner |
|
444 is given by `MODE_EXEC_PERM` |
|
445 - The expected file type is given by `MODE_IS_SIMLINK`: |
|
446 a symbolic link if set, or a normal file if unset. |
|
447 If this is unset the expected size, permission, and file type are unknown. |
|
448 The `size` field is unused (set to zero). |
|
449 |
|
450 `HAS_MTIME` |
|
451 If unset, the `mtime` field is unused (set to zero). |
|
452 If set, it contains a timestamp represented as |
|
453 - the number of seconds since the Unix epoch, |
|
454 truncated to its lower 31 bits. |
|
455 - and the number of nanoseconds since `mtime.seconds`, |
|
456 always stritctly less than one billion. |
|
457 This may be zero if more precision is not available. |
|
458 (This can happen because of limitations in any of Mercurial, Python, |
|
459 libc, the operating system, …) |
|
460 |
|
461 If set for a file tracked anywhere, |
|
462 `mtime` is the expected modification time for the file to be clean. |
|
463 |
|
464 If set for an untracked node, at some point, |
|
465 this path in the working directory was observed: |
|
466 |
|
467 - To be a directory |
|
468 - With the modification time given in `mtime` |
|
469 - That time was already strictly in the past when observed, |
|
470 meaning that later changes cannot happen in the same clock tick |
|
471 and must cause a different modification time |
|
472 (unless the system clock jumps back and we get unlucky, |
|
473 which is not impossible but deemed unlikely enough). |
|
474 - All direct children of this directory |
|
475 (as returned by `std::fs::read_dir`) |
|
476 either have a corresponding dirstate node, |
|
477 or are ignored by ignore patterns whose hash is in tree metadata. |
|
478 |
|
479 This means that if `std::fs::symlink_metadata` later reports |
|
480 the same modification time |
|
481 and ignored patterns haven’t changed, |
|
482 a run of status that is not listing ignored files |
|
483 can skip calling `std::fs::read_dir` again for this directory, |
|
484 and iterate child dirstate nodes instead. |
|
485 |
|
486 `MODE_EXEC_PERM` |
|
487 Must be unset if `HAS_MODE_AND_SIZE` is unset. |
|
488 If `HAS_MODE_AND_SIZE` is set, |
|
489 this indicates whether the file’s own is expected |
|
490 to have execute permission. |
|
491 |
|
492 `MODE_IS_SYMLINK` |
|
493 Must be unset if `HAS_MODE_AND_SIZE` is unset. |
|
494 If `HAS_MODE_AND_SIZE` is set, |
|
495 this indicates whether the file is expected to be a symlink |
|
496 as opposed to a normal file. |