Show More
@@ -0,0 +1,4 b'' | |||||
|
1 | /// Added at the start of `.hg/dirstate` when the "v2" format is used. | |||
|
2 | /// Acts like a "magic number". This is a sanity check, not strictly necessary | |||
|
3 | /// since `.hg/requires` already governs which format should be used. | |||
|
4 | pub const V2_FORMAT_MARKER: &[u8; 12] = b"dirstate-v2\n"; |
@@ -25,6 +25,7 b' from mercurial import (' | |||||
25 | httpconnection, |
|
25 | httpconnection, | |
26 | match as matchmod, |
|
26 | match as matchmod, | |
27 | pycompat, |
|
27 | pycompat, | |
|
28 | requirements, | |||
28 | scmutil, |
|
29 | scmutil, | |
29 | sparse, |
|
30 | sparse, | |
30 | util, |
|
31 | util, | |
@@ -197,6 +198,7 b' def openlfdirstate(ui, repo, create=True' | |||||
197 | vfs = repo.vfs |
|
198 | vfs = repo.vfs | |
198 | lfstoredir = longname |
|
199 | lfstoredir = longname | |
199 | opener = vfsmod.vfs(vfs.join(lfstoredir)) |
|
200 | opener = vfsmod.vfs(vfs.join(lfstoredir)) | |
|
201 | use_dirstate_v2 = requirements.DIRSTATE_V2_REQUIREMENT in repo.requirements | |||
200 | lfdirstate = largefilesdirstate( |
|
202 | lfdirstate = largefilesdirstate( | |
201 | opener, |
|
203 | opener, | |
202 | ui, |
|
204 | ui, | |
@@ -204,6 +206,7 b' def openlfdirstate(ui, repo, create=True' | |||||
204 | repo.dirstate._validate, |
|
206 | repo.dirstate._validate, | |
205 | lambda: sparse.matcher(repo), |
|
207 | lambda: sparse.matcher(repo), | |
206 | repo.nodeconstants, |
|
208 | repo.nodeconstants, | |
|
209 | use_dirstate_v2, | |||
207 | ) |
|
210 | ) | |
208 |
|
211 | |||
209 | # If the largefiles dirstate does not exist, populate and create |
|
212 | # If the largefiles dirstate does not exist, populate and create |
@@ -75,7 +75,14 b' def _getfsnow(vfs):' | |||||
75 | @interfaceutil.implementer(intdirstate.idirstate) |
|
75 | @interfaceutil.implementer(intdirstate.idirstate) | |
76 | class dirstate(object): |
|
76 | class dirstate(object): | |
77 | def __init__( |
|
77 | def __init__( | |
78 | self, opener, ui, root, validate, sparsematchfn, nodeconstants |
|
78 | self, | |
|
79 | opener, | |||
|
80 | ui, | |||
|
81 | root, | |||
|
82 | validate, | |||
|
83 | sparsematchfn, | |||
|
84 | nodeconstants, | |||
|
85 | use_dirstate_v2, | |||
79 | ): |
|
86 | ): | |
80 | """Create a new dirstate object. |
|
87 | """Create a new dirstate object. | |
81 |
|
88 | |||
@@ -83,6 +90,7 b' class dirstate(object):' | |||||
83 | dirstate file; root is the root of the directory tracked by |
|
90 | dirstate file; root is the root of the directory tracked by | |
84 | the dirstate. |
|
91 | the dirstate. | |
85 | """ |
|
92 | """ | |
|
93 | self._use_dirstate_v2 = use_dirstate_v2 | |||
86 | self._nodeconstants = nodeconstants |
|
94 | self._nodeconstants = nodeconstants | |
87 | self._opener = opener |
|
95 | self._opener = opener | |
88 | self._validate = validate |
|
96 | self._validate = validate | |
@@ -141,7 +149,11 b' class dirstate(object):' | |||||
141 | def _map(self): |
|
149 | def _map(self): | |
142 | """Return the dirstate contents (see documentation for dirstatemap).""" |
|
150 | """Return the dirstate contents (see documentation for dirstatemap).""" | |
143 | self._map = self._mapcls( |
|
151 | self._map = self._mapcls( | |
144 | self._ui, self._opener, self._root, self._nodeconstants |
|
152 | self._ui, | |
|
153 | self._opener, | |||
|
154 | self._root, | |||
|
155 | self._nodeconstants, | |||
|
156 | self._use_dirstate_v2, | |||
145 | ) |
|
157 | ) | |
146 | return self._map |
|
158 | return self._map | |
147 |
|
159 | |||
@@ -1435,13 +1447,16 b' class dirstatemap(object):' | |||||
1435 | denormalized form that they appear as in the dirstate. |
|
1447 | denormalized form that they appear as in the dirstate. | |
1436 | """ |
|
1448 | """ | |
1437 |
|
1449 | |||
1438 | def __init__(self, ui, opener, root, nodeconstants): |
|
1450 | def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2): | |
1439 | self._ui = ui |
|
1451 | self._ui = ui | |
1440 | self._opener = opener |
|
1452 | self._opener = opener | |
1441 | self._root = root |
|
1453 | self._root = root | |
1442 | self._filename = b'dirstate' |
|
1454 | self._filename = b'dirstate' | |
1443 | self._nodelen = 20 |
|
1455 | self._nodelen = 20 | |
1444 | self._nodeconstants = nodeconstants |
|
1456 | self._nodeconstants = nodeconstants | |
|
1457 | assert ( | |||
|
1458 | not use_dirstate_v2 | |||
|
1459 | ), "should have detected unsupported requirement" | |||
1445 |
|
1460 | |||
1446 | self._parents = None |
|
1461 | self._parents = None | |
1447 | self._dirtyparents = False |
|
1462 | self._dirtyparents = False | |
@@ -1746,13 +1761,14 b' class dirstatemap(object):' | |||||
1746 | if rustmod is not None: |
|
1761 | if rustmod is not None: | |
1747 |
|
1762 | |||
1748 | class dirstatemap(object): |
|
1763 | class dirstatemap(object): | |
1749 | def __init__(self, ui, opener, root, nodeconstants): |
|
1764 | def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2): | |
|
1765 | self._use_dirstate_v2 = use_dirstate_v2 | |||
1750 | self._nodeconstants = nodeconstants |
|
1766 | self._nodeconstants = nodeconstants | |
1751 | self._ui = ui |
|
1767 | self._ui = ui | |
1752 | self._opener = opener |
|
1768 | self._opener = opener | |
1753 | self._root = root |
|
1769 | self._root = root | |
1754 | self._filename = b'dirstate' |
|
1770 | self._filename = b'dirstate' | |
1755 | self._nodelen = 20 |
|
1771 | self._nodelen = 20 # Also update Rust code when changing this! | |
1756 | self._parents = None |
|
1772 | self._parents = None | |
1757 | self._dirtyparents = False |
|
1773 | self._dirtyparents = False | |
1758 |
|
1774 | |||
@@ -1832,9 +1848,14 b' if rustmod is not None:' | |||||
1832 |
|
1848 | |||
1833 | def parents(self): |
|
1849 | def parents(self): | |
1834 | if not self._parents: |
|
1850 | if not self._parents: | |
|
1851 | if self._use_dirstate_v2: | |||
|
1852 | offset = len(rustmod.V2_FORMAT_MARKER) | |||
|
1853 | else: | |||
|
1854 | offset = 0 | |||
|
1855 | read_len = offset + self._nodelen * 2 | |||
1835 | try: |
|
1856 | try: | |
1836 | fp = self._opendirstatefile() |
|
1857 | fp = self._opendirstatefile() | |
1837 |
st = fp.read( |
|
1858 | st = fp.read(read_len) | |
1838 | fp.close() |
|
1859 | fp.close() | |
1839 | except IOError as err: |
|
1860 | except IOError as err: | |
1840 | if err.errno != errno.ENOENT: |
|
1861 | if err.errno != errno.ENOENT: | |
@@ -1843,7 +1864,8 b' if rustmod is not None:' | |||||
1843 | st = b'' |
|
1864 | st = b'' | |
1844 |
|
1865 | |||
1845 | l = len(st) |
|
1866 | l = len(st) | |
1846 |
if l == |
|
1867 | if l == read_len: | |
|
1868 | st = st[offset:] | |||
1847 | self._parents = ( |
|
1869 | self._parents = ( | |
1848 | st[: self._nodelen], |
|
1870 | st[: self._nodelen], | |
1849 | st[self._nodelen : 2 * self._nodelen], |
|
1871 | st[self._nodelen : 2 * self._nodelen], | |
@@ -1887,7 +1909,7 b' if rustmod is not None:' | |||||
1887 | False, |
|
1909 | False, | |
1888 | ) |
|
1910 | ) | |
1889 | self._rustmap, parents = rustmod.DirstateMap.new( |
|
1911 | self._rustmap, parents = rustmod.DirstateMap.new( | |
1890 | use_dirstate_tree, st |
|
1912 | use_dirstate_tree, self._use_dirstate_v2, st | |
1891 | ) |
|
1913 | ) | |
1892 |
|
1914 | |||
1893 | if parents and not self._dirtyparents: |
|
1915 | if parents and not self._dirtyparents: | |
@@ -1900,7 +1922,10 b' if rustmod is not None:' | |||||
1900 |
|
1922 | |||
1901 | def write(self, st, now): |
|
1923 | def write(self, st, now): | |
1902 | parents = self.parents() |
|
1924 | parents = self.parents() | |
1903 | st.write(self._rustmap.write(parents[0], parents[1], now)) |
|
1925 | packed = self._rustmap.write( | |
|
1926 | self._use_dirstate_v2, parents[0], parents[1], now | |||
|
1927 | ) | |||
|
1928 | st.write(packed) | |||
1904 | st.close() |
|
1929 | st.close() | |
1905 | self._dirtyparents = False |
|
1930 | self._dirtyparents = False | |
1906 |
|
1931 |
@@ -6,7 +6,15 b' from . import util as interfaceutil' | |||||
6 |
|
6 | |||
7 |
|
7 | |||
8 | class idirstate(interfaceutil.Interface): |
|
8 | class idirstate(interfaceutil.Interface): | |
9 | def __init__(opener, ui, root, validate, sparsematchfn, nodeconstants): |
|
9 | def __init__( | |
|
10 | opener, | |||
|
11 | ui, | |||
|
12 | root, | |||
|
13 | validate, | |||
|
14 | sparsematchfn, | |||
|
15 | nodeconstants, | |||
|
16 | use_dirstate_v2, | |||
|
17 | ): | |||
10 | """Create a new dirstate object. |
|
18 | """Create a new dirstate object. | |
11 |
|
19 | |||
12 | opener is an open()-like callable that can be used to open the |
|
20 | opener is an open()-like callable that can be used to open the |
@@ -1690,6 +1690,8 b' class localrepository(object):' | |||||
1690 | def _makedirstate(self): |
|
1690 | def _makedirstate(self): | |
1691 | """Extension point for wrapping the dirstate per-repo.""" |
|
1691 | """Extension point for wrapping the dirstate per-repo.""" | |
1692 | sparsematchfn = lambda: sparse.matcher(self) |
|
1692 | sparsematchfn = lambda: sparse.matcher(self) | |
|
1693 | v2_req = requirementsmod.DIRSTATE_V2_REQUIREMENT | |||
|
1694 | use_dirstate_v2 = v2_req in self.requirements | |||
1693 |
|
1695 | |||
1694 | return dirstate.dirstate( |
|
1696 | return dirstate.dirstate( | |
1695 | self.vfs, |
|
1697 | self.vfs, | |
@@ -1698,6 +1700,7 b' class localrepository(object):' | |||||
1698 | self._dirstatevalidate, |
|
1700 | self._dirstatevalidate, | |
1699 | sparsematchfn, |
|
1701 | sparsematchfn, | |
1700 | self.nodeconstants, |
|
1702 | self.nodeconstants, | |
|
1703 | use_dirstate_v2, | |||
1701 | ) |
|
1704 | ) | |
1702 |
|
1705 | |||
1703 | def _dirstatevalidate(self, node): |
|
1706 | def _dirstatevalidate(self, node): |
@@ -1,4 +1,5 b'' | |||||
1 | pub mod dirstate_map; |
|
1 | pub mod dirstate_map; | |
2 | pub mod dispatch; |
|
2 | pub mod dispatch; | |
|
3 | pub mod on_disk; | |||
3 | pub mod path_with_basename; |
|
4 | pub mod path_with_basename; | |
4 | mod status; |
|
5 | mod status; |
@@ -4,14 +4,17 b' use std::borrow::Cow;' | |||||
4 | use std::convert::TryInto; |
|
4 | use std::convert::TryInto; | |
5 | use std::path::PathBuf; |
|
5 | use std::path::PathBuf; | |
6 |
|
6 | |||
|
7 | use super::on_disk::V2_FORMAT_MARKER; | |||
7 | use super::path_with_basename::WithBasename; |
|
8 | use super::path_with_basename::WithBasename; | |
8 | use crate::dirstate::parsers::clear_ambiguous_mtime; |
|
9 | use crate::dirstate::parsers::clear_ambiguous_mtime; | |
9 | use crate::dirstate::parsers::pack_entry; |
|
10 | use crate::dirstate::parsers::pack_entry; | |
10 | use crate::dirstate::parsers::packed_entry_size; |
|
11 | use crate::dirstate::parsers::packed_entry_size; | |
11 | use crate::dirstate::parsers::parse_dirstate_entries; |
|
12 | use crate::dirstate::parsers::parse_dirstate_entries; | |
12 | use crate::dirstate::parsers::Timestamp; |
|
13 | use crate::dirstate::parsers::Timestamp; | |
|
14 | use crate::errors::HgError; | |||
13 | use crate::matchers::Matcher; |
|
15 | use crate::matchers::Matcher; | |
14 | use crate::utils::hg_path::{HgPath, HgPathBuf}; |
|
16 | use crate::utils::hg_path::{HgPath, HgPathBuf}; | |
|
17 | use crate::utils::SliceExt; | |||
15 | use crate::CopyMapIter; |
|
18 | use crate::CopyMapIter; | |
16 | use crate::DirstateEntry; |
|
19 | use crate::DirstateEntry; | |
17 | use crate::DirstateError; |
|
20 | use crate::DirstateError; | |
@@ -75,7 +78,24 b" type NodeDataMut<'tree, 'on_disk> = (" | |||||
75 | ); |
|
78 | ); | |
76 |
|
79 | |||
77 | impl<'on_disk> DirstateMap<'on_disk> { |
|
80 | impl<'on_disk> DirstateMap<'on_disk> { | |
78 | pub fn new( |
|
81 | #[timed] | |
|
82 | pub fn new_v2( | |||
|
83 | on_disk: &'on_disk [u8], | |||
|
84 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { | |||
|
85 | if let Some(rest) = on_disk.drop_prefix(V2_FORMAT_MARKER) { | |||
|
86 | Self::new_v1(rest) | |||
|
87 | } else if on_disk.is_empty() { | |||
|
88 | Self::new_v1(on_disk) | |||
|
89 | } else { | |||
|
90 | return Err(HgError::corrupted( | |||
|
91 | "missing dirstate-v2 magic number", | |||
|
92 | ) | |||
|
93 | .into()); | |||
|
94 | } | |||
|
95 | } | |||
|
96 | ||||
|
97 | #[timed] | |||
|
98 | pub fn new_v1( | |||
79 | on_disk: &'on_disk [u8], |
|
99 | on_disk: &'on_disk [u8], | |
80 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
|
100 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { | |
81 | let mut map = Self { |
|
101 | let mut map = Self { | |
@@ -84,23 +104,16 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||||
84 | nodes_with_entry_count: 0, |
|
104 | nodes_with_entry_count: 0, | |
85 | nodes_with_copy_source_count: 0, |
|
105 | nodes_with_copy_source_count: 0, | |
86 | }; |
|
106 | }; | |
87 | let parents = map.read()?; |
|
107 | if map.on_disk.is_empty() { | |
88 |
Ok((map, |
|
108 | return Ok((map, None)); | |
89 | } |
|
|||
90 |
|
||||
91 | /// Should only be called in `new` |
|
|||
92 | #[timed] |
|
|||
93 | fn read(&mut self) -> Result<Option<DirstateParents>, DirstateError> { |
|
|||
94 | if self.on_disk.is_empty() { |
|
|||
95 | return Ok(None); |
|
|||
96 | } |
|
109 | } | |
97 |
|
110 | |||
98 | let parents = parse_dirstate_entries( |
|
111 | let parents = parse_dirstate_entries( | |
99 |
|
|
112 | map.on_disk, | |
100 | |path, entry, copy_source| { |
|
113 | |path, entry, copy_source| { | |
101 | let tracked = entry.state.is_tracked(); |
|
114 | let tracked = entry.state.is_tracked(); | |
102 | let node = Self::get_or_insert_node( |
|
115 | let node = Self::get_or_insert_node( | |
103 |
&mut |
|
116 | &mut map.root, | |
104 | path, |
|
117 | path, | |
105 | WithBasename::to_cow_borrowed, |
|
118 | WithBasename::to_cow_borrowed, | |
106 | |ancestor| { |
|
119 | |ancestor| { | |
@@ -119,14 +132,15 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||||
119 | ); |
|
132 | ); | |
120 | node.entry = Some(*entry); |
|
133 | node.entry = Some(*entry); | |
121 | node.copy_source = copy_source.map(Cow::Borrowed); |
|
134 | node.copy_source = copy_source.map(Cow::Borrowed); | |
122 |
|
|
135 | map.nodes_with_entry_count += 1; | |
123 | if copy_source.is_some() { |
|
136 | if copy_source.is_some() { | |
124 |
|
|
137 | map.nodes_with_copy_source_count += 1 | |
125 | } |
|
138 | } | |
126 | }, |
|
139 | }, | |
127 | )?; |
|
140 | )?; | |
|
141 | let parents = Some(parents.clone()); | |||
128 |
|
142 | |||
129 |
Ok( |
|
143 | Ok((map, parents)) | |
130 | } |
|
144 | } | |
131 |
|
145 | |||
132 | fn get_node(&self, path: &HgPath) -> Option<&Node> { |
|
146 | fn get_node(&self, path: &HgPath) -> Option<&Node> { | |
@@ -498,7 +512,8 b" impl<'on_disk> super::dispatch::Dirstate" | |||||
498 | } |
|
512 | } | |
499 | } |
|
513 | } | |
500 |
|
514 | |||
501 | fn pack( |
|
515 | #[timed] | |
|
516 | fn pack_v1( | |||
502 | &mut self, |
|
517 | &mut self, | |
503 | parents: DirstateParents, |
|
518 | parents: DirstateParents, | |
504 | now: Timestamp, |
|
519 | now: Timestamp, | |
@@ -533,6 +548,18 b" impl<'on_disk> super::dispatch::Dirstate" | |||||
533 | Ok(packed) |
|
548 | Ok(packed) | |
534 | } |
|
549 | } | |
535 |
|
550 | |||
|
551 | #[timed] | |||
|
552 | fn pack_v2( | |||
|
553 | &mut self, | |||
|
554 | parents: DirstateParents, | |||
|
555 | now: Timestamp, | |||
|
556 | ) -> Result<Vec<u8>, DirstateError> { | |||
|
557 | // Inefficient but temporary | |||
|
558 | let mut v2 = V2_FORMAT_MARKER.to_vec(); | |||
|
559 | v2.append(&mut self.pack_v1(parents, now)?); | |||
|
560 | Ok(v2) | |||
|
561 | } | |||
|
562 | ||||
536 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { |
|
563 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { | |
537 | // Do nothing, this `DirstateMap` does not a separate `all_dirs` that |
|
564 | // Do nothing, this `DirstateMap` does not a separate `all_dirs` that | |
538 | // needs to be recomputed |
|
565 | // needs to be recomputed |
@@ -73,7 +73,13 b' pub trait DirstateMapMethods {' | |||||
73 | directory: &HgPath, |
|
73 | directory: &HgPath, | |
74 | ) -> Result<bool, DirstateMapError>; |
|
74 | ) -> Result<bool, DirstateMapError>; | |
75 |
|
75 | |||
76 | fn pack( |
|
76 | fn pack_v1( | |
|
77 | &mut self, | |||
|
78 | parents: DirstateParents, | |||
|
79 | now: Timestamp, | |||
|
80 | ) -> Result<Vec<u8>, DirstateError>; | |||
|
81 | ||||
|
82 | fn pack_v2( | |||
77 | &mut self, |
|
83 | &mut self, | |
78 | parents: DirstateParents, |
|
84 | parents: DirstateParents, | |
79 | now: Timestamp, |
|
85 | now: Timestamp, | |
@@ -211,7 +217,7 b' impl DirstateMapMethods for DirstateMap ' | |||||
211 | self.has_dir(directory) |
|
217 | self.has_dir(directory) | |
212 | } |
|
218 | } | |
213 |
|
219 | |||
214 | fn pack( |
|
220 | fn pack_v1( | |
215 | &mut self, |
|
221 | &mut self, | |
216 | parents: DirstateParents, |
|
222 | parents: DirstateParents, | |
217 | now: Timestamp, |
|
223 | now: Timestamp, | |
@@ -219,6 +225,16 b' impl DirstateMapMethods for DirstateMap ' | |||||
219 | self.pack(parents, now) |
|
225 | self.pack(parents, now) | |
220 | } |
|
226 | } | |
221 |
|
227 | |||
|
228 | fn pack_v2( | |||
|
229 | &mut self, | |||
|
230 | _parents: DirstateParents, | |||
|
231 | _now: Timestamp, | |||
|
232 | ) -> Result<Vec<u8>, DirstateError> { | |||
|
233 | panic!( | |||
|
234 | "should have used dirstate_tree::DirstateMap to use the v2 format" | |||
|
235 | ) | |||
|
236 | } | |||
|
237 | ||||
222 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { |
|
238 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { | |
223 | self.set_all_dirs() |
|
239 | self.set_all_dirs() | |
224 | } |
|
240 | } |
@@ -26,6 +26,7 b' use cpython::{' | |||||
26 | exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, |
|
26 | exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult, | |
27 | PySequence, Python, |
|
27 | PySequence, Python, | |
28 | }; |
|
28 | }; | |
|
29 | use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER; | |||
29 | use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap}; |
|
30 | use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap}; | |
30 | use libc::{c_char, c_int}; |
|
31 | use libc::{c_char, c_int}; | |
31 | use std::convert::TryFrom; |
|
32 | use std::convert::TryFrom; | |
@@ -117,6 +118,7 b' pub fn init_module(py: Python, package: ' | |||||
117 | )?; |
|
118 | )?; | |
118 | m.add_class::<Dirs>(py)?; |
|
119 | m.add_class::<Dirs>(py)?; | |
119 | m.add_class::<DirstateMap>(py)?; |
|
120 | m.add_class::<DirstateMap>(py)?; | |
|
121 | m.add(py, "V2_FORMAT_MARKER", PyBytes::new(py, V2_FORMAT_MARKER))?; | |||
120 | m.add( |
|
122 | m.add( | |
121 | py, |
|
123 | py, | |
122 | "status", |
|
124 | "status", |
@@ -55,13 +55,17 b' py_class!(pub class DirstateMap |py| {' | |||||
55 |
|
55 | |||
56 | /// Returns a `(dirstate_map, parents)` tuple |
|
56 | /// Returns a `(dirstate_map, parents)` tuple | |
57 | @staticmethod |
|
57 | @staticmethod | |
58 | def new(use_dirstate_tree: bool, on_disk: PyBytes) -> PyResult<PyObject> { |
|
58 | def new( | |
59 | let dirstate_error = |_: DirstateError| { |
|
59 | use_dirstate_tree: bool, | |
60 | PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()) |
|
60 | use_dirstate_v2: bool, | |
|
61 | on_disk: PyBytes, | |||
|
62 | ) -> PyResult<PyObject> { | |||
|
63 | let dirstate_error = |e: DirstateError| { | |||
|
64 | PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e)) | |||
61 | }; |
|
65 | }; | |
62 | let (inner, parents) = if use_dirstate_tree { |
|
66 | let (inner, parents) = if use_dirstate_tree || use_dirstate_v2 { | |
63 | let (map, parents) = |
|
67 | let (map, parents) = | |
64 | OwningDirstateMap::new(py, on_disk) |
|
68 | OwningDirstateMap::new(py, on_disk, use_dirstate_v2) | |
65 | .map_err(dirstate_error)?; |
|
69 | .map_err(dirstate_error)?; | |
66 | (Box::new(map) as _, parents) |
|
70 | (Box::new(map) as _, parents) | |
67 | } else { |
|
71 | } else { | |
@@ -288,6 +292,7 b' py_class!(pub class DirstateMap |py| {' | |||||
288 |
|
292 | |||
289 | def write( |
|
293 | def write( | |
290 | &self, |
|
294 | &self, | |
|
295 | use_dirstate_v2: bool, | |||
291 | p1: PyObject, |
|
296 | p1: PyObject, | |
292 | p2: PyObject, |
|
297 | p2: PyObject, | |
293 | now: PyObject |
|
298 | now: PyObject | |
@@ -298,7 +303,13 b' py_class!(pub class DirstateMap |py| {' | |||||
298 | p2: extract_node_id(py, &p2)?, |
|
303 | p2: extract_node_id(py, &p2)?, | |
299 | }; |
|
304 | }; | |
300 |
|
305 | |||
301 |
|
|
306 | let mut inner = self.inner(py).borrow_mut(); | |
|
307 | let result = if use_dirstate_v2 { | |||
|
308 | inner.pack_v2(parents, now) | |||
|
309 | } else { | |||
|
310 | inner.pack_v1(parents, now) | |||
|
311 | }; | |||
|
312 | match result { | |||
302 | Ok(packed) => Ok(PyBytes::new(py, &packed)), |
|
313 | Ok(packed) => Ok(PyBytes::new(py, &packed)), | |
303 | Err(_) => Err(PyErr::new::<exc::OSError, _>( |
|
314 | Err(_) => Err(PyErr::new::<exc::OSError, _>( | |
304 | py, |
|
315 | py, |
@@ -101,12 +101,20 b' impl DirstateMapMethods for OwningDirsta' | |||||
101 | self.get_mut().has_dir(directory) |
|
101 | self.get_mut().has_dir(directory) | |
102 | } |
|
102 | } | |
103 |
|
103 | |||
104 | fn pack( |
|
104 | fn pack_v1( | |
105 | &mut self, |
|
105 | &mut self, | |
106 | parents: DirstateParents, |
|
106 | parents: DirstateParents, | |
107 | now: Timestamp, |
|
107 | now: Timestamp, | |
108 | ) -> Result<Vec<u8>, DirstateError> { |
|
108 | ) -> Result<Vec<u8>, DirstateError> { | |
109 | self.get_mut().pack(parents, now) |
|
109 | self.get_mut().pack_v1(parents, now) | |
|
110 | } | |||
|
111 | ||||
|
112 | fn pack_v2( | |||
|
113 | &mut self, | |||
|
114 | parents: DirstateParents, | |||
|
115 | now: Timestamp, | |||
|
116 | ) -> Result<Vec<u8>, DirstateError> { | |||
|
117 | self.get_mut().pack_v2(parents, now) | |||
110 | } |
|
118 | } | |
111 |
|
119 | |||
112 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { |
|
120 | fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { |
@@ -31,9 +31,14 b' impl OwningDirstateMap {' | |||||
31 | pub fn new( |
|
31 | pub fn new( | |
32 | py: Python, |
|
32 | py: Python, | |
33 | on_disk: PyBytes, |
|
33 | on_disk: PyBytes, | |
|
34 | use_dirstate_v2: bool, | |||
34 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
|
35 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { | |
35 | let bytes: &'_ [u8] = on_disk.data(py); |
|
36 | let bytes: &'_ [u8] = on_disk.data(py); | |
36 |
let (map, parents) = |
|
37 | let (map, parents) = if use_dirstate_v2 { | |
|
38 | DirstateMap::new_v2(bytes)? | |||
|
39 | } else { | |||
|
40 | DirstateMap::new_v1(bytes)? | |||
|
41 | }; | |||
37 |
|
42 | |||
38 | // Like in `bytes` above, this `'_` lifetime parameter borrows from |
|
43 | // Like in `bytes` above, this `'_` lifetime parameter borrows from | |
39 | // the bytes buffer owned by `on_disk`. |
|
44 | // the bytes buffer owned by `on_disk`. |
General Comments 0
You need to be logged in to leave comments.
Login now