Show More
@@ -264,6 +264,10 b" pub struct DirstateStatus<'a> {" | |||||
264 | pub ignored: Vec<HgPathCow<'a>>, |
|
264 | pub ignored: Vec<HgPathCow<'a>>, | |
265 | pub unknown: Vec<HgPathCow<'a>>, |
|
265 | pub unknown: Vec<HgPathCow<'a>>, | |
266 | pub bad: Vec<(HgPathCow<'a>, BadMatch)>, |
|
266 | pub bad: Vec<(HgPathCow<'a>, BadMatch)>, | |
|
267 | /// Either clean or modified, but we canβt tell from filesystem metadata | |||
|
268 | /// alone. The file contents need to be read and compared with that in | |||
|
269 | /// the parent. | |||
|
270 | pub unsure: Vec<HgPathCow<'a>>, | |||
267 | /// Only filled if `collect_traversed_dirs` is `true` |
|
271 | /// Only filled if `collect_traversed_dirs` is `true` | |
268 | pub traversed: Vec<HgPathBuf>, |
|
272 | pub traversed: Vec<HgPathBuf>, | |
269 | } |
|
273 | } | |
@@ -847,8 +851,8 b' where' | |||||
847 | pub fn build_response<'a>( |
|
851 | pub fn build_response<'a>( | |
848 | results: impl IntoIterator<Item = DispatchedPath<'a>>, |
|
852 | results: impl IntoIterator<Item = DispatchedPath<'a>>, | |
849 | traversed: Vec<HgPathBuf>, |
|
853 | traversed: Vec<HgPathBuf>, | |
850 |
) -> |
|
854 | ) -> DirstateStatus<'a> { | |
851 |
let mut |
|
855 | let mut unsure = vec![]; | |
852 | let mut modified = vec![]; |
|
856 | let mut modified = vec![]; | |
853 | let mut added = vec![]; |
|
857 | let mut added = vec![]; | |
854 | let mut removed = vec![]; |
|
858 | let mut removed = vec![]; | |
@@ -861,7 +865,7 b" pub fn build_response<'a>(" | |||||
861 | for (filename, dispatch) in results.into_iter() { |
|
865 | for (filename, dispatch) in results.into_iter() { | |
862 | match dispatch { |
|
866 | match dispatch { | |
863 | Dispatch::Unknown => unknown.push(filename), |
|
867 | Dispatch::Unknown => unknown.push(filename), | |
864 |
Dispatch::Unsure => |
|
868 | Dispatch::Unsure => unsure.push(filename), | |
865 | Dispatch::Modified => modified.push(filename), |
|
869 | Dispatch::Modified => modified.push(filename), | |
866 | Dispatch::Added => added.push(filename), |
|
870 | Dispatch::Added => added.push(filename), | |
867 | Dispatch::Removed => removed.push(filename), |
|
871 | Dispatch::Removed => removed.push(filename), | |
@@ -874,8 +878,6 b" pub fn build_response<'a>(" | |||||
874 | } |
|
878 | } | |
875 | } |
|
879 | } | |
876 |
|
880 | |||
877 | ( |
|
|||
878 | lookup, |
|
|||
879 |
|
|
881 | DirstateStatus { | |
880 |
|
|
882 | modified, | |
881 |
|
|
883 | added, | |
@@ -885,9 +887,9 b" pub fn build_response<'a>(" | |||||
885 |
|
|
887 | ignored, | |
886 |
|
|
888 | unknown, | |
887 |
|
|
889 | bad, | |
|
890 | unsure, | |||
888 |
|
|
891 | traversed, | |
889 |
|
|
892 | } | |
890 | ) |
|
|||
891 | } |
|
893 | } | |
892 |
|
894 | |||
893 | /// Get the status of files in the working directory. |
|
895 | /// Get the status of files in the working directory. | |
@@ -902,10 +904,7 b" pub fn status<'a>(" | |||||
902 | root_dir: PathBuf, |
|
904 | root_dir: PathBuf, | |
903 | ignore_files: Vec<PathBuf>, |
|
905 | ignore_files: Vec<PathBuf>, | |
904 | options: StatusOptions, |
|
906 | options: StatusOptions, | |
905 | ) -> StatusResult<( |
|
907 | ) -> StatusResult<(DirstateStatus<'a>, Vec<PatternFileWarning>)> { | |
906 | (Vec<HgPathCow<'a>>, DirstateStatus<'a>), |
|
|||
907 | Vec<PatternFileWarning>, |
|
|||
908 | )> { |
|
|||
909 | let (status, warnings) = |
|
908 | let (status, warnings) = | |
910 | Status::new(dmap, matcher, root_dir, ignore_files, options)?; |
|
909 | Status::new(dmap, matcher, root_dir, ignore_files, options)?; | |
911 |
|
910 |
@@ -19,7 +19,6 b' use crate::DirstateMapError;' | |||||
19 | use crate::DirstateParents; |
|
19 | use crate::DirstateParents; | |
20 | use crate::DirstateStatus; |
|
20 | use crate::DirstateStatus; | |
21 | use crate::EntryState; |
|
21 | use crate::EntryState; | |
22 | use crate::HgPathCow; |
|
|||
23 | use crate::PatternFileWarning; |
|
22 | use crate::PatternFileWarning; | |
24 | use crate::StateMapIter; |
|
23 | use crate::StateMapIter; | |
25 | use crate::StatusError; |
|
24 | use crate::StatusError; | |
@@ -582,13 +581,8 b' impl super::dispatch::DirstateMapMethods' | |||||
582 | _root_dir: PathBuf, |
|
581 | _root_dir: PathBuf, | |
583 | _ignore_files: Vec<PathBuf>, |
|
582 | _ignore_files: Vec<PathBuf>, | |
584 | _options: StatusOptions, |
|
583 | _options: StatusOptions, | |
585 | ) -> Result< |
|
584 | ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError> | |
586 | ( |
|
585 | { | |
587 | (Vec<HgPathCow<'a>>, DirstateStatus<'a>), |
|
|||
588 | Vec<PatternFileWarning>, |
|
|||
589 | ), |
|
|||
590 | StatusError, |
|
|||
591 | > { |
|
|||
592 | todo!() |
|
586 | todo!() | |
593 | } |
|
587 | } | |
594 |
|
588 |
@@ -11,7 +11,6 b' use crate::DirstateMapError;' | |||||
11 | use crate::DirstateParents; |
|
11 | use crate::DirstateParents; | |
12 | use crate::DirstateStatus; |
|
12 | use crate::DirstateStatus; | |
13 | use crate::EntryState; |
|
13 | use crate::EntryState; | |
14 | use crate::HgPathCow; |
|
|||
15 | use crate::PatternFileWarning; |
|
14 | use crate::PatternFileWarning; | |
16 | use crate::StateMapIter; |
|
15 | use crate::StateMapIter; | |
17 | use crate::StatusError; |
|
16 | use crate::StatusError; | |
@@ -102,13 +101,7 b' pub trait DirstateMapMethods {' | |||||
102 | root_dir: PathBuf, |
|
101 | root_dir: PathBuf, | |
103 | ignore_files: Vec<PathBuf>, |
|
102 | ignore_files: Vec<PathBuf>, | |
104 | options: StatusOptions, |
|
103 | options: StatusOptions, | |
105 | ) -> Result< |
|
104 | ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>; | |
106 | ( |
|
|||
107 | (Vec<HgPathCow<'a>>, DirstateStatus<'a>), |
|
|||
108 | Vec<PatternFileWarning>, |
|
|||
109 | ), |
|
|||
110 | StatusError, |
|
|||
111 | >; |
|
|||
112 |
|
105 | |||
113 | fn copy_map_len(&self) -> usize; |
|
106 | fn copy_map_len(&self) -> usize; | |
114 |
|
107 | |||
@@ -270,13 +263,8 b' impl DirstateMapMethods for DirstateMap ' | |||||
270 | root_dir: PathBuf, |
|
263 | root_dir: PathBuf, | |
271 | ignore_files: Vec<PathBuf>, |
|
264 | ignore_files: Vec<PathBuf>, | |
272 | options: StatusOptions, |
|
265 | options: StatusOptions, | |
273 | ) -> Result< |
|
266 | ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError> | |
274 | ( |
|
267 | { | |
275 | (Vec<HgPathCow<'a>>, DirstateStatus<'a>), |
|
|||
276 | Vec<PatternFileWarning>, |
|
|||
277 | ), |
|
|||
278 | StatusError, |
|
|||
279 | > { |
|
|||
280 | crate::status(self, matcher, root_dir, ignore_files, options) |
|
268 | crate::status(self, matcher, root_dir, ignore_files, options) | |
281 | } |
|
269 | } | |
282 |
|
270 |
@@ -5,17 +5,12 b'' | |||||
5 | // This software may be used and distributed according to the terms of the |
|
5 | // This software may be used and distributed according to the terms of the | |
6 | // GNU General Public License version 2 or any later version. |
|
6 | // GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 |
use crate::dirstate::status::{build_response, Dispatch, |
|
8 | use crate::dirstate::status::{build_response, Dispatch, Status}; | |
9 | use crate::matchers::Matcher; |
|
9 | use crate::matchers::Matcher; | |
10 | use crate::{DirstateStatus, StatusError}; |
|
10 | use crate::{DirstateStatus, StatusError}; | |
11 |
|
11 | |||
12 | /// A tuple of the paths that need to be checked in the filelog because it's |
|
|||
13 | /// ambiguous whether they've changed, and the rest of the already dispatched |
|
|||
14 | /// files. |
|
|||
15 | pub type LookupAndStatus<'a> = (Vec<HgPathCow<'a>>, DirstateStatus<'a>); |
|
|||
16 |
|
||||
17 | impl<'a, M: ?Sized + Matcher + Sync> Status<'a, M> { |
|
12 | impl<'a, M: ?Sized + Matcher + Sync> Status<'a, M> { | |
18 |
pub(crate) fn run(&self) -> Result< |
|
13 | pub(crate) fn run(&self) -> Result<DirstateStatus<'a>, StatusError> { | |
19 | let (traversed_sender, traversed_receiver) = |
|
14 | let (traversed_sender, traversed_receiver) = | |
20 | crossbeam_channel::unbounded(); |
|
15 | crossbeam_channel::unbounded(); | |
21 |
|
16 |
@@ -25,7 +25,7 b' use hg::{' | |||||
25 | BadMatch, DirstateStatus, IgnorePattern, PatternFileWarning, StatusError, |
|
25 | BadMatch, DirstateStatus, IgnorePattern, PatternFileWarning, StatusError, | |
26 | StatusOptions, |
|
26 | StatusOptions, | |
27 | }; |
|
27 | }; | |
28 |
use std::borrow:: |
|
28 | use std::borrow::Borrow; | |
29 |
|
29 | |||
30 | /// This will be useless once trait impls for collection are added to `PyBytes` |
|
30 | /// This will be useless once trait impls for collection are added to `PyBytes` | |
31 | /// upstream. |
|
31 | /// upstream. | |
@@ -126,7 +126,7 b' pub fn status_wrapper(' | |||||
126 | match matcher.get_type(py).name(py).borrow() { |
|
126 | match matcher.get_type(py).name(py).borrow() { | |
127 | "alwaysmatcher" => { |
|
127 | "alwaysmatcher" => { | |
128 | let matcher = AlwaysMatcher; |
|
128 | let matcher = AlwaysMatcher; | |
129 |
let ( |
|
129 | let (status_res, warnings) = dmap | |
130 | .status( |
|
130 | .status( | |
131 | &matcher, |
|
131 | &matcher, | |
132 | root_dir.to_path_buf(), |
|
132 | root_dir.to_path_buf(), | |
@@ -141,7 +141,7 b' pub fn status_wrapper(' | |||||
141 | }, |
|
141 | }, | |
142 | ) |
|
142 | ) | |
143 | .map_err(|e| handle_fallback(py, e))?; |
|
143 | .map_err(|e| handle_fallback(py, e))?; | |
144 |
build_response(py |
|
144 | build_response(py, status_res, warnings) | |
145 | } |
|
145 | } | |
146 | "exactmatcher" => { |
|
146 | "exactmatcher" => { | |
147 | let files = matcher.call_method( |
|
147 | let files = matcher.call_method( | |
@@ -163,7 +163,7 b' pub fn status_wrapper(' | |||||
163 | let files = files?; |
|
163 | let files = files?; | |
164 | let matcher = FileMatcher::new(files.as_ref()) |
|
164 | let matcher = FileMatcher::new(files.as_ref()) | |
165 | .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?; |
|
165 | .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?; | |
166 |
let ( |
|
166 | let (status_res, warnings) = dmap | |
167 | .status( |
|
167 | .status( | |
168 | &matcher, |
|
168 | &matcher, | |
169 | root_dir.to_path_buf(), |
|
169 | root_dir.to_path_buf(), | |
@@ -178,7 +178,7 b' pub fn status_wrapper(' | |||||
178 | }, |
|
178 | }, | |
179 | ) |
|
179 | ) | |
180 | .map_err(|e| handle_fallback(py, e))?; |
|
180 | .map_err(|e| handle_fallback(py, e))?; | |
181 |
build_response(py |
|
181 | build_response(py, status_res, warnings) | |
182 | } |
|
182 | } | |
183 | "includematcher" => { |
|
183 | "includematcher" => { | |
184 | // Get the patterns from Python even though most of them are |
|
184 | // Get the patterns from Python even though most of them are | |
@@ -218,7 +218,7 b' pub fn status_wrapper(' | |||||
218 | .map_err(|e| handle_fallback(py, e.into()))?; |
|
218 | .map_err(|e| handle_fallback(py, e.into()))?; | |
219 | all_warnings.extend(warnings); |
|
219 | all_warnings.extend(warnings); | |
220 |
|
220 | |||
221 |
let ( |
|
221 | let (status_res, warnings) = dmap | |
222 | .status( |
|
222 | .status( | |
223 | &matcher, |
|
223 | &matcher, | |
224 | root_dir.to_path_buf(), |
|
224 | root_dir.to_path_buf(), | |
@@ -236,7 +236,7 b' pub fn status_wrapper(' | |||||
236 |
|
236 | |||
237 | all_warnings.extend(warnings); |
|
237 | all_warnings.extend(warnings); | |
238 |
|
238 | |||
239 |
build_response(py |
|
239 | build_response(py, status_res, all_warnings) | |
240 | } |
|
240 | } | |
241 | e => Err(PyErr::new::<ValueError, _>( |
|
241 | e => Err(PyErr::new::<ValueError, _>( | |
242 | py, |
|
242 | py, | |
@@ -247,7 +247,6 b' pub fn status_wrapper(' | |||||
247 |
|
247 | |||
248 | fn build_response( |
|
248 | fn build_response( | |
249 | py: Python, |
|
249 | py: Python, | |
250 | lookup: Vec<Cow<HgPath>>, |
|
|||
251 | status_res: DirstateStatus, |
|
250 | status_res: DirstateStatus, | |
252 | warnings: Vec<PatternFileWarning>, |
|
251 | warnings: Vec<PatternFileWarning>, | |
253 | ) -> PyResult<PyTuple> { |
|
252 | ) -> PyResult<PyTuple> { | |
@@ -258,7 +257,7 b' fn build_response(' | |||||
258 | let clean = collect_pybytes_list(py, status_res.clean.as_ref()); |
|
257 | let clean = collect_pybytes_list(py, status_res.clean.as_ref()); | |
259 | let ignored = collect_pybytes_list(py, status_res.ignored.as_ref()); |
|
258 | let ignored = collect_pybytes_list(py, status_res.ignored.as_ref()); | |
260 | let unknown = collect_pybytes_list(py, status_res.unknown.as_ref()); |
|
259 | let unknown = collect_pybytes_list(py, status_res.unknown.as_ref()); | |
261 |
let |
|
260 | let unsure = collect_pybytes_list(py, status_res.unsure.as_ref()); | |
262 | let bad = collect_bad_matches(py, status_res.bad.as_ref())?; |
|
261 | let bad = collect_bad_matches(py, status_res.bad.as_ref())?; | |
263 | let traversed = collect_pybytes_list(py, status_res.traversed.as_ref()); |
|
262 | let traversed = collect_pybytes_list(py, status_res.traversed.as_ref()); | |
264 | let py_warnings = PyList::new(py, &[]); |
|
263 | let py_warnings = PyList::new(py, &[]); | |
@@ -287,7 +286,7 b' fn build_response(' | |||||
287 | Ok(PyTuple::new( |
|
286 | Ok(PyTuple::new( | |
288 | py, |
|
287 | py, | |
289 | &[ |
|
288 | &[ | |
290 |
|
|
289 | unsure.into_object(), | |
291 | modified.into_object(), |
|
290 | modified.into_object(), | |
292 | added.into_object(), |
|
291 | added.into_object(), | |
293 | removed.into_object(), |
|
292 | removed.into_object(), |
@@ -181,7 +181,7 b' pub fn run(invocation: &crate::CliInvoca' | |||||
181 | collect_traversed_dirs: false, |
|
181 | collect_traversed_dirs: false, | |
182 | }; |
|
182 | }; | |
183 | let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded |
|
183 | let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded | |
184 |
let ( |
|
184 | let (ds_status, pattern_warnings) = hg::status( | |
185 | &dmap, |
|
185 | &dmap, | |
186 | &AlwaysMatcher, |
|
186 | &AlwaysMatcher, | |
187 | repo.working_directory_path().to_owned(), |
|
187 | repo.working_directory_path().to_owned(), | |
@@ -195,10 +195,10 b' pub fn run(invocation: &crate::CliInvoca' | |||||
195 | if !ds_status.bad.is_empty() { |
|
195 | if !ds_status.bad.is_empty() { | |
196 | warn!("Bad matches {:?}", &(ds_status.bad)) |
|
196 | warn!("Bad matches {:?}", &(ds_status.bad)) | |
197 | } |
|
197 | } | |
198 |
if ! |
|
198 | if !ds_status.unsure.is_empty() { | |
199 | info!( |
|
199 | info!( | |
200 | "Files to be rechecked by retrieval from filelog: {:?}", |
|
200 | "Files to be rechecked by retrieval from filelog: {:?}", | |
201 | &lookup |
|
201 | &ds_status.unsure | |
202 | ); |
|
202 | ); | |
203 | } |
|
203 | } | |
204 | // TODO check ordering to match `hg status` output. |
|
204 | // TODO check ordering to match `hg status` output. | |
@@ -206,7 +206,7 b' pub fn run(invocation: &crate::CliInvoca' | |||||
206 | if display_states.modified { |
|
206 | if display_states.modified { | |
207 | display_status_paths(ui, &(ds_status.modified), b"M")?; |
|
207 | display_status_paths(ui, &(ds_status.modified), b"M")?; | |
208 | } |
|
208 | } | |
209 |
if ! |
|
209 | if !ds_status.unsure.is_empty() { | |
210 | let p1: Node = parents |
|
210 | let p1: Node = parents | |
211 | .expect( |
|
211 | .expect( | |
212 | "Dirstate with no parents should not list any file to |
|
212 | "Dirstate with no parents should not list any file to | |
@@ -217,7 +217,7 b' pub fn run(invocation: &crate::CliInvoca' | |||||
217 | let p1_hex = format!("{:x}", p1); |
|
217 | let p1_hex = format!("{:x}", p1); | |
218 | let mut rechecked_modified: Vec<HgPathCow> = Vec::new(); |
|
218 | let mut rechecked_modified: Vec<HgPathCow> = Vec::new(); | |
219 | let mut rechecked_clean: Vec<HgPathCow> = Vec::new(); |
|
219 | let mut rechecked_clean: Vec<HgPathCow> = Vec::new(); | |
220 |
for to_check in |
|
220 | for to_check in ds_status.unsure { | |
221 | if cat_file_is_modified(repo, &to_check, &p1_hex)? { |
|
221 | if cat_file_is_modified(repo, &to_check, &p1_hex)? { | |
222 | rechecked_modified.push(to_check); |
|
222 | rechecked_modified.push(to_check); | |
223 | } else { |
|
223 | } else { |
General Comments 0
You need to be logged in to leave comments.
Login now