Mercurial > public > mercurial-scm > hg
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 |
---|---|
46434
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; |
45364
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; |
46501
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
3 use clap::Arg; |
46436
252d1bdba33d
rhg: replace `map_*_error` functions with `From` impls
Simon Sapin <simon.sapin@octobus.net>
parents:
46434
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:
46434
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:
46135
diff
changeset
|
6 use hg::repo::Repo; |
46740
97ac588b6d9e
rhg: Don?t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46739
diff
changeset
|
7 use hg::utils::current_dir; |
45436
1b3197047f5c
rhg: make output of `files` relative to the current directory and the root
Rapha?l Gom?s <rgomes@octobus.net>
parents:
45364
diff
changeset
|
8 use hg::utils::files::{get_bytes_from_path, relativize_path}; |
45537
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45535
diff
changeset
|
9 use hg::utils::hg_path::{HgPath, HgPathBuf}; |
45364
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 |
46501
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
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:
46500
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:
46500
diff
changeset
|
19 .arg( |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
20 Arg::with_name("rev") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
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:
46500
diff
changeset
|
22 .short("-r") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
23 .long("--revision") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
24 .value_name("REV") |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
25 .takes_value(true), |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
26 ) |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
27 .about(HELP_TEXT) |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
28 } |
1ecaf09d9964
rhg: Move subcommand CLI arguments definitions to respective modules
Simon Sapin <simon.sapin@octobus.net>
parents:
46500
diff
changeset
|
29 |
46592
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
30 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> { |
46739
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46593
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:
46593
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:
46593
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:
46593
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:
46593
diff
changeset
|
35 )); |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46593
diff
changeset
|
36 } |
c184b490da37
rhg: Fall back to Python if ui.relative-paths is configured
Simon Sapin <simon.sapin@octobus.net>
parents:
46593
diff
changeset
|
37 |
46592
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
38 let rev = invocation.subcommand_args.value_of("rev"); |
45364
5fe25f8ef5d9
rhg: add a `Files` `Command` to prepare the `rhg files` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
39 |
46593
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46592
diff
changeset
|
40 let repo = invocation.repo?; |
46500
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
41 if let Some(rev) = rev { |
46593
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46592
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:
46592
diff
changeset
|
43 display_files(invocation.ui, repo, files.iter()) |
46500
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
44 } else { |
46593
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46592
diff
changeset
|
45 let distate = Dirstate::new(repo)?; |
46500
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
46 let files = distate.tracked_files()?; |
46593
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46592
diff
changeset
|
47 display_files(invocation.ui, repo, files) |
45364
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 } |
45535
72b7d58d6e35
hg-core: simplify `list_tracked_files` operation
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45438
diff
changeset
|
50 |
46500
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
51 fn display_files<'a>( |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
52 ui: &Ui, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
53 repo: &Repo, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
54 files: impl IntoIterator<Item = &'a HgPath>, |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
55 ) -> Result<(), CommandError> { |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
56 let mut stdout = ui.stdout_buffer(); |
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
57 |
46925
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
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:
46745
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:
46745
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:
46745
diff
changeset
|
61 |
46745
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
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:
46745
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:
46745
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:
46745
diff
changeset
|
65 // relative paths |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
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:
46745
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:
46745
diff
changeset
|
68 any = true; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
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:
46745
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:
46745
diff
changeset
|
71 } |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
diff
changeset
|
72 } else { |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
diff
changeset
|
73 let working_directory = |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
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:
46745
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:
46745
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:
46745
diff
changeset
|
77 any = true; |
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
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:
46745
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:
46745
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:
46745
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:
46745
diff
changeset
|
82 } |
45537
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45535
diff
changeset
|
83 } |
46925
b5e8bf10436e
rhg: Make `files` work on repo-relative paths when possible
Simon Sapin <simon.sapin@octobus.net>
parents:
46745
diff
changeset
|
84 |
46500
184e46550dc8
rhg: replace command structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
85 stdout.flush()?; |
46745
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
86 if any { |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
87 Ok(()) |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
88 } else { |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
89 Err(CommandError::Unsuccessful) |
63bfcddddac1
rhg: Exit with an error code if `files` finds nothing
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
90 } |
45537
2f8227a12592
rhg: add `--revision` argument to `rhg files`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45535
diff
changeset
|
91 } |