##// END OF EJS Templates
rust: replace most "operation" structs with functions...
Simon Sapin -
r46751:dca9cb99 default
parent child Browse files
Show More
@@ -9,7 +9,7 b' use std::convert::From;'
9 9 use std::path::{Path, PathBuf};
10 10
11 11 use crate::revlog::changelog::Changelog;
12 use crate::revlog::manifest::{Manifest, ManifestEntry};
12 use crate::revlog::manifest::Manifest;
13 13 use crate::revlog::path_encode::path_encode;
14 14 use crate::revlog::revlog::Revlog;
15 15 use crate::revlog::revlog::RevlogError;
@@ -70,97 +70,60 b' impl From<RevlogError> for CatRevError {'
70 70 }
71 71
72 72 /// List files under Mercurial control at a given revision.
73 pub struct CatRev<'a> {
74 root: &'a Path,
75 /// The revision to cat the files from.
76 rev: &'a str,
77 /// The files to output.
78 files: &'a [HgPathBuf],
79 /// The changelog file
80 changelog: Changelog,
81 /// The manifest file
82 manifest: Manifest,
83 /// The manifest entry corresponding to the revision.
84 ///
85 /// Used to hold the owner of the returned references.
86 manifest_entry: Option<ManifestEntry>,
87 }
73 ///
74 /// * `root`: Repository root
75 /// * `rev`: The revision to cat the files from.
76 /// * `files`: The files to output.
77 pub fn cat(
78 root: &Path,
79 rev: &str,
80 files: &[HgPathBuf],
81 ) -> Result<Vec<u8>, CatRevError> {
82 let changelog = Changelog::open(&root)?;
83 let manifest = Manifest::open(&root)?;
84
85 let changelog_entry = match rev.parse::<Revision>() {
86 Ok(rev) => changelog.get_rev(rev)?,
87 _ => {
88 let changelog_node = NodePrefix::from_hex(&rev)
89 .map_err(|_| CatRevErrorKind::InvalidRevision)?;
90 changelog.get_node(changelog_node.borrow())?
91 }
92 };
93 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
94 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
95
96 let manifest_entry = manifest.get_node((&manifest_node).into())?;
97 let mut bytes = vec![];
88 98
89 impl<'a> CatRev<'a> {
90 pub fn new(
91 root: &'a Path,
92 rev: &'a str,
93 files: &'a [HgPathBuf],
94 ) -> Result<Self, CatRevError> {
95 let changelog = Changelog::open(&root)?;
96 let manifest = Manifest::open(&root)?;
97 let manifest_entry = None;
99 for (manifest_file, node_bytes) in manifest_entry.files_with_nodes() {
100 for cat_file in files.iter() {
101 if cat_file.as_bytes() == manifest_file.as_bytes() {
102 let index_path = store_path(root, manifest_file, b".i");
103 let data_path = store_path(root, manifest_file, b".d");
98 104
99 Ok(Self {
100 root,
101 rev,
102 files,
103 changelog,
104 manifest,
105 manifest_entry,
106 })
105 let file_log = Revlog::open(&index_path, Some(&data_path))?;
106 let file_node = Node::from_hex(node_bytes)
107 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
108 let file_rev = file_log.get_node_rev((&file_node).into())?;
109 let data = file_log.get_rev_data(file_rev)?;
110 if data.starts_with(&METADATA_DELIMITER) {
111 let end_delimiter_position = data
112 [METADATA_DELIMITER.len()..]
113 .windows(METADATA_DELIMITER.len())
114 .position(|bytes| bytes == METADATA_DELIMITER);
115 if let Some(position) = end_delimiter_position {
116 let offset = METADATA_DELIMITER.len() * 2;
117 bytes.extend(data[position + offset..].iter());
118 }
119 } else {
120 bytes.extend(data);
121 }
122 }
123 }
107 124 }
108 125
109 pub fn run(&mut self) -> Result<Vec<u8>, CatRevError> {
110 let changelog_entry = match self.rev.parse::<Revision>() {
111 Ok(rev) => self.changelog.get_rev(rev)?,
112 _ => {
113 let changelog_node = NodePrefix::from_hex(&self.rev)
114 .map_err(|_| CatRevErrorKind::InvalidRevision)?;
115 self.changelog.get_node(changelog_node.borrow())?
116 }
117 };
118 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
119 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
120
121 self.manifest_entry =
122 Some(self.manifest.get_node((&manifest_node).into())?);
123 if let Some(ref manifest_entry) = self.manifest_entry {
124 let mut bytes = vec![];
125
126 for (manifest_file, node_bytes) in
127 manifest_entry.files_with_nodes()
128 {
129 for cat_file in self.files.iter() {
130 if cat_file.as_bytes() == manifest_file.as_bytes() {
131 let index_path =
132 store_path(self.root, manifest_file, b".i");
133 let data_path =
134 store_path(self.root, manifest_file, b".d");
135
136 let file_log =
137 Revlog::open(&index_path, Some(&data_path))?;
138 let file_node = Node::from_hex(node_bytes)
139 .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
140 let file_rev =
141 file_log.get_node_rev((&file_node).into())?;
142 let data = file_log.get_rev_data(file_rev)?;
143 if data.starts_with(&METADATA_DELIMITER) {
144 let end_delimiter_position = data
145 [METADATA_DELIMITER.len()..]
146 .windows(METADATA_DELIMITER.len())
147 .position(|bytes| bytes == METADATA_DELIMITER);
148 if let Some(position) = end_delimiter_position {
149 let offset = METADATA_DELIMITER.len() * 2;
150 bytes.extend(data[position + offset..].iter());
151 }
152 } else {
153 bytes.extend(data);
154 }
155 }
156 }
157 }
158
159 Ok(bytes)
160 } else {
161 unreachable!("manifest_entry should have been stored");
162 }
163 }
126 Ok(bytes)
164 127 }
165 128
166 129 fn store_path(root: &Path, hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
@@ -5,7 +5,8 b''
5 5 // This software may be used and distributed according to the terms of the
6 6 // GNU General Public License version 2 or any later version.
7 7
8 use super::find_root;
8 use std::path::Path;
9
9 10 use crate::revlog::revlog::{Revlog, RevlogError};
10 11 use crate::revlog::NodePrefix;
11 12 use crate::revlog::Revision;
@@ -20,7 +21,6 b' pub enum DebugDataKind {'
20 21 /// Kind of error encountered by DebugData
21 22 #[derive(Debug)]
22 23 pub enum DebugDataErrorKind {
23 FindRootError(find_root::FindRootError),
24 24 /// Error when reading a `revlog` file.
25 25 IoError(std::io::Error),
26 26 /// The revision has not been found.
@@ -48,13 +48,6 b' impl From<DebugDataErrorKind> for DebugD'
48 48 }
49 49 }
50 50
51 impl From<find_root::FindRootError> for DebugDataError {
52 fn from(err: find_root::FindRootError) -> Self {
53 let kind = DebugDataErrorKind::FindRootError(err);
54 DebugDataError { kind }
55 }
56 }
57
58 51 impl From<std::io::Error> for DebugDataError {
59 52 fn from(err: std::io::Error) -> Self {
60 53 let kind = DebugDataErrorKind::IoError(err);
@@ -85,36 +78,26 b' impl From<RevlogError> for DebugDataErro'
85 78 }
86 79
87 80 /// Dump the contents data of a revision.
88 pub struct DebugData<'a> {
89 /// Revision or hash of the revision.
90 rev: &'a str,
91 /// Kind of data to debug.
81 pub fn debug_data(
82 root: &Path,
83 rev: &str,
92 84 kind: DebugDataKind,
93 }
94
95 impl<'a> DebugData<'a> {
96 pub fn new(rev: &'a str, kind: DebugDataKind) -> Self {
97 DebugData { rev, kind }
98 }
85 ) -> Result<Vec<u8>, DebugDataError> {
86 let index_file = match kind {
87 DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"),
88 DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"),
89 };
90 let revlog = Revlog::open(&index_file, None)?;
99 91
100 pub fn run(&mut self) -> Result<Vec<u8>, DebugDataError> {
101 let root = find_root::FindRoot::new().run()?;
102 let index_file = match self.kind {
103 DebugDataKind::Changelog => root.join(".hg/store/00changelog.i"),
104 DebugDataKind::Manifest => root.join(".hg/store/00manifest.i"),
105 };
106 let revlog = Revlog::open(&index_file, None)?;
92 let data = match rev.parse::<Revision>() {
93 Ok(rev) => revlog.get_rev_data(rev)?,
94 _ => {
95 let node = NodePrefix::from_hex(&rev)
96 .map_err(|_| DebugDataErrorKind::InvalidRevision)?;
97 let rev = revlog.get_node_rev(node.borrow())?;
98 revlog.get_rev_data(rev)?
99 }
100 };
107 101
108 let data = match self.rev.parse::<Revision>() {
109 Ok(rev) => revlog.get_rev_data(rev)?,
110 _ => {
111 let node = NodePrefix::from_hex(&self.rev)
112 .map_err(|_| DebugDataErrorKind::InvalidRevision)?;
113 let rev = revlog.get_node_rev(node.borrow())?;
114 revlog.get_rev_data(rev)?
115 }
116 };
117
118 Ok(data)
119 }
102 Ok(data)
120 103 }
@@ -28,46 +28,29 b' impl fmt::Display for FindRootError {'
28 28 }
29 29
30 30 /// Find the root of the repository
31 /// by searching for a .hg directory in the current directory and its
31 /// by searching for a .hg directory in the process’ current directory and its
32 32 /// ancestors
33 pub struct FindRoot<'a> {
34 current_dir: Option<&'a Path>,
33 pub fn find_root() -> Result<PathBuf, FindRootError> {
34 let current_dir = std::env::current_dir().map_err(|e| FindRootError {
35 kind: FindRootErrorKind::GetCurrentDirError(e),
36 })?;
37 Ok(find_root_from_path(&current_dir)?.into())
35 38 }
36 39
37 impl<'a> FindRoot<'a> {
38 pub fn new() -> Self {
39 Self { current_dir: None }
40 /// Find the root of the repository
41 /// by searching for a .hg directory in the given directory and its ancestors
42 pub fn find_root_from_path(start: &Path) -> Result<&Path, FindRootError> {
43 if start.join(".hg").exists() {
44 return Ok(start);
40 45 }
41
42 pub fn new_from_path(current_dir: &'a Path) -> Self {
43 Self {
44 current_dir: Some(current_dir),
46 for ancestor in start.ancestors() {
47 if ancestor.join(".hg").exists() {
48 return Ok(ancestor);
45 49 }
46 50 }
47
48 pub fn run(&self) -> Result<PathBuf, FindRootError> {
49 let current_dir = match self.current_dir {
50 None => std::env::current_dir().or_else(|e| {
51 Err(FindRootError {
52 kind: FindRootErrorKind::GetCurrentDirError(e),
53 })
54 })?,
55 Some(path) => path.into(),
56 };
57
58 if current_dir.join(".hg").exists() {
59 return Ok(current_dir);
60 }
61 let ancestors = current_dir.ancestors();
62 for parent in ancestors {
63 if parent.join(".hg").exists() {
64 return Ok(parent.into());
65 }
66 }
67 Err(FindRootError {
68 kind: FindRootErrorKind::RootNotFound(current_dir.to_path_buf()),
69 })
70 }
51 Err(FindRootError {
52 kind: FindRootErrorKind::RootNotFound(start.into()),
53 })
71 54 }
72 55
73 56 #[cfg(test)]
@@ -81,7 +64,7 b' mod tests {'
81 64 let tmp_dir = tempfile::tempdir().unwrap();
82 65 let path = tmp_dir.path();
83 66
84 let err = FindRoot::new_from_path(&path).run().unwrap_err();
67 let err = find_root_from_path(&path).unwrap_err();
85 68
86 69 // TODO do something better
87 70 assert!(match err {
@@ -98,7 +81,7 b' mod tests {'
98 81 let root = tmp_dir.path();
99 82 fs::create_dir_all(root.join(".hg")).unwrap();
100 83
101 let result = FindRoot::new_from_path(&root).run().unwrap();
84 let result = find_root_from_path(&root).unwrap();
102 85
103 86 assert_eq!(result, root)
104 87 }
@@ -109,10 +92,8 b' mod tests {'
109 92 let root = tmp_dir.path();
110 93 fs::create_dir_all(root.join(".hg")).unwrap();
111 94
112 let result =
113 FindRoot::new_from_path(&root.join("some/nested/directory"))
114 .run()
115 .unwrap();
95 let directory = root.join("some/nested/directory");
96 let result = find_root_from_path(&directory).unwrap();
116 97
117 98 assert_eq!(result, root)
118 99 }
@@ -51,20 +51,20 b' impl From<std::io::Error> for ListDirsta'
51 51
52 52 /// List files under Mercurial control in the working directory
53 53 /// by reading the dirstate
54 pub struct ListDirstateTrackedFiles {
54 pub struct Dirstate {
55 55 /// The `dirstate` content.
56 56 content: Vec<u8>,
57 57 }
58 58
59 impl ListDirstateTrackedFiles {
59 impl Dirstate {
60 60 pub fn new(root: &Path) -> Result<Self, ListDirstateTrackedFilesError> {
61 61 let dirstate = root.join(".hg/dirstate");
62 62 let content = fs::read(&dirstate)?;
63 63 Ok(Self { content })
64 64 }
65 65
66 pub fn run(
67 &mut self,
66 pub fn tracked_files(
67 &self,
68 68 ) -> Result<Vec<&HgPath>, ListDirstateTrackedFilesError> {
69 69 let (_, entries, _) = parse_dirstate(&self.content)
70 70 .map_err(ListDirstateTrackedFilesErrorKind::ParseError)?;
@@ -137,58 +137,31 b' impl From<RevlogError> for ListRevTracke'
137 137 }
138 138
139 139 /// List files under Mercurial control at a given revision.
140 pub struct ListRevTrackedFiles<'a> {
141 /// The revision to list the files from.
142 rev: &'a str,
143 /// The changelog file
144 changelog: Changelog,
145 /// The manifest file
146 manifest: Manifest,
147 /// The manifest entry corresponding to the revision.
148 ///
149 /// Used to hold the owner of the returned references.
150 manifest_entry: Option<ManifestEntry>,
140 pub fn list_rev_tracked_files(
141 root: &Path,
142 rev: &str,
143 ) -> Result<FilesForRev, ListRevTrackedFilesError> {
144 let changelog = Changelog::open(root)?;
145 let manifest = Manifest::open(root)?;
146
147 let changelog_entry = match rev.parse::<Revision>() {
148 Ok(rev) => changelog.get_rev(rev)?,
149 _ => {
150 let changelog_node = NodePrefix::from_hex(&rev)
151 .or(Err(ListRevTrackedFilesErrorKind::InvalidRevision))?;
152 changelog.get_node(changelog_node.borrow())?
153 }
154 };
155 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
156 .or(Err(ListRevTrackedFilesErrorKind::CorruptedRevlog))?;
157 let manifest_entry = manifest.get_node((&manifest_node).into())?;
158 Ok(FilesForRev(manifest_entry))
151 159 }
152 160
153 impl<'a> ListRevTrackedFiles<'a> {
154 pub fn new(
155 root: &Path,
156 rev: &'a str,
157 ) -> Result<Self, ListRevTrackedFilesError> {
158 let changelog = Changelog::open(root)?;
159 let manifest = Manifest::open(root)?;
160
161 Ok(Self {
162 rev,
163 changelog,
164 manifest,
165 manifest_entry: None,
166 })
167 }
161 pub struct FilesForRev(ManifestEntry);
168 162
169 pub fn run(
170 &mut self,
171 ) -> Result<impl Iterator<Item = &HgPath>, ListRevTrackedFilesError> {
172 let changelog_entry = match self.rev.parse::<Revision>() {
173 Ok(rev) => self.changelog.get_rev(rev)?,
174 _ => {
175 let changelog_node = NodePrefix::from_hex(&self.rev)
176 .or(Err(ListRevTrackedFilesErrorKind::InvalidRevision))?;
177 self.changelog.get_node(changelog_node.borrow())?
178 }
179 };
180 let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
181 .or(Err(ListRevTrackedFilesErrorKind::CorruptedRevlog))?;
182
183 self.manifest_entry =
184 Some(self.manifest.get_node((&manifest_node).into())?);
185
186 if let Some(ref manifest_entry) = self.manifest_entry {
187 Ok(manifest_entry.files())
188 } else {
189 panic!(
190 "manifest entry should have been stored in self.manifest_node to ensure its lifetime since references are returned from it"
191 )
192 }
163 impl FilesForRev {
164 pub fn iter(&self) -> impl Iterator<Item = &HgPath> {
165 self.0.files()
193 166 }
194 167 }
@@ -7,22 +7,17 b' mod debugdata;'
7 7 mod dirstate_status;
8 8 mod find_root;
9 9 mod list_tracked_files;
10 pub use cat::{CatRev, CatRevError, CatRevErrorKind};
10 pub use cat::{cat, CatRevError, CatRevErrorKind};
11 11 pub use debugdata::{
12 DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind,
12 debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
13 13 };
14 pub use find_root::{FindRoot, FindRootError, FindRootErrorKind};
15 pub use list_tracked_files::{
16 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
17 ListDirstateTrackedFilesErrorKind,
14 pub use find_root::{
15 find_root, find_root_from_path, FindRootError, FindRootErrorKind,
18 16 };
19 17 pub use list_tracked_files::{
20 ListRevTrackedFiles, ListRevTrackedFilesError,
18 list_rev_tracked_files, FilesForRev, ListRevTrackedFilesError,
21 19 ListRevTrackedFilesErrorKind,
22 20 };
23
24 // TODO add an `Operation` trait when GAT have landed (rust #44265):
25 // there is no way to currently define a trait which can both return
26 // references to `self` and to passed data, which is what we would need.
27 // Generic Associated Types may fix this and allow us to have a unified
28 // interface.
21 pub use list_tracked_files::{
22 Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
23 };
@@ -2,8 +2,8 b' use crate::commands::Command;'
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::utf8_to_local;
4 4 use crate::ui::Ui;
5 use hg::operations::FindRoot;
6 use hg::operations::{CatRev, CatRevError, CatRevErrorKind};
5 use hg::operations::find_root;
6 use hg::operations::{cat, CatRevError, CatRevErrorKind};
7 7 use hg::requirements;
8 8 use hg::utils::hg_path::HgPathBuf;
9 9 use micro_timer::timed;
@@ -32,7 +32,7 b" impl<'a> CatCommand<'a> {"
32 32 impl<'a> Command for CatCommand<'a> {
33 33 #[timed]
34 34 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
35 let root = FindRoot::new().run()?;
35 let root = find_root()?;
36 36 requirements::check(&root)?;
37 37 let cwd = std::env::current_dir()
38 38 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
@@ -50,10 +50,8 b" impl<'a> Command for CatCommand<'a> {"
50 50
51 51 match self.rev {
52 52 Some(rev) => {
53 let mut operation = CatRev::new(&root, rev, &files)
53 let data = cat(&root, rev, &files)
54 54 .map_err(|e| map_rev_error(rev, e))?;
55 let data =
56 operation.run().map_err(|e| map_rev_error(rev, e))?;
57 55 self.display(ui, &data)
58 56 }
59 57 None => Err(CommandErrorKind::Unimplemented.into()),
@@ -2,8 +2,9 b' use crate::commands::Command;'
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::utf8_to_local;
4 4 use crate::ui::Ui;
5 use hg::operations::find_root;
5 6 use hg::operations::{
6 DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind,
7 debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
7 8 };
8 9 use micro_timer::timed;
9 10
@@ -25,9 +26,9 b" impl<'a> DebugDataCommand<'a> {"
25 26 impl<'a> Command for DebugDataCommand<'a> {
26 27 #[timed]
27 28 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
28 let mut operation = DebugData::new(self.rev, self.kind);
29 let data =
30 operation.run().map_err(|e| to_command_error(self.rev, e))?;
29 let root = find_root()?;
30 let data = debug_data(&root, self.rev, self.kind)
31 .map_err(|e| to_command_error(self.rev, e))?;
31 32
32 33 let mut stdout = ui.stdout_buffer();
33 34 stdout.write_all(&data)?;
@@ -40,7 +41,6 b" impl<'a> Command for DebugDataCommand<'a"
40 41 /// Convert operation errors to command errors
41 42 fn to_command_error(rev: &str, err: DebugDataError) -> CommandError {
42 43 match err.kind {
43 DebugDataErrorKind::FindRootError(err) => CommandError::from(err),
44 44 DebugDataErrorKind::IoError(err) => CommandError {
45 45 kind: CommandErrorKind::Abort(Some(
46 46 utf8_to_local(&format!("abort: {}\n", err)).into(),
@@ -1,7 +1,7 b''
1 1 use crate::commands::Command;
2 2 use crate::error::CommandError;
3 3 use crate::ui::Ui;
4 use hg::operations::FindRoot;
4 use hg::operations::find_root;
5 5 use hg::requirements;
6 6
7 7 pub const HELP_TEXT: &str = "
@@ -18,7 +18,7 b' impl DebugRequirementsCommand {'
18 18
19 19 impl Command for DebugRequirementsCommand {
20 20 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
21 let root = FindRoot::new().run()?;
21 let root = find_root()?;
22 22 let mut output = String::new();
23 23 for req in requirements::load(&root)? {
24 24 output.push_str(&req);
@@ -2,14 +2,13 b' use crate::commands::Command;'
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::utf8_to_local;
4 4 use crate::ui::Ui;
5 use hg::operations::FindRoot;
5 use hg::operations::find_root;
6 6 use hg::operations::{
7 ListDirstateTrackedFiles, ListDirstateTrackedFilesError,
8 ListDirstateTrackedFilesErrorKind,
7 list_rev_tracked_files, ListRevTrackedFilesError,
8 ListRevTrackedFilesErrorKind,
9 9 };
10 10 use hg::operations::{
11 ListRevTrackedFiles, ListRevTrackedFilesError,
12 ListRevTrackedFilesErrorKind,
11 Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
13 12 };
14 13 use hg::requirements;
15 14 use hg::utils::files::{get_bytes_from_path, relativize_path};
@@ -57,17 +56,15 b" impl<'a> FilesCommand<'a> {"
57 56
58 57 impl<'a> Command for FilesCommand<'a> {
59 58 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
60 let root = FindRoot::new().run()?;
59 let root = find_root()?;
61 60 requirements::check(&root)?;
62 61 if let Some(rev) = self.rev {
63 let mut operation = ListRevTrackedFiles::new(&root, rev)
62 let files = list_rev_tracked_files(&root, rev)
64 63 .map_err(|e| map_rev_error(rev, e))?;
65 let files = operation.run().map_err(|e| map_rev_error(rev, e))?;
66 self.display_files(ui, &root, files)
64 self.display_files(ui, &root, files.iter())
67 65 } else {
68 let mut operation = ListDirstateTrackedFiles::new(&root)
69 .map_err(map_dirstate_error)?;
70 let files = operation.run().map_err(map_dirstate_error)?;
66 let distate = Dirstate::new(&root).map_err(map_dirstate_error)?;
67 let files = distate.tracked_files().map_err(map_dirstate_error)?;
71 68 self.display_files(ui, &root, files)
72 69 }
73 70 }
@@ -2,7 +2,7 b' use crate::commands::Command;'
2 2 use crate::error::CommandError;
3 3 use crate::ui::Ui;
4 4 use format_bytes::format_bytes;
5 use hg::operations::FindRoot;
5 use hg::operations::find_root;
6 6 use hg::utils::files::get_bytes_from_path;
7 7
8 8 pub const HELP_TEXT: &str = "
@@ -21,7 +21,7 b' impl RootCommand {'
21 21
22 22 impl Command for RootCommand {
23 23 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
24 let path_buf = FindRoot::new().run()?;
24 let path_buf = find_root()?;
25 25
26 26 let bytes = get_bytes_from_path(path_buf);
27 27
General Comments 0
You need to be logged in to leave comments. Login now