--- a/rust/hg-core/src/dirstate_tree/on_disk.rs Wed May 26 11:53:37 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/on_disk.rs Tue May 25 09:20:30 2021 +0200
@@ -167,6 +167,16 @@
}
}
+fn read_header(on_disk: &[u8]) -> Result<&Header, DirstateV2ParseError> {
+ let (header, _) =
+ Header::from_bytes(on_disk).map_err(|_| DirstateV2ParseError)?;
+ if header.marker == *V2_FORMAT_MARKER {
+ Ok(header)
+ } else {
+ Err(DirstateV2ParseError)
+ }
+}
+
pub(super) fn read<'on_disk>(
on_disk: &'on_disk [u8],
) -> Result<
@@ -176,27 +186,19 @@
if on_disk.is_empty() {
return Ok((DirstateMap::empty(on_disk), None));
}
- let (header, _) =
- Header::from_bytes(on_disk).map_err(|_| DirstateV2ParseError)?;
- let Header {
- marker,
- parents,
- root,
- nodes_with_entry_count,
- nodes_with_copy_source_count,
- } = header;
- if marker != V2_FORMAT_MARKER {
- return Err(DirstateV2ParseError);
- }
+ let header = read_header(on_disk)?;
let dirstate_map = DirstateMap {
on_disk,
root: dirstate_map::ChildNodes::OnDisk(read_slice::<Node>(
- on_disk, *root,
+ on_disk,
+ header.root,
)?),
- nodes_with_entry_count: nodes_with_entry_count.get(),
- nodes_with_copy_source_count: nodes_with_copy_source_count.get(),
+ nodes_with_entry_count: header.nodes_with_entry_count.get(),
+ nodes_with_copy_source_count: header
+ .nodes_with_copy_source_count
+ .get(),
};
- let parents = Some(parents.clone());
+ let parents = Some(header.parents.clone());
Ok((dirstate_map, parents))
}
@@ -414,6 +416,35 @@
.ok_or_else(|| DirstateV2ParseError)
}
+pub(crate) fn parse_dirstate_parents(
+ on_disk: &[u8],
+) -> Result<&DirstateParents, HgError> {
+ Ok(&read_header(on_disk)?.parents)
+}
+
+pub(crate) fn for_each_tracked_path<'on_disk>(
+ on_disk: &'on_disk [u8],
+ mut f: impl FnMut(&'on_disk HgPath),
+) -> Result<(), DirstateV2ParseError> {
+ let header = read_header(on_disk)?;
+ fn recur<'on_disk>(
+ on_disk: &'on_disk [u8],
+ nodes: Slice,
+ f: &mut impl FnMut(&'on_disk HgPath),
+ ) -> Result<(), DirstateV2ParseError> {
+ for node in read_slice::<Node>(on_disk, nodes)? {
+ if let Some(state) = node.state()? {
+ if state.is_tracked() {
+ f(node.full_path(on_disk)?)
+ }
+ }
+ recur(on_disk, node.children, f)?
+ }
+ Ok(())
+ }
+ recur(on_disk, header.root, &mut f)
+}
+
pub(super) fn write(
dirstate_map: &mut DirstateMap,
parents: DirstateParents,