##// END OF EJS Templates
rhg-files: reuse centralized dirstate logic...
Raphaël Gomès -
r50875:95ffa065 default
parent child Browse files
Show More
@@ -599,32 +599,6 b' where'
599 .map(|(slice, _rest)| slice)
599 .map(|(slice, _rest)| slice)
600 }
600 }
601
601
602 pub(crate) fn for_each_tracked_path<'on_disk>(
603 on_disk: &'on_disk [u8],
604 metadata: &[u8],
605 mut f: impl FnMut(&'on_disk HgPath),
606 ) -> Result<(), DirstateV2ParseError> {
607 let (meta, _) = TreeMetadata::from_bytes(metadata).map_err(|e| {
608 DirstateV2ParseError::new(format!("when parsing tree metadata, {}", e))
609 })?;
610 fn recur<'on_disk>(
611 on_disk: &'on_disk [u8],
612 nodes: ChildNodes,
613 f: &mut impl FnMut(&'on_disk HgPath),
614 ) -> Result<(), DirstateV2ParseError> {
615 for node in read_nodes(on_disk, nodes)? {
616 if let Some(entry) = node.entry()? {
617 if entry.tracked() {
618 f(node.full_path(on_disk)?)
619 }
620 }
621 recur(on_disk, node.children, f)?
622 }
623 Ok(())
624 }
625 recur(on_disk, meta.root_nodes, &mut f)
626 }
627
628 /// Returns new data and metadata, together with whether that data should be
602 /// Returns new data and metadata, together with whether that data should be
629 /// appended to the existing data file whose content is at
603 /// appended to the existing data file whose content is at
630 /// `dirstate_map.on_disk` (true), instead of written to a new data file
604 /// `dirstate_map.on_disk` (true), instead of written to a new data file
@@ -5,64 +5,11 b''
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::dirstate::parsers::parse_dirstate_entries;
9 use crate::dirstate_tree::on_disk::{for_each_tracked_path, read_docket};
10 use crate::errors::HgError;
8 use crate::errors::HgError;
11 use crate::repo::Repo;
9 use crate::repo::Repo;
12 use crate::revlog::manifest::Manifest;
10 use crate::revlog::manifest::Manifest;
13 use crate::revlog::RevlogError;
11 use crate::revlog::RevlogError;
14 use crate::utils::hg_path::HgPath;
12 use crate::utils::hg_path::HgPath;
15 use crate::DirstateError;
16 use rayon::prelude::*;
17
18 /// List files under Mercurial control in the working directory
19 /// by reading the dirstate
20 pub struct Dirstate {
21 /// The `dirstate` content.
22 content: Vec<u8>,
23 v2_metadata: Option<Vec<u8>>,
24 }
25
26 impl Dirstate {
27 pub fn new(repo: &Repo) -> Result<Self, HgError> {
28 let mut content = repo.hg_vfs().read("dirstate")?;
29 let v2_metadata = if repo.has_dirstate_v2() {
30 let docket = read_docket(&content)?;
31 let meta = docket.tree_metadata().to_vec();
32 content = repo.hg_vfs().read(docket.data_filename())?;
33 Some(meta)
34 } else {
35 None
36 };
37 Ok(Self {
38 content,
39 v2_metadata,
40 })
41 }
42
43 pub fn tracked_files(&self) -> Result<Vec<&HgPath>, DirstateError> {
44 let mut files = Vec::new();
45 if !self.content.is_empty() {
46 if let Some(meta) = &self.v2_metadata {
47 for_each_tracked_path(&self.content, meta, |path| {
48 files.push(path)
49 })?
50 } else {
51 let _parents = parse_dirstate_entries(
52 &self.content,
53 |path, entry, _copy_source| {
54 if entry.tracked() {
55 files.push(path)
56 }
57 Ok(())
58 },
59 )?;
60 }
61 }
62 files.par_sort_unstable();
63 Ok(files)
64 }
65 }
66
13
67 /// List files under Mercurial control at a given revision.
14 /// List files under Mercurial control at a given revision.
68 pub fn list_rev_tracked_files(
15 pub fn list_rev_tracked_files(
@@ -7,5 +7,4 b' mod debugdata;'
7 mod list_tracked_files;
7 mod list_tracked_files;
8 pub use cat::{cat, CatOutput};
8 pub use cat::{cat, CatOutput};
9 pub use debugdata::{debug_data, DebugDataKind};
9 pub use debugdata::{debug_data, DebugDataKind};
10 pub use list_tracked_files::Dirstate;
11 pub use list_tracked_files::{list_rev_tracked_files, FilesForRev};
10 pub use list_tracked_files::{list_rev_tracked_files, FilesForRev};
@@ -4,9 +4,10 b' use crate::utils::path_utils::Relativize'
4 use clap::Arg;
4 use clap::Arg;
5 use hg::errors::HgError;
5 use hg::errors::HgError;
6 use hg::operations::list_rev_tracked_files;
6 use hg::operations::list_rev_tracked_files;
7 use hg::operations::Dirstate;
8 use hg::repo::Repo;
7 use hg::repo::Repo;
8 use hg::utils::filter_map_results;
9 use hg::utils::hg_path::HgPath;
9 use hg::utils::hg_path::HgPath;
10 use rayon::prelude::*;
10
11
11 pub const HELP_TEXT: &str = "
12 pub const HELP_TEXT: &str = "
12 List tracked files.
13 List tracked files.
@@ -70,8 +71,16 b' pub fn run(invocation: &crate::CliInvoca'
70 "rhg files is not supported in narrow clones",
71 "rhg files is not supported in narrow clones",
71 ));
72 ));
72 }
73 }
73 let dirstate = Dirstate::new(repo)?;
74 let dirstate = repo.dirstate_map()?;
74 let files = dirstate.tracked_files()?;
75 let files_res: Result<Vec<_>, _> =
76 filter_map_results(dirstate.iter(), |(path, entry)| {
77 Ok(if entry.tracked() { Some(path) } else { None })
78 })
79 .collect();
80
81 let mut files = files_res?;
82 files.par_sort_unstable();
83
75 display_files(invocation.ui, repo, files.into_iter().map(Ok))
84 display_files(invocation.ui, repo, files.into_iter().map(Ok))
76 }
85 }
77 }
86 }
General Comments 0
You need to be logged in to leave comments. Login now