Skip to content

Commit 082bd7d

Browse files
committed
refactor
- be sure we don't truncate unnecessarily.
1 parent 01c8fd8 commit 082bd7d

2 files changed

Lines changed: 16 additions & 8 deletions

File tree

gix-worktree-state/src/checkout/chunk.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,12 +224,12 @@ where
224224
inner: std::io::BufWriter::with_capacity(512 * 1024, file),
225225
progress: bytes,
226226
};
227-
let num_bytes = std::io::copy(&mut read, &mut write)?;
228-
bytes_written += num_bytes;
227+
let actual_bytes = std::io::copy(&mut read, &mut write)?;
228+
bytes_written += actual_bytes;
229229
entry::finalize_entry(
230230
delayed.entry,
231-
num_bytes as usize,
232231
write.inner.into_inner().map_err(std::io::IntoInnerError::into_error)?,
232+
actual_bytes,
233233
set_executable_after_creation,
234234
)?;
235235
delayed_files += 1;

gix-worktree-state/src/checkout/entry.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ where
135135
};
136136

137137
// For possibly existing, overwritten files, we must change the file mode explicitly.
138-
finalize_entry(entry, num_bytes, file, set_executable_after_creation)?;
138+
finalize_entry(entry, file, num_bytes as u64, set_executable_after_creation)?;
139139
num_bytes
140140
}
141141
gix_index::entry::Mode::SYMLINK => {
@@ -276,23 +276,31 @@ pub(crate) fn open_file(
276276
}
277277

278278
/// Close `file` and store its stats in `entry`, possibly setting `file` executable.
279+
///
280+
/// `desired_bytes` is the amount of bytes Git thinks the file should have after writing.
279281
pub(crate) fn finalize_entry(
280282
entry: &mut gix_index::Entry,
281-
num_bytes: usize,
282283
file: std::fs::File,
284+
desired_bytes: u64,
283285
#[cfg_attr(windows, allow(unused_variables))] set_executable_after_creation: bool,
284286
) -> Result<(), crate::checkout::Error> {
285287
// For possibly existing, overwritten files, we must change the file mode explicitly.
286288
#[cfg(unix)]
287289
if set_executable_after_creation {
288290
set_executable(&file)?;
289291
}
290-
if let Ok(num_bytes) = num_bytes.try_into() {
291-
file.set_len(num_bytes)?;
292+
293+
let md = &gix_index::fs::Metadata::from_file(&file)?;
294+
// A last sanity check: if the file wasn't truncated upon opening, which is good in case something
295+
// goes wrong during writing, not everything is lost, then after writing the file is smaller than it was
296+
// before, it needs truncation. We do that here.
297+
let needs_truncation = md.len() > desired_bytes;
298+
if needs_truncation {
299+
file.set_len(desired_bytes)?;
292300
}
293301
// NOTE: we don't call `file.sync_all()` here knowing that some filesystems don't handle this well.
294302
// revisit this once there is a bug to fix.
295-
entry.stat = Stat::from_fs(&gix_index::fs::Metadata::from_file(&file)?)?;
303+
entry.stat = Stat::from_fs(md)?;
296304
file.close()?;
297305
Ok(())
298306
}

0 commit comments

Comments
 (0)