Mercurial > hg
comparison rust/rhg/src/commands/status.rs @ 47956:81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
This moves low-level dirstate wrangling out of the status command and into
a more reusable location.
The open dirstate map is lazily initialized and kept on the Repo object,
for reuse by sub-sequent calls.
Differential Revision: https://phab.mercurial-scm.org/D11398
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 09 Sep 2021 21:04:55 +0200 |
parents | 78f7f0d490ee |
children | 796206e74b10 |
comparison
equal
deleted
inserted
replaced
47955:e834b79def74 | 47956:81aedf1fc897 |
---|---|
7 | 7 |
8 use crate::error::CommandError; | 8 use crate::error::CommandError; |
9 use crate::ui::Ui; | 9 use crate::ui::Ui; |
10 use clap::{Arg, SubCommand}; | 10 use clap::{Arg, SubCommand}; |
11 use hg; | 11 use hg; |
12 use hg::dirstate_tree::dirstate_map::DirstateMap; | 12 use hg::dirstate_tree::dispatch::DirstateMapMethods; |
13 use hg::dirstate_tree::on_disk; | |
14 use hg::errors::HgResultExt; | |
15 use hg::errors::IoResultExt; | 13 use hg::errors::IoResultExt; |
16 use hg::matchers::AlwaysMatcher; | 14 use hg::matchers::AlwaysMatcher; |
17 use hg::operations::cat; | 15 use hg::operations::cat; |
18 use hg::repo::Repo; | 16 use hg::repo::Repo; |
19 use hg::revlog::node::Node; | 17 use hg::revlog::node::Node; |
164 requested | 162 requested |
165 } | 163 } |
166 }; | 164 }; |
167 | 165 |
168 let repo = invocation.repo?; | 166 let repo = invocation.repo?; |
169 let dirstate_data_mmap; | 167 let mut dmap = repo.dirstate_map_mut()?; |
170 let (mut dmap, parents) = if repo.has_dirstate_v2() { | |
171 let docket_data = | |
172 repo.hg_vfs().read("dirstate").io_not_found_as_none()?; | |
173 let parents; | |
174 let dirstate_data; | |
175 let data_size; | |
176 let docket; | |
177 let tree_metadata; | |
178 if let Some(docket_data) = &docket_data { | |
179 docket = on_disk::read_docket(docket_data)?; | |
180 tree_metadata = docket.tree_metadata(); | |
181 parents = Some(docket.parents()); | |
182 data_size = docket.data_size(); | |
183 dirstate_data_mmap = repo | |
184 .hg_vfs() | |
185 .mmap_open(docket.data_filename()) | |
186 .io_not_found_as_none()?; | |
187 dirstate_data = dirstate_data_mmap.as_deref().unwrap_or(b""); | |
188 } else { | |
189 parents = None; | |
190 tree_metadata = b""; | |
191 data_size = 0; | |
192 dirstate_data = b""; | |
193 } | |
194 let dmap = | |
195 DirstateMap::new_v2(dirstate_data, data_size, tree_metadata)?; | |
196 (dmap, parents) | |
197 } else { | |
198 dirstate_data_mmap = | |
199 repo.hg_vfs().mmap_open("dirstate").io_not_found_as_none()?; | |
200 let dirstate_data = dirstate_data_mmap.as_deref().unwrap_or(b""); | |
201 DirstateMap::new_v1(dirstate_data)? | |
202 }; | |
203 | 168 |
204 let options = StatusOptions { | 169 let options = StatusOptions { |
205 // TODO should be provided by the dirstate parsing and | 170 // TODO should be provided by the dirstate parsing and |
206 // hence be stored on dmap. Using a value that assumes we aren't | 171 // hence be stored on dmap. Using a value that assumes we aren't |
207 // below the time resolution granularity of the FS and the | 172 // below the time resolution granularity of the FS and the |
214 list_unknown: display_states.unknown, | 179 list_unknown: display_states.unknown, |
215 list_ignored: display_states.ignored, | 180 list_ignored: display_states.ignored, |
216 collect_traversed_dirs: false, | 181 collect_traversed_dirs: false, |
217 }; | 182 }; |
218 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded | 183 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded |
219 let (mut ds_status, pattern_warnings) = hg::dirstate_tree::status::status( | 184 let (mut ds_status, pattern_warnings) = dmap.status( |
220 &mut dmap, | |
221 &AlwaysMatcher, | 185 &AlwaysMatcher, |
222 repo.working_directory_path().to_owned(), | 186 repo.working_directory_path().to_owned(), |
223 vec![ignore_file], | 187 vec![ignore_file], |
224 options, | 188 options, |
225 )?; | 189 )?; |
237 ); | 201 ); |
238 } | 202 } |
239 if !ds_status.unsure.is_empty() | 203 if !ds_status.unsure.is_empty() |
240 && (display_states.modified || display_states.clean) | 204 && (display_states.modified || display_states.clean) |
241 { | 205 { |
242 let p1: Node = parents | 206 let p1: Node = repo.dirstate_parents()?.p1.into(); |
243 .expect( | |
244 "Dirstate with no parents should not list any file to | |
245 be rechecked for modifications", | |
246 ) | |
247 .p1 | |
248 .into(); | |
249 let p1_hex = format!("{:x}", p1); | 207 let p1_hex = format!("{:x}", p1); |
250 for to_check in ds_status.unsure { | 208 for to_check in ds_status.unsure { |
251 if cat_file_is_modified(repo, &to_check, &p1_hex)? { | 209 if cat_file_is_modified(repo, &to_check, &p1_hex)? { |
252 if display_states.modified { | 210 if display_states.modified { |
253 ds_status.modified.push(to_check); | 211 ds_status.modified.push(to_check); |