##// END OF EJS Templates
hg-core: add a `ListRevTrackedFiles` operation...
Antoine Cezar -
r46107:639f33f2 default
parent child Browse files
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::ops::Deref;
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