Show More
@@ -599,32 +599,6 b' where' | |||
|
599 | 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 | 602 | /// Returns new data and metadata, together with whether that data should be |
|
629 | 603 | /// appended to the existing data file whose content is at |
|
630 | 604 | /// `dirstate_map.on_disk` (true), instead of written to a new data file |
@@ -5,64 +5,11 b'' | |||
|
5 | 5 | // This software may be used and distributed according to the terms of the |
|
6 | 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 | 8 | use crate::errors::HgError; |
|
11 | 9 | use crate::repo::Repo; |
|
12 | 10 | use crate::revlog::manifest::Manifest; |
|
13 | 11 | use crate::revlog::RevlogError; |
|
14 | 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 | 14 | /// List files under Mercurial control at a given revision. |
|
68 | 15 | pub fn list_rev_tracked_files( |
@@ -7,5 +7,4 b' mod debugdata;' | |||
|
7 | 7 | mod list_tracked_files; |
|
8 | 8 | pub use cat::{cat, CatOutput}; |
|
9 | 9 | pub use debugdata::{debug_data, DebugDataKind}; |
|
10 | pub use list_tracked_files::Dirstate; | |
|
11 | 10 | pub use list_tracked_files::{list_rev_tracked_files, FilesForRev}; |
@@ -4,9 +4,10 b' use crate::utils::path_utils::Relativize' | |||
|
4 | 4 | use clap::Arg; |
|
5 | 5 | use hg::errors::HgError; |
|
6 | 6 | use hg::operations::list_rev_tracked_files; |
|
7 | use hg::operations::Dirstate; | |
|
8 | 7 | use hg::repo::Repo; |
|
8 | use hg::utils::filter_map_results; | |
|
9 | 9 | use hg::utils::hg_path::HgPath; |
|
10 | use rayon::prelude::*; | |
|
10 | 11 | |
|
11 | 12 | pub const HELP_TEXT: &str = " |
|
12 | 13 | List tracked files. |
@@ -70,8 +71,16 b' pub fn run(invocation: &crate::CliInvoca' | |||
|
70 | 71 | "rhg files is not supported in narrow clones", |
|
71 | 72 | )); |
|
72 | 73 | } |
|
73 |
let dirstate = |
|
|
74 | let files = dirstate.tracked_files()?; | |
|
74 | let dirstate = repo.dirstate_map()?; | |
|
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 | 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