From f6a516ff6d78b6b3f7f0782c36c412abb1e496d9 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Mon, 23 May 2022 23:58:03 -0700 Subject: [PATCH] working_copy: record expected written size, not actual size, on checkout When we have just written a file to disk on checkout, let's record the size we expected instead of what we got from `fstat()`. This should address a race where the file was modified between the time we wrote it and the time we requested its stat. I just happened to notice this while going through the code; it seems very unlikely to be noticed in practice. --- lib/src/working_copy.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/src/working_copy.rs b/lib/src/working_copy.rs index 1fcb1c95b..ad4ec7f7f 100644 --- a/lib/src/working_copy.rs +++ b/lib/src/working_copy.rs @@ -608,10 +608,11 @@ impl TreeState { err, })?; let mut contents = self.store.read_file(path, id)?; - std::io::copy(&mut contents, &mut file).map_err(|err| CheckoutError::IoError { - message: format!("Failed to write file {}", disk_path.display()), - err, - })?; + let size = + std::io::copy(&mut contents, &mut file).map_err(|err| CheckoutError::IoError { + message: format!("Failed to write file {}", disk_path.display()), + err, + })?; self.set_executable(disk_path, executable)?; // Read the file state from the file descriptor. That way, know that the file // exists and is of the expected type, and the stat information is most likely @@ -625,6 +626,7 @@ impl TreeState { // for Windows, since the executable bit is not reflected in the file system // there. file_state.mark_executable(executable); + file_state.size = size; Ok(file_state) }