equal
deleted
inserted
replaced
189 return Ok(vec![]); |
189 return Ok(vec![]); |
190 }; |
190 }; |
191 // Todo return -> Cow |
191 // Todo return -> Cow |
192 let mut entry = self.get_entry(rev)?; |
192 let mut entry = self.get_entry(rev)?; |
193 let mut delta_chain = vec![]; |
193 let mut delta_chain = vec![]; |
194 while let Some(base_rev) = entry.base_rev { |
194 |
|
195 // The meaning of `base_rev_or_base_of_delta_chain` depends on |
|
196 // generaldelta. See the doc on `ENTRY_DELTA_BASE` in |
|
197 // `mercurial/revlogutils/constants.py` and the code in |
|
198 // [_chaininfo] and in [index_deltachain]. |
|
199 let uses_generaldelta = self.index.uses_generaldelta(); |
|
200 while let Some(base_rev) = entry.base_rev_or_base_of_delta_chain { |
|
201 let base_rev = if uses_generaldelta { |
|
202 base_rev |
|
203 } else { |
|
204 entry.rev - 1 |
|
205 }; |
195 delta_chain.push(entry); |
206 delta_chain.push(entry); |
196 entry = self |
207 entry = self.get_entry_internal(base_rev)?; |
197 .get_entry(base_rev) |
|
198 .map_err(|_| RevlogError::corrupted())?; |
|
199 } |
208 } |
200 |
209 |
201 // TODO do not look twice in the index |
210 // TODO do not look twice in the index |
202 let index_entry = self |
211 let index_entry = self |
203 .index |
212 .index |
289 let entry = RevlogEntry { |
298 let entry = RevlogEntry { |
290 rev, |
299 rev, |
291 bytes: data, |
300 bytes: data, |
292 compressed_len: index_entry.compressed_len(), |
301 compressed_len: index_entry.compressed_len(), |
293 uncompressed_len: index_entry.uncompressed_len(), |
302 uncompressed_len: index_entry.uncompressed_len(), |
294 base_rev: if index_entry.base_revision() == rev { |
303 base_rev_or_base_of_delta_chain: if index_entry |
|
304 .base_revision_or_base_of_delta_chain() |
|
305 == rev |
|
306 { |
295 None |
307 None |
296 } else { |
308 } else { |
297 Some(index_entry.base_revision()) |
309 Some(index_entry.base_revision_or_base_of_delta_chain()) |
298 }, |
310 }, |
299 }; |
311 }; |
300 Ok(entry) |
312 Ok(entry) |
|
313 } |
|
314 |
|
315 /// when resolving internal references within revlog, any errors |
|
316 /// should be reported as corruption, instead of e.g. "invalid revision" |
|
317 fn get_entry_internal( |
|
318 &self, |
|
319 rev: Revision, |
|
320 ) -> Result<RevlogEntry, RevlogError> { |
|
321 return self.get_entry(rev).map_err(|_| RevlogError::corrupted()); |
301 } |
322 } |
302 } |
323 } |
303 |
324 |
304 /// The revlog entry's bytes and the necessary informations to extract |
325 /// The revlog entry's bytes and the necessary informations to extract |
305 /// the entry's data. |
326 /// the entry's data. |
307 pub struct RevlogEntry<'a> { |
328 pub struct RevlogEntry<'a> { |
308 rev: Revision, |
329 rev: Revision, |
309 bytes: &'a [u8], |
330 bytes: &'a [u8], |
310 compressed_len: usize, |
331 compressed_len: usize, |
311 uncompressed_len: usize, |
332 uncompressed_len: usize, |
312 base_rev: Option<Revision>, |
333 base_rev_or_base_of_delta_chain: Option<Revision>, |
313 } |
334 } |
314 |
335 |
315 impl<'a> RevlogEntry<'a> { |
336 impl<'a> RevlogEntry<'a> { |
316 pub fn revision(&self) -> Revision { |
337 pub fn revision(&self) -> Revision { |
317 self.rev |
338 self.rev |
373 } |
394 } |
374 |
395 |
375 /// Tell if the entry is a snapshot or a delta |
396 /// Tell if the entry is a snapshot or a delta |
376 /// (influences on decompression). |
397 /// (influences on decompression). |
377 fn is_delta(&self) -> bool { |
398 fn is_delta(&self) -> bool { |
378 self.base_rev.is_some() |
399 self.base_rev_or_base_of_delta_chain.is_some() |
379 } |
400 } |
380 } |
401 } |
381 |
402 |
382 /// Calculate the hash of a revision given its data and its parents. |
403 /// Calculate the hash of a revision given its data and its parents. |
383 fn hash( |
404 fn hash( |