Changeset View
Changeset View
Standalone View
Standalone View
mercurial/helptext/internals/dirstate-v2.txt
Show First 20 Lines • Show All 366 Lines • ▼ Show 20 Line(s) | |||||
* Offset 26: | * Offset 26: | ||||
Number as a 32-bit integer of descendant nodes in this subtree, | Number as a 32-bit integer of descendant nodes in this subtree, | ||||
not including this node itself, | not including this node itself, | ||||
that represent files tracked in the working directory. | that represent files tracked in the working directory. | ||||
(For example, `hg rm` makes a file untracked.) | (For example, `hg rm` makes a file untracked.) | ||||
This counter is used to implement `has_tracked_dir`. | This counter is used to implement `has_tracked_dir`. | ||||
* Offset 30: | * Offset 30: | ||||
Some boolean values packed as bits of a single byte. | A single `flags` byte that packs some boolean values as bits. | ||||
Starting from least-significant, bit masks are:: | Starting from least-significant, bit masks are:: | ||||
WDIR_TRACKED = 1 << 0 | WDIR_TRACKED = 1 << 0 | ||||
P1_TRACKED = 1 << 1 | P1_TRACKED = 1 << 1 | ||||
P2_INFO = 1 << 2 | P2_INFO = 1 << 2 | ||||
HAS_MODE_AND_SIZE = 1 << 3 | HAS_MODE_AND_SIZE = 1 << 3 | ||||
HAS_MTIME = 1 << 4 | HAS_MTIME = 1 << 4 | ||||
MODE_EXEC_PERM = 1 << 5 | MODE_EXEC_PERM = 1 << 5 | ||||
MODE_IS_SYMLINK = 1 << 7 | MODE_IS_SYMLINK = 1 << 6 | ||||
The meaning of each bit is described below. | |||||
Other bits are unset. | |||||
Other bits are unset. The meaning of these bits are: | * Offset 31: | ||||
A `size` field described below, as a 32-bit integer. | |||||
Unlike in dirstate-v1, negative values are not used. | |||||
* Offset 35: | |||||
The seconds component of an `mtime` field described below, | |||||
as a 32-bit integer. | |||||
Unlike in dirstate-v1, negative values are not used. | |||||
* Offset 39: | |||||
The nanoseconds component of an `mtime` field described below, | |||||
as a 32-bit integer. | |||||
* (Offset 43: end of this node) | |||||
The meaning of the boolean values packed in `flags` is: | |||||
`WDIR_TRACKED` | `WDIR_TRACKED` | ||||
Set if the working directory contains a tracked file at this node’s path. | Set if the working directory contains a tracked file at this node’s path. | ||||
This is typically set and unset by `hg add` and `hg rm`. | This is typically set and unset by `hg add` and `hg rm`. | ||||
`P1_TRACKED` | `P1_TRACKED` | ||||
set if the working directory’s first parent changeset | Set if the working directory’s first parent changeset | ||||
(whose node identifier is found in tree metadata) | (whose node identifier is found in tree metadata) | ||||
contains a tracked file at this node’s path. | contains a tracked file at this node’s path. | ||||
This is a cache to reduce manifest lookups. | This is a cache to reduce manifest lookups. | ||||
`P2_INFO` | `P2_INFO` | ||||
Set if the file has been involved in some merge operation. | Set if the file has been involved in some merge operation. | ||||
Either because it was actually merged, | Either because it was actually merged, | ||||
or because the version in the second parent p2 version was ahead, | or because the version in the second parent p2 version was ahead, | ||||
or because some rename moved it there. | or because some rename moved it there. | ||||
In either case `hg status` will want it displayed as modified. | In either case `hg status` will want it displayed as modified. | ||||
Files that would be mentioned at all in the `dirstate-v1` file format | Files that would be mentioned at all in the `dirstate-v1` file format | ||||
have a node with at least one of the above three bits set in `dirstate-v2`. | have a node with at least one of the above three bits set in `dirstate-v2`. | ||||
Let’s call these files "tracked anywhere", | Let’s call these files "tracked anywhere", | ||||
and "untracked" the nodes with all three of these bits unset. | and "untracked" the nodes with all three of these bits unset. | ||||
Untracked nodes are typically for directories: | Untracked nodes are typically for directories: | ||||
they hold child nodes and form the tree structure. | they hold child nodes and form the tree structure. | ||||
Additional untracked nodes may also exist. | Additional untracked nodes may also exist. | ||||
Although implementations should strive to clean up nodes | Although implementations should strive to clean up nodes | ||||
that are entirely unused, other untracked nodes may also exist. | that are entirely unused, other untracked nodes may also exist. | ||||
For example, a future version of Mercurial might in some cases | For example, a future version of Mercurial might in some cases | ||||
add nodes for untracked files or/and ignored files in the working directory | add nodes for untracked files or/and ignored files in the working directory | ||||
in order to optimize `hg status` | in order to optimize `hg status` | ||||
by enabling it to skip `readdir` in more cases. | by enabling it to skip `readdir` in more cases. | ||||
When a node is for a file tracked anywhere: | `HAS_MODE_AND_SIZE` | ||||
- If `HAS_MODE_AND_SIZE` is set, the file is expected | Must be unset for untracked nodes. | ||||
to be a symbolic link or a normal file based on `MODE_IS_SYMLINK`. | For files tracked anywhere, if this is set: | ||||
- If `HAS_MODE_AND_SIZE` is set, the file’s owner is expected | - The `size` field is the expected file size, | ||||
to have execute permission or not based on `MODE_EXEC_PERM`. | in bytes truncated its lower to 31 bits, | ||||
- If `HAS_MODE_AND_SIZE` is unset, | for the file to be clean. | ||||
the expected type of file and permission are unknown. | - The expected execute permission for the file’s owner | ||||
The rest of the node data is three fields: | is given by `MODE_EXEC_PERM` | ||||
- The expected file type is given by `MODE_IS_SIMLINK`: | |||||
* Offset 31: | a symbolic link if set, or a normal file if unset. | ||||
4 unused bytes, set to zero | If this is unset the expected size, permission, and file type are unknown. | ||||
The `size` field is unused (set to zero). | |||||
* Offset 35: | |||||
If `HAS_MODE_AND_SIZE` is unset, four zero bytes. | `HAS_MTIME` | ||||
Otherwise, a 32-bit integer for expected size of the file | If unset, the `mtime` field is unused (set to zero). | ||||
truncated to its 31 least-significant bits. | If set, it contains a timestamp represented as | ||||
Unlike in dirstate-v1, negative values are not used. | - the number of seconds since the Unix epoch, | ||||
truncated to its lower 31 bits. | |||||
* Offset 39: | - and the number of nanoseconds since `mtime.seconds`, | ||||
If `HAS_MTIME` is unset, four zero bytes. | always stritctly less than one billion. | ||||
Otherwise, a 32-bit integer for expected modified time of the file | This may be zero if more precision is not available. | ||||
(as in `stat_result.st_mtime`), | (This can happen because of limitations in any of Mercurial, Python, | ||||
truncated to its 31 least-significant bits. | libc, the operating system, …) | ||||
Unlike in dirstate-v1, negative values are not used. | |||||
If an untracked node `HAS_MTIME` *unset*, this space is unused: | |||||
* Offset 31: | |||||
12 unused bytes, set to zero | |||||
If an untracked node `HAS_MTIME` *set*, | |||||
what follows is the modification time of a directory | |||||
represented similarly to the C `timespec` struct: | |||||
* Offset 31: | If set for a file tracked anywhere, | ||||
4 unused bytes, set to zero | `mtime` is the expected modification time for the file to be clean. | ||||
* Offset 35: | |||||
The number of seconds elapsed since the Unix epoch, | |||||
truncated to its lower 31 bits, | |||||
as a 32-bit integer. | |||||
* Offset 39: | If set for an untracked node, at some point, | ||||
The sub-second number of nanoseconds elapsed since the Unix epoch, | |||||
as 32-bit integer. | |||||
Always greater than or equal to zero, and strictly less than a billion. | |||||
The presence of a directory modification time means that at some point, | |||||
this path in the working directory was observed: | this path in the working directory was observed: | ||||
- To be a directory | - To be a directory | ||||
- With the given modification time | - With the modification time given in `mtime` | ||||
- That time was already strictly in the past when observed, | - That time was already strictly in the past when observed, | ||||
meaning that later changes cannot happen in the same clock tick | meaning that later changes cannot happen in the same clock tick | ||||
and must cause a different modification time | and must cause a different modification time | ||||
(unless the system clock jumps back and we get unlucky, | (unless the system clock jumps back and we get unlucky, | ||||
which is not impossible but deemed unlikely enough). | which is not impossible but deemed unlikely enough). | ||||
- All direct children of this directory | - All direct children of this directory | ||||
(as returned by `std::fs::read_dir`) | (as returned by `std::fs::read_dir`) | ||||
either have a corresponding dirstate node, | either have a corresponding dirstate node, | ||||
or are ignored by ignore patterns whose hash is in tree metadata. | or are ignored by ignore patterns whose hash is in tree metadata. | ||||
This means that if `std::fs::symlink_metadata` later reports | This means that if `std::fs::symlink_metadata` later reports | ||||
the same modification time | the same modification time | ||||
and ignored patterns haven’t changed, | and ignored patterns haven’t changed, | ||||
a run of status that is not listing ignored files | a run of status that is not listing ignored files | ||||
can skip calling `std::fs::read_dir` again for this directory, | can skip calling `std::fs::read_dir` again for this directory, | ||||
and iterate child dirstate nodes instead. | and iterate child dirstate nodes instead. | ||||
`MODE_EXEC_PERM` | |||||
* (Offset 43: end of this node) | Must be unset if `HAS_MODE_AND_SIZE` is unset. | ||||
If `HAS_MODE_AND_SIZE` is set, | |||||
this indicates whether the file’s own is expected | |||||
to have execute permission. | |||||
`MODE_IS_SYMLINK` | |||||
Must be unset if `HAS_MODE_AND_SIZE` is unset. | |||||
If `HAS_MODE_AND_SIZE` is set, | |||||
this indicates whether the file is expected to be a symlink | |||||
as opposed to a normal file. |