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 = |
|
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