comparison rust/rhg/src/commands/files.rs @ 45537:2f8227a12592

rhg: add `--revision` argument to `rhg files` Add the option to list the tracked files of a revision given its number or full node id. Benched on a clone of moz-central where tip is 1671467:81deaa1a68ebb28db0490954034ab38ab269409d files -r 81deaa1a68ebb28db0490954034ab38ab269409d > out.txt hg 0m1.633s rhg 0m0.157s files -r 81deaa1a68ebb28db0490954034ab38ab269409d > /dev/null hg 0m0.415s rhg 0m0.143s Differential Revision: https://phab.mercurial-scm.org/D9015
author Antoine Cezar <antoine.cezar@octobus.net>
date Wed, 09 Sep 2020 14:53:15 +0200
parents 72b7d58d6e35
children 2ad2745e0be9
comparison
equal deleted inserted replaced
45536:639f33f22faf 45537:2f8227a12592
5 use hg::operations::FindRoot; 5 use hg::operations::FindRoot;
6 use hg::operations::{ 6 use hg::operations::{
7 ListDirstateTrackedFiles, ListDirstateTrackedFilesError, 7 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
8 ListDirstateTrackedFilesErrorKind, 8 ListDirstateTrackedFilesErrorKind,
9 }; 9 };
10 use hg::operations::{
11 ListRevTrackedFiles, ListRevTrackedFilesError,
12 ListRevTrackedFilesErrorKind,
13 };
10 use hg::utils::files::{get_bytes_from_path, relativize_path}; 14 use hg::utils::files::{get_bytes_from_path, relativize_path};
11 use hg::utils::hg_path::HgPathBuf; 15 use hg::utils::hg_path::{HgPath, HgPathBuf};
16 use std::path::PathBuf;
12 17
13 pub const HELP_TEXT: &str = " 18 pub const HELP_TEXT: &str = "
14 List tracked files. 19 List tracked files.
15 20
16 Returns 0 on success. 21 Returns 0 on success.
17 "; 22 ";
18 23
19 pub struct FilesCommand {} 24 pub struct FilesCommand<'a> {
20 25 rev: Option<&'a str>,
21 impl FilesCommand {
22 pub fn new() -> Self {
23 FilesCommand {}
24 }
25 } 26 }
26 27
27 impl Command for FilesCommand { 28 impl<'a> FilesCommand<'a> {
28 fn run(&self, ui: &Ui) -> Result<(), CommandError> { 29 pub fn new(rev: Option<&'a str>) -> Self {
29 let root = FindRoot::new().run()?; 30 FilesCommand { rev }
30 let mut operation = ListDirstateTrackedFiles::new(&root) 31 }
31 .map_err(map_dirstate_error)?;
32 let files = operation.run().map_err(map_dirstate_error)?;
33 32
33 fn display_files(
34 &self,
35 ui: &Ui,
36 root: &PathBuf,
37 files: impl IntoIterator<Item = &'a HgPath>,
38 ) -> Result<(), CommandError> {
34 let cwd = std::env::current_dir() 39 let cwd = std::env::current_dir()
35 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?; 40 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
36 let rooted_cwd = cwd 41 let rooted_cwd = cwd
37 .strip_prefix(&root) 42 .strip_prefix(&root)
38 .expect("cwd was already checked within the repository"); 43 .expect("cwd was already checked within the repository");
47 stdout.flush()?; 52 stdout.flush()?;
48 Ok(()) 53 Ok(())
49 } 54 }
50 } 55 }
51 56
52 /// Convert operation errors to command errors 57 impl<'a> Command for FilesCommand<'a> {
58 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
59 let root = FindRoot::new().run()?;
60 if let Some(rev) = self.rev {
61 let mut operation = ListRevTrackedFiles::new(&root, rev)
62 .map_err(|e| map_rev_error(rev, e))?;
63 let files = operation.run().map_err(|e| map_rev_error(rev, e))?;
64 self.display_files(ui, &root, files)
65 } else {
66 let mut operation = ListDirstateTrackedFiles::new(&root)
67 .map_err(map_dirstate_error)?;
68 let files = operation.run().map_err(map_dirstate_error)?;
69 self.display_files(ui, &root, files)
70 }
71 }
72 }
73
74 /// Convert `ListRevTrackedFilesErrorKind` to `CommandError`
75 fn map_rev_error(rev: &str, err: ListRevTrackedFilesError) -> CommandError {
76 CommandError {
77 kind: match err.kind {
78 ListRevTrackedFilesErrorKind::IoError(err) => {
79 CommandErrorKind::Abort(Some(
80 utf8_to_local(&format!("abort: {}\n", err)).into(),
81 ))
82 }
83 ListRevTrackedFilesErrorKind::InvalidRevision => {
84 CommandErrorKind::Abort(Some(
85 utf8_to_local(&format!(
86 "abort: invalid revision identifier{}\n",
87 rev
88 ))
89 .into(),
90 ))
91 }
92 ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version) => {
93 CommandErrorKind::Abort(Some(
94 utf8_to_local(&format!(
95 "abort: unsupported revlog version {}\n",
96 version
97 ))
98 .into(),
99 ))
100 }
101 ListRevTrackedFilesErrorKind::CorruptedRevlog => {
102 CommandErrorKind::Abort(Some(
103 "abort: corrupted revlog\n".into(),
104 ))
105 }
106 ListRevTrackedFilesErrorKind::UnknowRevlogDataFormat(format) => {
107 CommandErrorKind::Abort(Some(
108 utf8_to_local(&format!(
109 "abort: unknow revlog dataformat {:?}\n",
110 format
111 ))
112 .into(),
113 ))
114 }
115 },
116 }
117 }
118
119 /// Convert `ListDirstateTrackedFilesError` to `CommandError`
53 fn map_dirstate_error(err: ListDirstateTrackedFilesError) -> CommandError { 120 fn map_dirstate_error(err: ListDirstateTrackedFilesError) -> CommandError {
54 CommandError { 121 CommandError {
55 kind: match err.kind { 122 kind: match err.kind {
56 ListDirstateTrackedFilesErrorKind::IoError(err) => { 123 ListDirstateTrackedFilesErrorKind::IoError(err) => {
57 CommandErrorKind::Abort(Some( 124 CommandErrorKind::Abort(Some(