list_tracked_files.rs
82 lines
| 2.5 KiB
| application/rls-services+xml
|
RustLexer
|
r45918 | // list_tracked_files.rs | ||
// | ||||
// Copyright 2020 Antoine Cezar <antoine.cezar@octobus.net> | ||||
// | ||||
// This software may be used and distributed according to the terms of the | ||||
// GNU General Public License version 2 or any later version. | ||||
|
r48164 | use crate::dirstate::parsers::parse_dirstate_entries; | ||
|
r48474 | use crate::dirstate_tree::on_disk::{for_each_tracked_path, read_docket}; | ||
|
r47172 | use crate::errors::HgError; | ||
|
r46782 | use crate::repo::Repo; | ||
|
r48773 | use crate::revlog::manifest::Manifest; | ||
|
r46107 | use crate::revlog::revlog::RevlogError; | ||
|
r45918 | use crate::utils::hg_path::HgPath; | ||
|
r48165 | use crate::DirstateError; | ||
|
r45918 | use rayon::prelude::*; | ||
/// List files under Mercurial control in the working directory | ||||
/// by reading the dirstate | ||||
|
r46751 | pub struct Dirstate { | ||
|
r46106 | /// The `dirstate` content. | ||
|
r45918 | content: Vec<u8>, | ||
|
r48482 | v2_metadata: Option<Vec<u8>>, | ||
|
r45918 | } | ||
|
r46751 | impl Dirstate { | ||
|
r47169 | pub fn new(repo: &Repo) -> Result<Self, HgError> { | ||
|
r48474 | let mut content = repo.hg_vfs().read("dirstate")?; | ||
|
r48482 | let v2_metadata = if repo.has_dirstate_v2() { | ||
|
r48474 | let docket = read_docket(&content)?; | ||
|
r48482 | let meta = docket.tree_metadata().to_vec(); | ||
|
r48474 | content = repo.hg_vfs().read(docket.data_filename())?; | ||
|
r48482 | Some(meta) | ||
} else { | ||||
None | ||||
}; | ||||
|
r48165 | Ok(Self { | ||
|
r48474 | content, | ||
|
r48482 | v2_metadata, | ||
|
r48165 | }) | ||
|
r46106 | } | ||
|
r48165 | pub fn tracked_files(&self) -> Result<Vec<&HgPath>, DirstateError> { | ||
|
r48164 | let mut files = Vec::new(); | ||
|
r48165 | if !self.content.is_empty() { | ||
|
r48482 | if let Some(meta) = &self.v2_metadata { | ||
for_each_tracked_path(&self.content, meta, |path| { | ||||
files.push(path) | ||||
})? | ||||
|
r48165 | } else { | ||
let _parents = parse_dirstate_entries( | ||||
&self.content, | ||||
|path, entry, _copy_source| { | ||||
|
r48834 | if entry.state().is_tracked() { | ||
|
r48165 | files.push(path) | ||
} | ||||
Ok(()) | ||||
}, | ||||
)?; | ||||
} | ||||
} | ||||
|
r45918 | files.par_sort_unstable(); | ||
Ok(files) | ||||
} | ||||
} | ||||
|
r46107 | |||
/// List files under Mercurial control at a given revision. | ||||
|
r46751 | pub fn list_rev_tracked_files( | ||
|
r46782 | repo: &Repo, | ||
|
r47162 | revset: &str, | ||
|
r47166 | ) -> Result<FilesForRev, RevlogError> { | ||
|
r47162 | let rev = crate::revset::resolve_single(revset, repo)?; | ||
|
r48778 | Ok(FilesForRev(repo.manifest_for_rev(rev)?)) | ||
|
r46107 | } | ||
|
r48771 | pub struct FilesForRev(Manifest); | ||
|
r46107 | |||
|
r46751 | impl FilesForRev { | ||
|
r49165 | pub fn iter(&self) -> impl Iterator<Item = Result<&HgPath, HgError>> { | ||
|
r49166 | self.0.iter().map(|entry| Ok(entry?.path)) | ||
|
r46107 | } | ||
} | ||||