##// END OF EJS Templates
rust-dirstate-v2: don't write dirstate if data file has changed...
Raphaël Gomès -
r51139:07d030b3 stable
parent child Browse files
Show More
@@ -34,7 +34,6 b' pub struct Repo {'
34 requirements: HashSet<String>,
34 requirements: HashSet<String>,
35 config: Config,
35 config: Config,
36 dirstate_parents: LazyCell<DirstateParents>,
36 dirstate_parents: LazyCell<DirstateParents>,
37 dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>>,
38 dirstate_map: LazyCell<OwningDirstateMap>,
37 dirstate_map: LazyCell<OwningDirstateMap>,
39 changelog: LazyCell<Changelog>,
38 changelog: LazyCell<Changelog>,
40 manifestlog: LazyCell<Manifestlog>,
39 manifestlog: LazyCell<Manifestlog>,
@@ -187,7 +186,6 b' impl Repo {'
187 dot_hg,
186 dot_hg,
188 config: repo_config,
187 config: repo_config,
189 dirstate_parents: LazyCell::new(),
188 dirstate_parents: LazyCell::new(),
190 dirstate_data_file_uuid: LazyCell::new(),
191 dirstate_map: LazyCell::new(),
189 dirstate_map: LazyCell::new(),
192 changelog: LazyCell::new(),
190 changelog: LazyCell::new(),
193 manifestlog: LazyCell::new(),
191 manifestlog: LazyCell::new(),
@@ -270,15 +268,10 b' impl Repo {'
270 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
268 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> {
271 let dirstate = self.dirstate_file_contents()?;
269 let dirstate = self.dirstate_file_contents()?;
272 let parents = if dirstate.is_empty() {
270 let parents = if dirstate.is_empty() {
273 if self.has_dirstate_v2() {
274 self.dirstate_data_file_uuid.set(None);
275 }
276 DirstateParents::NULL
271 DirstateParents::NULL
277 } else if self.has_dirstate_v2() {
272 } else if self.has_dirstate_v2() {
278 let docket =
273 let docket =
279 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
274 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
280 self.dirstate_data_file_uuid
281 .set(Some(docket.uuid.to_owned()));
282 docket.parents()
275 docket.parents()
283 } else {
276 } else {
284 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
277 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?
@@ -288,9 +281,13 b' impl Repo {'
288 Ok(parents)
281 Ok(parents)
289 }
282 }
290
283
291 fn read_dirstate_data_file_uuid(
284 /// Returns the information read from the dirstate docket necessary to
285 /// check if the data file has been updated/deleted by another process
286 /// since we last read the dirstate.
287 /// Namely, the data file uuid and the data size.
288 fn get_dirstate_data_file_integrity(
292 &self,
289 &self,
293 ) -> Result<Option<Vec<u8>>, HgError> {
290 ) -> Result<(Option<Vec<u8>>, usize), HgError> {
294 assert!(
291 assert!(
295 self.has_dirstate_v2(),
292 self.has_dirstate_v2(),
296 "accessing dirstate data file ID without dirstate-v2"
293 "accessing dirstate data file ID without dirstate-v2"
@@ -298,12 +295,12 b' impl Repo {'
298 let dirstate = self.dirstate_file_contents()?;
295 let dirstate = self.dirstate_file_contents()?;
299 if dirstate.is_empty() {
296 if dirstate.is_empty() {
300 self.dirstate_parents.set(DirstateParents::NULL);
297 self.dirstate_parents.set(DirstateParents::NULL);
301 Ok(None)
298 Ok((None, 0))
302 } else {
299 } else {
303 let docket =
300 let docket =
304 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
301 crate::dirstate_tree::on_disk::read_docket(&dirstate)?;
305 self.dirstate_parents.set(docket.parents());
302 self.dirstate_parents.set(docket.parents());
306 Ok(Some(docket.uuid.to_owned()))
303 Ok((Some(docket.uuid.to_owned()), docket.data_size()))
307 }
304 }
308 }
305 }
309
306
@@ -370,7 +367,6 b' impl Repo {'
370 let dirstate_file_contents = self.dirstate_file_contents()?;
367 let dirstate_file_contents = self.dirstate_file_contents()?;
371 if dirstate_file_contents.is_empty() {
368 if dirstate_file_contents.is_empty() {
372 self.dirstate_parents.set(DirstateParents::NULL);
369 self.dirstate_parents.set(DirstateParents::NULL);
373 self.dirstate_data_file_uuid.set(None);
374 return Ok(OwningDirstateMap::new_empty(Vec::new()));
370 return Ok(OwningDirstateMap::new_empty(Vec::new()));
375 }
371 }
376 let docket = crate::dirstate_tree::on_disk::read_docket(
372 let docket = crate::dirstate_tree::on_disk::read_docket(
@@ -381,8 +377,6 b' impl Repo {'
381 "dirstate.post-docket-read-file",
377 "dirstate.post-docket-read-file",
382 );
378 );
383 self.dirstate_parents.set(docket.parents());
379 self.dirstate_parents.set(docket.parents());
384 self.dirstate_data_file_uuid
385 .set(Some(docket.uuid.to_owned()));
386 let uuid = docket.uuid.to_owned();
380 let uuid = docket.uuid.to_owned();
387 let data_size = docket.data_size();
381 let data_size = docket.data_size();
388
382
@@ -540,10 +534,27 b' impl Repo {'
540 // it’s unset
534 // it’s unset
541 let parents = self.dirstate_parents()?;
535 let parents = self.dirstate_parents()?;
542 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
536 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
543 let uuid_opt = self
537 let (uuid, data_size) = self.get_dirstate_data_file_integrity()?;
544 .dirstate_data_file_uuid
538 let uuid_changed = uuid.as_deref() != map.old_uuid();
545 .get_or_init(|| self.read_dirstate_data_file_uuid())?;
539 let data_length_changed = data_size != map.old_data_size();
546 let uuid_opt = uuid_opt.as_ref();
540
541 if uuid_changed || data_length_changed {
542 // If uuid or length changed since last disk read, don't write.
543 // This is fine because either we're in a command that doesn't
544 // write anything too important (like `hg status`), or we're in
545 // `hg add` and we're supposed to have taken the lock before
546 // reading anyway.
547 //
548 // TODO complain loudly if we've changed anything important
549 // without taking the lock.
550 // (see `hg help config.format.use-dirstate-tracked-hint`)
551 log::debug!(
552 "dirstate has changed since last read, not updating."
553 );
554 return Ok(());
555 }
556
557 let uuid_opt = map.old_uuid();
547 let write_mode = if uuid_opt.is_some() {
558 let write_mode = if uuid_opt.is_some() {
548 DirstateMapWriteMode::Auto
559 DirstateMapWriteMode::Auto
549 } else {
560 } else {
@@ -312,25 +312,6 b' do an update'
312 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
312 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
313 $ touch $TESTTMP/status-race-lock
313 $ touch $TESTTMP/status-race-lock
314 $ wait
314 $ wait
315 #if rhg dirstate-v2-append pre-some-read
316 $ hg log -GT '{node|short} {desc}\n'
317 @ 9a86dcbfb938 more files to have two commit
318 |
319 o 4f23db756b09 recreate a bunch of files to facilitate dirstate-v2 append
320
321 $ hg status
322 A dir/o
323 R dir/nested/m
324 ! dir/i
325 ! dir/j
326 ! dir/nested/h
327 ! dir2/k
328 ! dir2/l
329 ! g
330 ? dir/n
331 ? p
332 ? q
333 #else
334 $ hg log -GT '{node|short} {desc}\n'
315 $ hg log -GT '{node|short} {desc}\n'
335 o 9a86dcbfb938 more files to have two commit
316 o 9a86dcbfb938 more files to have two commit
336 |
317 |
@@ -341,7 +322,6 b' do an update'
341 ? dir/n
322 ? dir/n
342 ? p
323 ? p
343 ? q
324 ? q
344 #endif
345
325
346 The status process should return a consistent result and not crash.
326 The status process should return a consistent result and not crash.
347
327
@@ -242,12 +242,12 b' Add a file'
242 The file should in a "added" state
242 The file should in a "added" state
243
243
244 $ hg status
244 $ hg status
245 A dir/n (no-rhg !)
245 A dir/n (no-rhg dirstate-v1 !)
246 A dir/n (rhg dirstate-v2-rewrite !)
246 A dir/n (no-dirstate-v1 !)
247 A dir/n (missing-correct-output rhg dirstate-v1 !)
247 A dir/n (missing-correct-output rhg dirstate-v1 !)
248 A dir/o
248 A dir/o
249 R dir/nested/m
249 R dir/nested/m
250 ? dir/n (known-bad-output rhg no-dirstate-v2-rewrite !)
250 ? dir/n (known-bad-output rhg dirstate-v1 !)
251 ? p
251 ? p
252 ? q
252 ? q
253
253
@@ -260,7 +260,6 b' The status process should return a consi'
260 ? p
260 ? p
261 ? q
261 ? q
262 $ cat $TESTTMP/status-race-lock.log
262 $ cat $TESTTMP/status-race-lock.log
263 abort: when writing $TESTTMP/race-with-add/.hg/dirstate.*: $ENOENT$ (glob) (known-bad-output rhg dirstate-v2-rewrite !)
264
263
265 final cleanup
264 final cleanup
266
265
@@ -291,20 +290,7 b' Add a file and force the data file rewri'
291 The parent must change and the status should be clean
290 The parent must change and the status should be clean
292
291
293 # XXX rhg misbehaves here
292 # XXX rhg misbehaves here
294 #if no-rhg
293 #if rhg dirstate-v1
295 $ hg summary
296 parent: 2:2e3b442a2fd4 tip
297 created-during-status
298 branch: default
299 commit: 1 removed, 3 unknown
300 update: (current)
301 phases: 3 draft
302 $ hg status
303 R dir/nested/m
304 ? dir/n
305 ? p
306 ? q
307 #else
308 $ hg summary
294 $ hg summary
309 parent: 1:c349430a1631
295 parent: 1:c349430a1631
310 more files to have two commits
296 more files to have two commits
@@ -318,6 +304,19 b' The parent must change and the status sh'
318 ? dir/n
304 ? dir/n
319 ? p
305 ? p
320 ? q
306 ? q
307 #else
308 $ hg summary
309 parent: 2:2e3b442a2fd4 tip
310 created-during-status
311 branch: default
312 commit: 1 removed, 3 unknown
313 update: (current)
314 phases: 3 draft
315 $ hg status
316 R dir/nested/m
317 ? dir/n
318 ? p
319 ? q
321 #endif
320 #endif
322
321
323 The status process should return a consistent result and not crash.
322 The status process should return a consistent result and not crash.
@@ -329,7 +328,6 b' The status process should return a consi'
329 ? p
328 ? p
330 ? q
329 ? q
331 $ cat $TESTTMP/status-race-lock.log
330 $ cat $TESTTMP/status-race-lock.log
332 abort: when removing $TESTTMP/race-with-commit/.hg/dirstate.*: $ENOENT$ (glob) (known-bad-output rhg dirstate-v2-rewrite !)
333
331
334 final cleanup
332 final cleanup
335
333
@@ -418,9 +416,9 b' touch g'
418 the first update should be on disk
416 the first update should be on disk
419
417
420 $ hg debugstate --all | grep "g"
418 $ hg debugstate --all | grep "g"
419 n 644 0 2000-01-01 00:10:00 g (known-bad-output rhg dirstate-v1 !)
420 n 644 0 2000-01-01 00:25:00 g (rhg no-dirstate-v1 !)
421 n 644 0 2000-01-01 00:25:00 g (no-rhg !)
421 n 644 0 2000-01-01 00:25:00 g (no-rhg !)
422 n 644 0 2000-01-01 00:25:00 g (missing-correct-output rhg !)
423 n 644 0 2000-01-01 00:10:00 g (known-bad-output rhg !)
424
422
425 The status process should return a consistent result and not crash.
423 The status process should return a consistent result and not crash.
426
424
@@ -431,7 +429,6 b' The status process should return a consi'
431 ? p
429 ? p
432 ? q
430 ? q
433 $ cat $TESTTMP/status-race-lock.log
431 $ cat $TESTTMP/status-race-lock.log
434 abort: when removing $TESTTMP/race-with-status/.hg/dirstate.*: $ENOENT$ (glob) (known-bad-output rhg dirstate-v2-rewrite !)
435
432
436 final cleanup
433 final cleanup
437
434
General Comments 0
You need to be logged in to leave comments. Login now