Show More
@@ -87,6 +87,10 b' impl TruncatedTimestamp {' | |||||
87 | } |
|
87 | } | |
88 | } |
|
88 | } | |
89 |
|
89 | |||
|
90 | /// Returns a `TruncatedTimestamp` for the modification time of `metadata`. | |||
|
91 | /// | |||
|
92 | /// Propagates errors from `std` on platforms where modification time | |||
|
93 | /// is not available at all. | |||
90 | pub fn for_mtime_of(metadata: &fs::Metadata) -> io::Result<Self> { |
|
94 | pub fn for_mtime_of(metadata: &fs::Metadata) -> io::Result<Self> { | |
91 | #[cfg(unix)] |
|
95 | #[cfg(unix)] | |
92 | { |
|
96 | { | |
@@ -102,13 +106,18 b' impl TruncatedTimestamp {' | |||||
102 | } |
|
106 | } | |
103 | } |
|
107 | } | |
104 |
|
108 | |||
105 | /// Returns whether this timestamp is reliable as the "mtime" of a file. |
|
109 | /// Like `for_mtime_of`, but may return `None` or a value with | |
|
110 | /// `second_ambiguous` set if the mtime is not "reliable". | |||
106 | /// |
|
111 | /// | |
107 | /// A modification time is reliable if it is older than `boundary` (or |
|
112 | /// A modification time is reliable if it is older than `boundary` (or | |
108 | /// sufficiently in the future). |
|
113 | /// sufficiently in the future). | |
109 | /// |
|
114 | /// | |
110 | /// Otherwise a concurrent modification might happens with the same mtime. |
|
115 | /// Otherwise a concurrent modification might happens with the same mtime. | |
111 | pub fn is_reliable_mtime(&self, boundary: &Self) -> bool { |
|
116 | pub fn for_reliable_mtime_of( | |
|
117 | metadata: &fs::Metadata, | |||
|
118 | boundary: &Self, | |||
|
119 | ) -> io::Result<Option<Self>> { | |||
|
120 | let mut mtime = Self::for_mtime_of(metadata)?; | |||
112 | // If the mtime of the ambiguous file is younger (or equal) to the |
|
121 | // If the mtime of the ambiguous file is younger (or equal) to the | |
113 | // starting point of the `status` walk, we cannot garantee that |
|
122 | // starting point of the `status` walk, we cannot garantee that | |
114 | // another, racy, write will not happen right after with the same mtime |
|
123 | // another, racy, write will not happen right after with the same mtime | |
@@ -118,16 +127,23 b' impl TruncatedTimestamp {' | |||||
118 | // mismatch between the current clock and previous file system |
|
127 | // mismatch between the current clock and previous file system | |
119 | // operation. So mtime more than one days in the future are considered |
|
128 | // operation. So mtime more than one days in the future are considered | |
120 | // fine. |
|
129 | // fine. | |
121 |
if |
|
130 | let reliable = if mtime.truncated_seconds == boundary.truncated_seconds | |
122 | self.nanoseconds != 0 |
|
131 | { | |
|
132 | mtime.second_ambiguous = true; | |||
|
133 | mtime.nanoseconds != 0 | |||
123 | && boundary.nanoseconds != 0 |
|
134 | && boundary.nanoseconds != 0 | |
124 |
&& |
|
135 | && mtime.nanoseconds < boundary.nanoseconds | |
125 | } else { |
|
136 | } else { | |
126 | // `truncated_seconds` is less than 2**31, |
|
137 | // `truncated_seconds` is less than 2**31, | |
127 | // so this does not overflow `u32`: |
|
138 | // so this does not overflow `u32`: | |
128 | let one_day_later = boundary.truncated_seconds + 24 * 3600; |
|
139 | let one_day_later = boundary.truncated_seconds + 24 * 3600; | |
129 |
|
|
140 | mtime.truncated_seconds < boundary.truncated_seconds | |
130 |
|| |
|
141 | || mtime.truncated_seconds > one_day_later | |
|
142 | }; | |||
|
143 | if reliable { | |||
|
144 | Ok(Some(mtime)) | |||
|
145 | } else { | |||
|
146 | Ok(None) | |||
131 | } |
|
147 | } | |
132 | } |
|
148 | } | |
133 |
|
149 |
@@ -352,9 +352,13 b' pub fn run(invocation: &crate::CliInvoca' | |||||
352 | let fs_metadata = repo |
|
352 | let fs_metadata = repo | |
353 | .working_directory_vfs() |
|
353 | .working_directory_vfs() | |
354 | .symlink_metadata(&fs_path)?; |
|
354 | .symlink_metadata(&fs_path)?; | |
355 | let mtime = TruncatedTimestamp::for_mtime_of(&fs_metadata) |
|
355 | if let Some(mtime) = | |
356 | .when_reading_file(&fs_path)?; |
|
356 | TruncatedTimestamp::for_reliable_mtime_of( | |
357 | if mtime.is_reliable_mtime(&mtime_boundary) { |
|
357 | &fs_metadata, | |
|
358 | &mtime_boundary, | |||
|
359 | ) | |||
|
360 | .when_reading_file(&fs_path)? | |||
|
361 | { | |||
358 | let mode = fs_metadata.mode(); |
|
362 | let mode = fs_metadata.mode(); | |
359 | let size = fs_metadata.len() as u32 & RANGE_MASK_31BIT; |
|
363 | let size = fs_metadata.len() as u32 & RANGE_MASK_31BIT; | |
360 | let mut entry = dmap |
|
364 | let mut entry = dmap |
General Comments 0
You need to be logged in to leave comments.
Login now