##// END OF EJS Templates
rhg: handle null changelog and manifest revisions...
Arseniy Alekseyev -
r49012:61ce70fd default
parent child Browse files
Show More
@@ -0,0 +1,23 b''
1 Create a repo such that the changelog entry refers to a null manifest node:
2
3 $ hg init a
4 $ cd a
5 $ hg log
6 $ touch x
7 $ hg add x
8 $ hg commit -m "init"
9 $ hg rm x
10 $ hg commit -q --amend
11
12 $ wc -c < .hg/store/00manifest.i
13 0
14
15 Make sure that the manifest can be read (and is empty):
16
17 $ hg --config rhg.on-unsupported=abort files -r .
18 [1]
19
20 Test a null changelog rev, too:
21
22 $ hg --config rhg.on-unsupported=abort files -r 0000000000000000000000000000000000000000
23 [1]
@@ -1,5 +1,6 b''
1 1 use crate::errors::HgError;
2 2 use crate::repo::Repo;
3 use crate::revlog::node::NULL_NODE;
3 4 use crate::revlog::revlog::{Revlog, RevlogError};
4 5 use crate::revlog::Revision;
5 6 use crate::revlog::{Node, NodePrefix};
@@ -58,10 +59,9 b' impl ChangelogEntry {'
58 59 /// Return the node id of the `manifest` referenced by this `changelog`
59 60 /// entry.
60 61 pub fn manifest_node(&self) -> Result<Node, HgError> {
61 Node::from_hex_for_repo(
62 self.lines()
63 .next()
64 .ok_or_else(|| HgError::corrupted("empty changelog entry"))?,
65 )
62 match self.lines().next() {
63 None => Ok(NULL_NODE),
64 Some(x) => Node::from_hex_for_repo(x),
65 }
66 66 }
67 67 }
@@ -208,6 +208,9 b" impl<'a> IndexEntry<'a> {"
208 208
209 209 /// Value of the inline flag.
210 210 pub fn is_inline(index_bytes: &[u8]) -> bool {
211 if index_bytes.len() < 4 {
212 return true;
213 }
211 214 match &index_bytes[0..=1] {
212 215 [0, 0] | [0, 2] => false,
213 216 _ => true,
@@ -72,7 +72,7 b' impl Revlog {'
72 72 let index_path = index_path.as_ref();
73 73 let index_mmap = repo.store_vfs().mmap_open(&index_path)?;
74 74
75 let version = get_version(&index_mmap);
75 let version = get_version(&index_mmap)?;
76 76 if version != 1 {
77 77 // A proper new version should have had a repo/store requirement.
78 78 return Err(HgError::corrupted("corrupted revlog"));
@@ -179,6 +179,9 b' impl Revlog {'
179 179 /// snapshot to rebuild the final data.
180 180 #[timed]
181 181 pub fn get_rev_data(&self, rev: Revision) -> Result<Vec<u8>, RevlogError> {
182 if rev == NULL_REVISION {
183 return Ok(vec![]);
184 };
182 185 // Todo return -> Cow
183 186 let mut entry = self.get_entry(rev)?;
184 187 let mut delta_chain = vec![];
@@ -371,8 +374,16 b" impl<'a> RevlogEntry<'a> {"
371 374 }
372 375
373 376 /// Format version of the revlog.
374 pub fn get_version(index_bytes: &[u8]) -> u16 {
375 BigEndian::read_u16(&index_bytes[2..=3])
377 pub fn get_version(index_bytes: &[u8]) -> Result<u16, HgError> {
378 if index_bytes.len() == 0 {
379 return Ok(1);
380 };
381 if index_bytes.len() < 4 {
382 return Err(HgError::corrupted(
383 "corrupted revlog: can't read the index format header",
384 ));
385 };
386 Ok(BigEndian::read_u16(&index_bytes[2..=3]))
376 387 }
377 388
378 389 /// Calculate the hash of a revision given its data and its parents.
General Comments 0
You need to be logged in to leave comments. Login now