Mercurial > public > mercurial-scm > hg
diff rust/rhg/src/commands/status.rs @ 47674:ff97e793ed36
dirstate-v2: Introduce a docket file
.hg/dirstate now only contains some metadata to point to a separate data file
named .hg/dirstate.{}.d with a random hexadecimal identifier. For now every
update creates a new data file and removes the old one, but later we?ll
(usually) append to an existing file.
Separating into two files allows doing the "write to a temporary file then
atomically rename into destination" dance with only a small docket file,
without always rewriting a lot of data.
Differential Revision: https://phab.mercurial-scm.org/D11088
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 08 Jul 2021 12:18:21 +0200 |
parents | bd88b6bfd8da |
children | 48aec076b8fb |
line wrap: on
line diff
--- a/rust/rhg/src/commands/status.rs Thu Jul 15 17:24:09 2021 +0200 +++ b/rust/rhg/src/commands/status.rs Thu Jul 08 12:18:21 2021 +0200 @@ -10,6 +10,7 @@ use clap::{Arg, SubCommand}; use hg; use hg::dirstate_tree::dirstate_map::DirstateMap; +use hg::dirstate_tree::on_disk; use hg::errors::HgResultExt; use hg::errors::IoResultExt; use hg::matchers::AlwaysMatcher; @@ -165,17 +166,33 @@ }; let repo = invocation.repo?; - let dirstate_data = - repo.hg_vfs().mmap_open("dirstate").io_not_found_as_none()?; - let dirstate_data = match &dirstate_data { - Some(mmap) => &**mmap, - None => b"", - }; + let dirstate_data_mmap; let (mut dmap, parents) = if repo.has_dirstate_v2() { - DirstateMap::new_v2(dirstate_data)? + let parents; + let dirstate_data; + if let Some(docket_data) = + repo.hg_vfs().read("dirstate").io_not_found_as_none()? + { + let docket = on_disk::read_docket(&docket_data)?; + parents = Some(docket.parents()); + dirstate_data_mmap = repo + .hg_vfs() + .mmap_open(docket.data_filename()) + .io_not_found_as_none()?; + dirstate_data = dirstate_data_mmap.as_deref().unwrap_or(b""); + } else { + parents = None; + dirstate_data = b""; + } + let dmap = DirstateMap::new_v2(dirstate_data)?; + (dmap, parents) } else { + dirstate_data_mmap = + repo.hg_vfs().mmap_open("dirstate").io_not_found_as_none()?; + let dirstate_data = dirstate_data_mmap.as_deref().unwrap_or(b""); DirstateMap::new_v1(dirstate_data)? }; + let options = StatusOptions { // TODO should be provided by the dirstate parsing and // hence be stored on dmap. Using a value that assumes we aren't