mercurial/helptext/internals/dirstate-v2.txt
changeset 48219 308d9c245337
parent 48195 4d5a13253d34
child 48231 0524c1359bfc
equal deleted inserted replaced
48218:15dedc0c5c35 48219:308d9c245337
   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.