##// 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 If an untracked node `HAS_MTIME` *set*,
444 If an untracked node `HAS_MTIME` *set*,
445 what follows is the modification time of a directory
445 what follows is the modification time of a directory
446 represented with separated second and sub-second components
446 represented similarly to the C `timespec` struct:
447 since the Unix epoch:
448
447
449 * Offset 31:
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 * Offset 39:
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 Always greater than or equal to zero, and strictly less than a billion.
456 Always greater than or equal to zero, and strictly less than a billion.
455 Increasing this component makes the modification time
457 Increasing this component makes the modification time
456 go forward or backward in time dependening
458 go forward in time regardless of the sign of the seconds component.
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.)
460
459
461 The presence of a directory modification time means that at some point,
460 The presence of a directory modification time means that at some point,
462 this path in the working directory was observed:
461 this path in the working directory was observed:
@@ -126,8 +126,7 b' pub(super) struct Timestamp {'
126
126
127 /// In `0 .. 1_000_000_000`.
127 /// In `0 .. 1_000_000_000`.
128 ///
128 ///
129 /// This timestamp is later or earlier than `(seconds, 0)` by this many
129 /// This timestamp is after `(seconds, 0)` by this many nanoseconds.
130 /// nanoseconds, if `seconds` is non-negative or negative, respectively.
131 nanoseconds: U32Be,
130 nanoseconds: U32Be,
132 }
131 }
133
132
@@ -446,13 +445,30 b' impl Timestamp {'
446
445
447 impl From<SystemTime> for Timestamp {
446 impl From<SystemTime> for Timestamp {
448 fn from(system_time: SystemTime) -> Self {
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 let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) {
452 let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) {
450 Ok(duration) => {
453 Ok(duration) => {
451 (duration.as_secs() as i64, duration.subsec_nanos())
454 (duration.as_secs() as i64, duration.subsec_nanos())
452 }
455 }
453 Err(error) => {
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 let negative = error.duration();
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 Timestamp {
474 Timestamp {
General Comments 0
You need to be logged in to leave comments. Login now