diff --git a/rust/hg-core/src/dirstate_tree/on_disk.rs b/rust/hg-core/src/dirstate_tree/on_disk.rs --- a/rust/hg-core/src/dirstate_tree/on_disk.rs +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs @@ -61,7 +61,7 @@ pub struct Docket<'on_disk> { header: &'on_disk DocketHeader, - uuid: &'on_disk [u8], + pub uuid: &'on_disk [u8], } /// Fields are documented in the *Tree metadata in the docket file* diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs --- a/rust/hg-core/src/repo.rs +++ b/rust/hg-core/src/repo.rs @@ -28,6 +28,7 @@ requirements: HashSet, config: Config, dirstate_parents: LazyCell, + dirstate_data_file_uuid: LazyCell>, HgError>, dirstate_map: LazyCell, changelog: LazyCell, manifestlog: LazyCell, @@ -203,6 +204,9 @@ dot_hg, config: repo_config, dirstate_parents: LazyCell::new(Self::read_dirstate_parents), + dirstate_data_file_uuid: LazyCell::new( + Self::read_dirstate_data_file_uuid, + ), dirstate_map: LazyCell::new(Self::new_dirstate_map), changelog: LazyCell::new(Changelog::open), manifestlog: LazyCell::new(Manifestlog::open), @@ -278,9 +282,16 @@ fn read_dirstate_parents(&self) -> Result { let dirstate = self.dirstate_file_contents()?; let parents = if dirstate.is_empty() { + if self.has_dirstate_v2() { + self.dirstate_data_file_uuid.set(None); + } DirstateParents::NULL } else if self.has_dirstate_v2() { - crate::dirstate_tree::on_disk::read_docket(&dirstate)?.parents() + let docket = + crate::dirstate_tree::on_disk::read_docket(&dirstate)?; + self.dirstate_data_file_uuid + .set(Some(docket.uuid.to_owned())); + docket.parents() } else { crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? .clone() @@ -289,16 +300,40 @@ Ok(parents) } + fn read_dirstate_data_file_uuid( + &self, + ) -> Result>, HgError> { + assert!( + self.has_dirstate_v2(), + "accessing dirstate data file ID without dirstate-v2" + ); + let dirstate = self.dirstate_file_contents()?; + if dirstate.is_empty() { + self.dirstate_parents.set(DirstateParents::NULL); + Ok(None) + } else { + let docket = + crate::dirstate_tree::on_disk::read_docket(&dirstate)?; + self.dirstate_parents.set(docket.parents()); + Ok(Some(docket.uuid.to_owned())) + } + } + fn new_dirstate_map(&self) -> Result { let dirstate_file_contents = self.dirstate_file_contents()?; if dirstate_file_contents.is_empty() { self.dirstate_parents.set(DirstateParents::NULL); + if self.has_dirstate_v2() { + self.dirstate_data_file_uuid.set(None); + } Ok(OwningDirstateMap::new_empty(Vec::new())) } else if self.has_dirstate_v2() { let docket = crate::dirstate_tree::on_disk::read_docket( &dirstate_file_contents, )?; self.dirstate_parents.set(docket.parents()); + self.dirstate_data_file_uuid + .set(Some(docket.uuid.to_owned())); let data_size = docket.data_size(); let metadata = docket.tree_metadata(); let mut map = if let Some(data_mmap) = self