Show More
@@ -6,14 +6,16 b'' | |||||
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::parsers::parse_dirstate; |
|
8 | use crate::dirstate::parsers::parse_dirstate; | |
|
9 | use crate::revlog::changelog::Changelog; | |||
|
10 | use crate::revlog::manifest::{Manifest, ManifestEntry}; | |||
|
11 | use crate::revlog::revlog::RevlogError; | |||
|
12 | use crate::revlog::Revision; | |||
9 | use crate::utils::hg_path::HgPath; |
|
13 | use crate::utils::hg_path::HgPath; | |
10 | use crate::{DirstateParseError, EntryState}; |
|
14 | use crate::{DirstateParseError, EntryState}; | |
11 | use rayon::prelude::*; |
|
15 | use rayon::prelude::*; | |
12 | use std::convert::From; |
|
16 | use std::convert::From; | |
13 | use std::fmt; |
|
|||
14 | use std::fs; |
|
17 | use std::fs; | |
15 |
use std:: |
|
18 | use std::path::PathBuf; | |
16 | use std::path::{Path, PathBuf}; |
|
|||
17 |
|
19 | |||
18 | /// Kind of error encountered by `ListDirstateTrackedFiles` |
|
20 | /// Kind of error encountered by `ListDirstateTrackedFiles` | |
19 | #[derive(Debug)] |
|
21 | #[derive(Debug)] | |
@@ -31,14 +33,6 b' pub struct ListDirstateTrackedFilesError' | |||||
31 | pub kind: ListDirstateTrackedFilesErrorKind, |
|
33 | pub kind: ListDirstateTrackedFilesErrorKind, | |
32 | } |
|
34 | } | |
33 |
|
35 | |||
34 | impl std::error::Error for ListDirstateTrackedFilesError {} |
|
|||
35 |
|
||||
36 | impl fmt::Display for ListDirstateTrackedFilesError { |
|
|||
37 | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
|||
38 | unimplemented!() |
|
|||
39 | } |
|
|||
40 | } |
|
|||
41 |
|
||||
42 | impl From<ListDirstateTrackedFilesErrorKind> |
|
36 | impl From<ListDirstateTrackedFilesErrorKind> | |
43 | for ListDirstateTrackedFilesError |
|
37 | for ListDirstateTrackedFilesError | |
44 | { |
|
38 | { | |
@@ -84,3 +78,111 b' impl ListDirstateTrackedFiles {' | |||||
84 | Ok(files) |
|
78 | Ok(files) | |
85 | } |
|
79 | } | |
86 | } |
|
80 | } | |
|
81 | ||||
|
82 | /// Kind of error encountered by `ListRevTrackedFiles` | |||
|
83 | #[derive(Debug)] | |||
|
84 | pub enum ListRevTrackedFilesErrorKind { | |||
|
85 | /// Error when reading a `revlog` file. | |||
|
86 | IoError(std::io::Error), | |||
|
87 | /// The revision has not been found. | |||
|
88 | InvalidRevision, | |||
|
89 | /// A `revlog` file is corrupted. | |||
|
90 | CorruptedRevlog, | |||
|
91 | /// The `revlog` format version is not supported. | |||
|
92 | UnsuportedRevlogVersion(u16), | |||
|
93 | /// The `revlog` data format is not supported. | |||
|
94 | UnknowRevlogDataFormat(u8), | |||
|
95 | } | |||
|
96 | ||||
|
97 | /// A `ListRevTrackedFiles` error | |||
|
98 | #[derive(Debug)] | |||
|
99 | pub struct ListRevTrackedFilesError { | |||
|
100 | /// Kind of error encountered by `ListRevTrackedFiles` | |||
|
101 | pub kind: ListRevTrackedFilesErrorKind, | |||
|
102 | } | |||
|
103 | ||||
|
104 | impl From<ListRevTrackedFilesErrorKind> for ListRevTrackedFilesError { | |||
|
105 | fn from(kind: ListRevTrackedFilesErrorKind) -> Self { | |||
|
106 | ListRevTrackedFilesError { kind } | |||
|
107 | } | |||
|
108 | } | |||
|
109 | ||||
|
110 | impl From<RevlogError> for ListRevTrackedFilesError { | |||
|
111 | fn from(err: RevlogError) -> Self { | |||
|
112 | match err { | |||
|
113 | RevlogError::IoError(err) => { | |||
|
114 | ListRevTrackedFilesErrorKind::IoError(err) | |||
|
115 | } | |||
|
116 | RevlogError::UnsuportedVersion(version) => { | |||
|
117 | ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version) | |||
|
118 | } | |||
|
119 | RevlogError::InvalidRevision => { | |||
|
120 | ListRevTrackedFilesErrorKind::InvalidRevision | |||
|
121 | } | |||
|
122 | RevlogError::Corrupted => { | |||
|
123 | ListRevTrackedFilesErrorKind::CorruptedRevlog | |||
|
124 | } | |||
|
125 | RevlogError::UnknowDataFormat(format) => { | |||
|
126 | ListRevTrackedFilesErrorKind::UnknowRevlogDataFormat(format) | |||
|
127 | } | |||
|
128 | } | |||
|
129 | .into() | |||
|
130 | } | |||
|
131 | } | |||
|
132 | ||||
|
133 | /// List files under Mercurial control at a given revision. | |||
|
134 | pub struct ListRevTrackedFiles<'a> { | |||
|
135 | /// The revision to list the files from. | |||
|
136 | rev: &'a str, | |||
|
137 | /// The changelog file | |||
|
138 | changelog: Changelog, | |||
|
139 | /// The manifest file | |||
|
140 | manifest: Manifest, | |||
|
141 | /// The manifest entry corresponding to the revision. | |||
|
142 | /// | |||
|
143 | /// Used to hold the owner of the returned references. | |||
|
144 | manifest_entry: Option<ManifestEntry>, | |||
|
145 | } | |||
|
146 | ||||
|
147 | impl<'a> ListRevTrackedFiles<'a> { | |||
|
148 | pub fn new( | |||
|
149 | root: &PathBuf, | |||
|
150 | rev: &'a str, | |||
|
151 | ) -> Result<Self, ListRevTrackedFilesError> { | |||
|
152 | let changelog = Changelog::open(&root)?; | |||
|
153 | let manifest = Manifest::open(&root)?; | |||
|
154 | ||||
|
155 | Ok(Self { | |||
|
156 | rev, | |||
|
157 | changelog, | |||
|
158 | manifest, | |||
|
159 | manifest_entry: None, | |||
|
160 | }) | |||
|
161 | } | |||
|
162 | ||||
|
163 | pub fn run( | |||
|
164 | &mut self, | |||
|
165 | ) -> Result<impl Iterator<Item = &HgPath>, ListRevTrackedFilesError> { | |||
|
166 | let changelog_entry = match self.rev.parse::<Revision>() { | |||
|
167 | Ok(rev) => self.changelog.get_rev(rev)?, | |||
|
168 | _ => { | |||
|
169 | let changelog_node = hex::decode(&self.rev).map_err(|_| { | |||
|
170 | ListRevTrackedFilesErrorKind::InvalidRevision | |||
|
171 | })?; | |||
|
172 | self.changelog.get_node(&changelog_node)? | |||
|
173 | } | |||
|
174 | }; | |||
|
175 | let manifest_node = hex::decode(&changelog_entry.manifest_node()?) | |||
|
176 | .map_err(|_| ListRevTrackedFilesErrorKind::CorruptedRevlog)?; | |||
|
177 | ||||
|
178 | self.manifest_entry = Some(self.manifest.get_node(&manifest_node)?); | |||
|
179 | ||||
|
180 | if let Some(ref manifest_entry) = self.manifest_entry { | |||
|
181 | Ok(manifest_entry.files()) | |||
|
182 | } else { | |||
|
183 | panic!( | |||
|
184 | "manifest entry should have been stored in self.manifest_node to ensure its lifetime since references are returned from it" | |||
|
185 | ) | |||
|
186 | } | |||
|
187 | } | |||
|
188 | } |
@@ -14,6 +14,10 b' pub use list_tracked_files::{' | |||||
14 | ListDirstateTrackedFiles, ListDirstateTrackedFilesError, |
|
14 | ListDirstateTrackedFiles, ListDirstateTrackedFilesError, | |
15 | ListDirstateTrackedFilesErrorKind, |
|
15 | ListDirstateTrackedFilesErrorKind, | |
16 | }; |
|
16 | }; | |
|
17 | pub use list_tracked_files::{ | |||
|
18 | ListRevTrackedFiles, ListRevTrackedFilesError, | |||
|
19 | ListRevTrackedFilesErrorKind, | |||
|
20 | }; | |||
17 |
|
21 | |||
18 | // TODO add an `Operation` trait when GAT have landed (rust #44265): |
|
22 | // TODO add an `Operation` trait when GAT have landed (rust #44265): | |
19 | // there is no way to currently define a trait which can both return |
|
23 | // there is no way to currently define a trait which can both return |
@@ -44,6 +44,20 b" impl<'a> Index<'a> {" | |||||
44 | } |
|
44 | } | |
45 | } |
|
45 | } | |
46 |
|
46 | |||
|
47 | /// Return number of entries of the revlog index. | |||
|
48 | pub fn len(&self) -> usize { | |||
|
49 | if let Some(offsets) = &self.offsets { | |||
|
50 | offsets.len() | |||
|
51 | } else { | |||
|
52 | self.bytes.len() / INDEX_ENTRY_SIZE | |||
|
53 | } | |||
|
54 | } | |||
|
55 | ||||
|
56 | /// Returns `true` if the `Index` has zero `entries`. | |||
|
57 | pub fn is_empty(&self) -> bool { | |||
|
58 | self.len() == 0 | |||
|
59 | } | |||
|
60 | ||||
47 | /// Return the index entry corresponding to the given revision if it |
|
61 | /// Return the index entry corresponding to the given revision if it | |
48 | /// exists. |
|
62 | /// exists. | |
49 | pub fn get_entry(&self, rev: Revision) -> Option<IndexEntry> { |
|
63 | pub fn get_entry(&self, rev: Revision) -> Option<IndexEntry> { |
@@ -188,7 +188,7 b' impl Revlog {' | |||||
188 | } |
|
188 | } | |
189 |
|
189 | |||
190 | /// Return the revlog index. |
|
190 | /// Return the revlog index. | |
191 | fn index(&self) -> Index { |
|
191 | pub fn index(&self) -> Index { | |
192 | let is_inline = self.data_bytes.is_none(); |
|
192 | let is_inline = self.data_bytes.is_none(); | |
193 | Index::new(&self.index_bytes, is_inline) |
|
193 | Index::new(&self.index_bytes, is_inline) | |
194 | } |
|
194 | } |
General Comments 0
You need to be logged in to leave comments.
Login now