Show More
@@ -70,8 +70,10 b' impl Revlog {' | |||
|
70 | 70 | data_path: Option<&Path>, |
|
71 | 71 | ) -> Result<Self, HgError> { |
|
72 | 72 | let index_path = index_path.as_ref(); |
|
73 | let index_mmap = repo.store_vfs().mmap_open(&index_path)?; | |
|
74 | ||
|
73 | let index = { | |
|
74 | match repo.store_vfs().mmap_open_opt(&index_path)? { | |
|
75 | None => Index::new(Box::new(vec![])), | |
|
76 | Some(index_mmap) => { | |
|
75 | 77 | let version = get_version(&index_mmap)?; |
|
76 | 78 | if version != 1 { |
|
77 | 79 | // A proper new version should have had a repo/store requirement. |
@@ -79,6 +81,10 b' impl Revlog {' | |||
|
79 | 81 | } |
|
80 | 82 | |
|
81 | 83 | let index = Index::new(Box::new(index_mmap))?; |
|
84 | Ok(index) | |
|
85 | } | |
|
86 | } | |
|
87 | }?; | |
|
82 | 88 | |
|
83 | 89 | let default_data_path = index_path.with_extension("d"); |
|
84 | 90 | |
@@ -418,6 +424,6 b' mod tests {' | |||
|
418 | 424 | .with_version(1) |
|
419 | 425 | .build(); |
|
420 | 426 | |
|
421 | assert_eq!(get_version(&bytes), 1) | |
|
427 | assert_eq!(get_version(&bytes).map_err(|_err|()), Ok(1)) | |
|
422 | 428 | } |
|
423 | 429 | } |
@@ -9,6 +9,8 b" pub struct Vfs<'a> {" | |||
|
9 | 9 | pub(crate) base: &'a Path, |
|
10 | 10 | } |
|
11 | 11 | |
|
12 | struct FileNotFound(std::io::Error, PathBuf); | |
|
13 | ||
|
12 | 14 | impl Vfs<'_> { |
|
13 | 15 | pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf { |
|
14 | 16 | self.base.join(relative_path) |
@@ -22,16 +24,41 b" impl Vfs<'_> {" | |||
|
22 | 24 | std::fs::read(&path).when_reading_file(&path) |
|
23 | 25 | } |
|
24 | 26 | |
|
27 | fn mmap_open_gen( | |
|
28 | &self, | |
|
29 | relative_path: impl AsRef<Path>, | |
|
30 | ) -> Result<Result<Mmap, FileNotFound>, HgError> { | |
|
31 | let path = self.join(relative_path); | |
|
32 | let file = match std::fs::File::open(&path) { | |
|
33 | Err(err) => { | |
|
34 | if let ErrorKind::NotFound = err.kind() { | |
|
35 | return Ok(Err(FileNotFound(err, path))); | |
|
36 | }; | |
|
37 | return (Err(err)).when_reading_file(&path); | |
|
38 | } | |
|
39 | Ok(file) => file, | |
|
40 | }; | |
|
41 | // TODO: what are the safety requirements here? | |
|
42 | let mmap = unsafe { MmapOptions::new().map(&file) } | |
|
43 | .when_reading_file(&path)?; | |
|
44 | Ok(Ok(mmap)) | |
|
45 | } | |
|
46 | ||
|
47 | pub fn mmap_open_opt( | |
|
48 | &self, | |
|
49 | relative_path: impl AsRef<Path>, | |
|
50 | ) -> Result<Option<Mmap>, HgError> { | |
|
51 | self.mmap_open_gen(relative_path).map(|res| res.ok()) | |
|
52 | } | |
|
53 | ||
|
25 | 54 | pub fn mmap_open( |
|
26 | 55 | &self, |
|
27 | 56 | relative_path: impl AsRef<Path>, |
|
28 | 57 | ) -> Result<Mmap, HgError> { |
|
29 |
|
|
|
30 |
let |
|
|
31 | // TODO: what are the safety requirements here? | |
|
32 | let mmap = unsafe { MmapOptions::new().map(&file) } | |
|
33 | .when_reading_file(&path)?; | |
|
34 | Ok(mmap) | |
|
58 | match self.mmap_open_gen(relative_path)? { | |
|
59 | Err(FileNotFound(err, path)) => Err(err).when_reading_file(&path), | |
|
60 | Ok(res) => Ok(res), | |
|
61 | } | |
|
35 | 62 | } |
|
36 | 63 | |
|
37 | 64 | pub fn rename( |
@@ -1,23 +1,27 b'' | |||
|
1 | Create a repo such that the changelog entry refers to a null manifest node: | |
|
1 | Test null revisions (node 0000000000000000000000000000000000000000, aka rev -1) | |
|
2 | in various circumstances. | |
|
3 | ||
|
4 | Make an empty repo: | |
|
2 | 5 | |
|
3 | 6 | $ hg init a |
|
4 | 7 | $ 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 | 8 | |
|
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 . | |
|
9 | $ hg files -r 0000000000000000000000000000000000000000 | |
|
10 | [1] | |
|
11 | $ hg files -r . | |
|
18 | 12 | [1] |
|
19 | 13 | |
|
20 | Test a null changelog rev, too: | |
|
14 | Add an empty commit (this makes the changelog refer to a null manifest node): | |
|
15 | ||
|
16 | ||
|
17 | $ hg commit -m "init" --config ui.allowemptycommit=true | |
|
21 | 18 | |
|
22 | $ hg --config rhg.on-unsupported=abort files -r 0000000000000000000000000000000000000000 | |
|
19 | $ hg files -r . | |
|
23 | 20 | [1] |
|
21 | ||
|
22 | Strip that empty commit (this makes the changelog file empty, as opposed to missing): | |
|
23 | ||
|
24 | $ hg --config 'extensions.strip=' strip . > /dev/null | |
|
25 | ||
|
26 | $ hg files -r . | |
|
27 | [1] |
General Comments 0
You need to be logged in to leave comments.
Login now