##// END OF EJS Templates
rhg: Make `files` work on repo-relative paths when possible...
rhg: Make `files` work on repo-relative paths when possible When the current directory is outside of the repository we need to turn everything into absolute filesystem paths in order to compute correct relative paths. This was previously done unconditionally, but is not necessary when the current directory is inside the repository. With this change `rhg files > /dev/null` at the root of a mozilla-central snapshot goes from ~150 ms to ~70 ms. My repository is located at a somewhat long path though (93 bytes). The effect may not be as pronounced at a shorter path. Differential Revision: https://phab.mercurial-scm.org/D10200

File last commit:

r47687:b5e8bf10 default
r47687:b5e8bf10 default
Show More
files.rs
91 lines | 2.7 KiB | application/rls-services+xml | RustLexer
Simon Sapin
rust: remove `FooError` structs with only `kind: FooErrorKind` enum field...
r47163 use crate::error::CommandError;
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923 use crate::ui::Ui;
Simon Sapin
rhg: Move subcommand CLI arguments definitions to respective modules...
r47251 use clap::Arg;
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 use hg::operations::list_rev_tracked_files;
use hg::operations::Dirstate;
Simon Sapin
rust: introduce Repo and Vfs types for filesystem abstraction...
r46782 use hg::repo::Repo;
Simon Sapin
rhg: Don’t make repository path absolute too early...
r47474 use hg::utils::current_dir;
Raphaël Gomès
rhg: make output of `files` relative to the current directory and the root...
r46007 use hg::utils::files::{get_bytes_from_path, relativize_path};
Antoine Cezar
rhg: add `--revision` argument to `rhg files`...
r46108 use hg::utils::hg_path::{HgPath, HgPathBuf};
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923
pub const HELP_TEXT: &str = "
List tracked files.
Returns 0 on success.
";
Simon Sapin
rhg: Move subcommand CLI arguments definitions to respective modules...
r47251 pub fn args() -> clap::App<'static, 'static> {
clap::SubCommand::with_name("files")
.arg(
Arg::with_name("rev")
.help("search the repository as it is in REV")
.short("-r")
.long("--revision")
.value_name("REV")
.takes_value(true),
)
.about(HELP_TEXT)
}
Simon Sapin
rhg: Group values passed to every sub-command into a struct...
r47334 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
Simon Sapin
rhg: Fall back to Python if ui.relative-paths is configured...
r47473 let relative = invocation.config.get(b"ui", b"relative-paths");
if relative.is_some() {
return Err(CommandError::unsupported(
"non-default ui.relative-paths",
));
}
Simon Sapin
rhg: Group values passed to every sub-command into a struct...
r47334 let rev = invocation.subcommand_args.value_of("rev");
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 let repo = invocation.repo?;
Simon Sapin
rhg: replace command structs with functions...
r47250 if let Some(rev) = rev {
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 let files = list_rev_tracked_files(repo, rev).map_err(|e| (e, rev))?;
display_files(invocation.ui, repo, files.iter())
Simon Sapin
rhg: replace command structs with functions...
r47250 } else {
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 let distate = Dirstate::new(repo)?;
Simon Sapin
rhg: replace command structs with functions...
r47250 let files = distate.tracked_files()?;
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 display_files(invocation.ui, repo, files)
Antoine Cezar
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand...
r45923 }
}
Antoine Cezar
hg-core: simplify `list_tracked_files` operation...
r46106
Simon Sapin
rhg: replace command structs with functions...
r47250 fn display_files<'a>(
ui: &Ui,
repo: &Repo,
files: impl IntoIterator<Item = &'a HgPath>,
) -> Result<(), CommandError> {
let mut stdout = ui.stdout_buffer();
Simon Sapin
rhg: Make `files` work on repo-relative paths when possible...
r47687 let cwd = current_dir()?;
let working_directory = repo.working_directory_path();
let working_directory = cwd.join(working_directory); // Make it absolute
Simon Sapin
rhg: Exit with an error code if `files` finds nothing...
r47479 let mut any = false;
Simon Sapin
rhg: Make `files` work on repo-relative paths when possible...
r47687 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&working_directory) {
// The current directory is inside the repo, so we can work with
// relative paths
let cwd = HgPathBuf::from(get_bytes_from_path(cwd_relative_to_repo));
for file in files {
any = true;
stdout.write_all(relativize_path(&file, &cwd).as_ref())?;
stdout.write_all(b"\n")?;
}
} else {
let working_directory =
HgPathBuf::from(get_bytes_from_path(working_directory));
let cwd = HgPathBuf::from(get_bytes_from_path(cwd));
for file in files {
any = true;
// Absolute path in the filesystem
let file = working_directory.join(file);
stdout.write_all(relativize_path(&file, &cwd).as_ref())?;
stdout.write_all(b"\n")?;
}
Antoine Cezar
rhg: add `--revision` argument to `rhg files`...
r46108 }
Simon Sapin
rhg: Make `files` work on repo-relative paths when possible...
r47687
Simon Sapin
rhg: replace command structs with functions...
r47250 stdout.flush()?;
Simon Sapin
rhg: Exit with an error code if `files` finds nothing...
r47479 if any {
Ok(())
} else {
Err(CommandError::Unsuccessful)
}
Antoine Cezar
rhg: add `--revision` argument to `rhg files`...
r46108 }