Mercurial > public > mercurial-scm > hg-stable
annotate rust/rhg/src/commands/files.rs @ 46925:b5e8bf10436e
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
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Sat, 13 Mar 2021 09:50:34 +0100 |
parents | 63bfcddddac1 |
children | 9ecf802b06e0 |
rev | line source |
---|---|
46502
3e2d539d0d1a
rust: remove `FooError` structs with only `kind: FooErrorKind` enum field
Simon Sapin <simon.sapin@octobus.net>
parents:
46167
diff
changeset
|
1 use crate::error::CommandError; |
45384
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
2 use crate::ui::Ui; |
46553
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
3 use clap::Arg; |
46504
252d1bdba33d
rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents:
46502
diff
changeset
|
4 use hg::operations::list_rev_tracked_files; |
252d1bdba33d
rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents:
46502
diff
changeset
|
5 use hg::operations::Dirstate; |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
46136
diff
changeset
|
6 use hg::repo::Repo; |
46753
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46752
diff
changeset
|
7 use hg::utils::current_dir; |
45447
1b3197047f5c
rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents:
45384
diff
changeset
|
8 use hg::utils::files::{get_bytes_from_path, relativize_path}; |
45543
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45541
diff
changeset
|
9 use hg::utils::hg_path::{HgPath, HgPathBuf}; |
45384
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
10 |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
11 pub const HELP_TEXT: &str = " |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
12 List tracked files. |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
13 |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
14 Returns 0 on success. |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
15 "; |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
16 |
46553
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
17 pub fn args() -> clap::App<'static, 'static> { |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
18 clap::SubCommand::with_name("files") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
19 .arg( |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
20 Arg::with_name("rev") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
21 .help("search the repository as it is in REV") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
22 .short("-r") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
23 .long("--revision") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
24 .value_name("REV") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
25 .takes_value(true), |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
26 ) |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
27 .about(HELP_TEXT) |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
28 } |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46552
diff
changeset
|
29 |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46555
diff
changeset
|
30 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> { |
46752
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
31 let relative = invocation.config.get(b"ui", b"relative-paths"); |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
32 if relative.is_some() { |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
33 return Err(CommandError::unsupported( |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
34 "non-default ui.relative-paths", |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
35 )); |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
36 } |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
37 |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46555
diff
changeset
|
38 let rev = invocation.subcommand_args.value_of("rev"); |
45384
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
39 |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
40 let repo = invocation.repo?; |
46552
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
41 if let Some(rev) = rev { |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
42 let files = list_rev_tracked_files(repo, rev).map_err(|e| (e, rev))?; |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
43 display_files(invocation.ui, repo, files.iter()) |
46552
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
44 } else { |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
45 let distate = Dirstate::new(repo)?; |
46552
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
46 let files = distate.tracked_files()?; |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
47 display_files(invocation.ui, repo, files) |
45384
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
48 } |
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
49 } |
45541
72b7d58d6e35
hg-core: simplify `list_tracked_files` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45449
diff
changeset
|
50 |
46552
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
51 fn display_files<'a>( |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
52 ui: &Ui, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
53 repo: &Repo, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
54 files: impl IntoIterator<Item = &'a HgPath>, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
55 ) -> Result<(), CommandError> { |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
56 let mut stdout = ui.stdout_buffer(); |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
57 |
46925
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
58 let cwd = current_dir()?; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
59 let working_directory = repo.working_directory_path(); |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
60 let working_directory = cwd.join(working_directory); // Make it absolute |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
61 |
46758
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
62 let mut any = false; |
46925
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
63 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&working_directory) { |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
64 // The current directory is inside the repo, so we can work with |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
65 // relative paths |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
66 let cwd = HgPathBuf::from(get_bytes_from_path(cwd_relative_to_repo)); |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
67 for file in files { |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
68 any = true; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
69 stdout.write_all(relativize_path(&file, &cwd).as_ref())?; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
70 stdout.write_all(b"\n")?; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
71 } |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
72 } else { |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
73 let working_directory = |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
74 HgPathBuf::from(get_bytes_from_path(working_directory)); |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
75 let cwd = HgPathBuf::from(get_bytes_from_path(cwd)); |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
76 for file in files { |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
77 any = true; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
78 // Absolute path in the filesystem |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
79 let file = working_directory.join(file); |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
80 stdout.write_all(relativize_path(&file, &cwd).as_ref())?; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
81 stdout.write_all(b"\n")?; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
82 } |
45543
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45541
diff
changeset
|
83 } |
46925
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46758
diff
changeset
|
84 |
46552
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46543
diff
changeset
|
85 stdout.flush()?; |
46758
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
86 if any { |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
87 Ok(()) |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
88 } else { |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
89 Err(CommandError::Unsuccessful) |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46753
diff
changeset
|
90 } |
45543
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45541
diff
changeset
|
91 } |