##// END OF EJS Templates
dirstate-v2: Change the representation of negative directory mtime...
Simon Sapin -
r49005:a5a673ec default
parent child Browse files
Show More
@@ -443,20 +443,19 b' Node components are:'
443 443
444 444 If an untracked node `HAS_MTIME` *set*,
445 445 what follows is the modification time of a directory
446 represented with separated second and sub-second components
447 since the Unix epoch:
446 represented similarly to the C `timespec` struct:
448 447
449 448 * Offset 31:
450 The number of seconds as a signed (two’s complement) 64-bit integer.
449 The number of seconds elapsed since the Unix epoch,
450 as a signed (two’s complement) 64-bit integer.
451 451
452 452 * Offset 39:
453 The number of nanoseconds as 32-bit integer.
453 The number of nanoseconds elapsed since
454 the instant specified by the previous field alone,
455 as 32-bit integer.
454 456 Always greater than or equal to zero, and strictly less than a billion.
455 457 Increasing this component makes the modification time
456 go forward or backward in time dependening
457 on the sign of the integral seconds components.
458 (Note: this is buggy because there is no negative zero integer,
459 but will be changed soon.)
458 go forward in time regardless of the sign of the seconds component.
460 459
461 460 The presence of a directory modification time means that at some point,
462 461 this path in the working directory was observed:
@@ -126,8 +126,7 b' pub(super) struct Timestamp {'
126 126
127 127 /// In `0 .. 1_000_000_000`.
128 128 ///
129 /// This timestamp is later or earlier than `(seconds, 0)` by this many
130 /// nanoseconds, if `seconds` is non-negative or negative, respectively.
129 /// This timestamp is after `(seconds, 0)` by this many nanoseconds.
131 130 nanoseconds: U32Be,
132 131 }
133 132
@@ -446,13 +445,30 b' impl Timestamp {'
446 445
447 446 impl From<SystemTime> for Timestamp {
448 447 fn from(system_time: SystemTime) -> Self {
448 // On Unix, `SystemTime` is a wrapper for the `timespec` C struct:
449 // https://www.gnu.org/software/libc/manual/html_node/Time-Types.html#index-struct-timespec
450 // We want to effectively access its fields, but the Rust standard
451 // library does not expose them. The best we can do is:
449 452 let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) {
450 453 Ok(duration) => {
451 454 (duration.as_secs() as i64, duration.subsec_nanos())
452 455 }
453 456 Err(error) => {
457 // `system_time` is before `UNIX_EPOCH`.
458 // We need to undo this algorithm:
459 // https://github.com/rust-lang/rust/blob/6bed1f0bc3cc50c10aab26d5f94b16a00776b8a5/library/std/src/sys/unix/time.rs#L40-L41
454 460 let negative = error.duration();
455 (-(negative.as_secs() as i64), negative.subsec_nanos())
461 let negative_secs = negative.as_secs() as i64;
462 let negative_nanos = negative.subsec_nanos();
463 if negative_nanos == 0 {
464 (-negative_secs, 0)
465 } else {
466 // For example if `system_time` was 4.3 seconds before
467 // the Unix epoch we get a Duration that represents
468 // `(-4, -0.3)` but we want `(-5, +0.7)`:
469 const NSEC_PER_SEC: u32 = 1_000_000_000;
470 (-1 - negative_secs, NSEC_PER_SEC - negative_nanos)
471 }
456 472 }
457 473 };
458 474 Timestamp {
General Comments 0
You need to be logged in to leave comments. Login now