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 ( |
|
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 |
|
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