Mercurial > hg
comparison rust/hg-core/src/repo.rs @ 50658:1e2c6cda2309 stable
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
It is closer to the right semantics. I added a docstring to better explain
the reasonning. In the next patch(es), I will address the underlying issue
of finding the "wrong" version of the dirstate on disk.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 05 Jun 2023 16:30:25 +0200 |
parents | a6b8b1ab9116 |
children | bf16ef96defe |
comparison
equal
deleted
inserted
replaced
50657:e77ca247b85b | 50658:1e2c6cda2309 |
---|---|
230 f: impl FnOnce() -> R, | 230 f: impl FnOnce() -> R, |
231 ) -> Result<R, LockError> { | 231 ) -> Result<R, LockError> { |
232 try_with_lock_no_wait(self.hg_vfs(), "wlock", f) | 232 try_with_lock_no_wait(self.hg_vfs(), "wlock", f) |
233 } | 233 } |
234 | 234 |
235 pub fn has_dirstate_v2(&self) -> bool { | 235 /// Whether this repo should use dirstate-v2. |
236 /// The presence of `dirstate-v2` in the requirements does not mean that | |
237 /// the on-disk dirstate is necessarily in version 2. In most cases, | |
238 /// a dirstate-v2 file will indeed be found, but in rare cases (like the | |
239 /// upgrade mechanism being cut short), the on-disk version will be a | |
240 /// v1 file. | |
241 /// Semantically, having a requirement only means that a client should be | |
242 /// able to understand the repo *if* it uses the requirement, but not that | |
243 /// the requirement is actually used. | |
244 pub fn use_dirstate_v2(&self) -> bool { | |
236 self.requirements | 245 self.requirements |
237 .contains(requirements::DIRSTATE_V2_REQUIREMENT) | 246 .contains(requirements::DIRSTATE_V2_REQUIREMENT) |
238 } | 247 } |
239 | 248 |
240 pub fn has_sparse(&self) -> bool { | 249 pub fn has_sparse(&self) -> bool { |
275 | 284 |
276 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { | 285 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { |
277 let dirstate = self.dirstate_file_contents()?; | 286 let dirstate = self.dirstate_file_contents()?; |
278 let parents = if dirstate.is_empty() { | 287 let parents = if dirstate.is_empty() { |
279 DirstateParents::NULL | 288 DirstateParents::NULL |
280 } else if self.has_dirstate_v2() { | 289 } else if self.use_dirstate_v2() { |
281 let docket = | 290 let docket = |
282 crate::dirstate_tree::on_disk::read_docket(&dirstate)?; | 291 crate::dirstate_tree::on_disk::read_docket(&dirstate)?; |
283 docket.parents() | 292 docket.parents() |
284 } else { | 293 } else { |
285 *crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? | 294 *crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? |
294 /// Namely, the inode, data file uuid and the data size. | 303 /// Namely, the inode, data file uuid and the data size. |
295 fn get_dirstate_data_file_integrity( | 304 fn get_dirstate_data_file_integrity( |
296 &self, | 305 &self, |
297 ) -> Result<DirstateMapIdentity, HgError> { | 306 ) -> Result<DirstateMapIdentity, HgError> { |
298 assert!( | 307 assert!( |
299 self.has_dirstate_v2(), | 308 self.use_dirstate_v2(), |
300 "accessing dirstate data file ID without dirstate-v2" | 309 "accessing dirstate data file ID without dirstate-v2" |
301 ); | 310 ); |
302 // Get the identity before the contents since we could have a race | 311 // Get the identity before the contents since we could have a race |
303 // between the two. Having an identity that is too old is fine, but | 312 // between the two. Having an identity that is too old is fine, but |
304 // one that is younger than the content change is bad. | 313 // one that is younger than the content change is bad. |
314 Ok((identity, Some(docket.uuid.to_owned()), docket.data_size())) | 323 Ok((identity, Some(docket.uuid.to_owned()), docket.data_size())) |
315 } | 324 } |
316 } | 325 } |
317 | 326 |
318 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { | 327 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { |
319 if self.has_dirstate_v2() { | 328 if self.use_dirstate_v2() { |
320 // The v2 dirstate is split into a docket and a data file. | 329 // The v2 dirstate is split into a docket and a data file. |
321 // Since we don't always take the `wlock` to read it | 330 // Since we don't always take the `wlock` to read it |
322 // (like in `hg status`), it is susceptible to races. | 331 // (like in `hg status`), it is susceptible to races. |
323 // A simple retry method should be enough since full rewrites | 332 // A simple retry method should be enough since full rewrites |
324 // only happen when too much garbage data is present and | 333 // only happen when too much garbage data is present and |
548 pub fn write_dirstate(&self) -> Result<(), DirstateError> { | 557 pub fn write_dirstate(&self) -> Result<(), DirstateError> { |
549 let map = self.dirstate_map()?; | 558 let map = self.dirstate_map()?; |
550 // TODO: Maintain a `DirstateMap::dirty` flag, and return early here if | 559 // TODO: Maintain a `DirstateMap::dirty` flag, and return early here if |
551 // it’s unset | 560 // it’s unset |
552 let parents = self.dirstate_parents()?; | 561 let parents = self.dirstate_parents()?; |
553 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() { | 562 let (packed_dirstate, old_uuid_to_remove) = if self.use_dirstate_v2() { |
554 let (identity, uuid, data_size) = | 563 let (identity, uuid, data_size) = |
555 self.get_dirstate_data_file_integrity()?; | 564 self.get_dirstate_data_file_integrity()?; |
556 let identity_changed = identity != map.old_identity(); | 565 let identity_changed = identity != map.old_identity(); |
557 let uuid_changed = uuid.as_deref() != map.old_uuid(); | 566 let uuid_changed = uuid.as_deref() != map.old_uuid(); |
558 let data_length_changed = data_size != map.old_data_size(); | 567 let data_length_changed = data_size != map.old_data_size(); |