From 57aee2f21df076d3c111a80e38a5b42499c18224 Mon Sep 17 00:00:00 2001 From: Peter Waller Date: Fri, 27 Jan 2023 22:56:41 +0000 Subject: [PATCH] Wire up modes Prior to this commit, modes did nothing since they were not populated. After this commit, they are populated in the index, and that information is used to specify modes on the created files. Closes #13. --- src/repo/pack.rs | 15 +++++++++++---- src/repo/repository.rs | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/repo/pack.rs b/src/repo/pack.rs index cb57e9e..1392921 100644 --- a/src/repo/pack.rs +++ b/src/repo/pack.rs @@ -8,6 +8,7 @@ use std::{ fs::{self, Permissions}, io, io::{BufReader, Read, Write}, + os::unix::prelude::PermissionsExt, path::{Path, PathBuf}, }; use std::{fmt::Display, str::FromStr}; @@ -548,7 +549,7 @@ fn assign_to_frames( ObjectMetadata { offset: local_offset, // Replace global offset -> local offset size: entry.metadata.size, - mode: None, + mode: entry.metadata.mode, }, ); frames[frame_index].push(local_entry); @@ -662,9 +663,15 @@ fn extract_files( path_buf.clear(); path_buf.push(&output_dir); path_buf.push(&entry.path); - stats.write_time += measure_ok(|| write_object(&buf[..], &path_buf, None))? - .0 - .as_secs_f64(); + stats.write_time += measure_ok(|| { + write_object( + &buf[..], + &path_buf, + entry.metadata.mode.map(Permissions::from_mode), + ) + })? + .0 + .as_secs_f64(); } Ok(()) diff --git a/src/repo/repository.rs b/src/repo/repository.rs index 2f726a5..927bac8 100644 --- a/src/repo/repository.rs +++ b/src/repo/repository.rs @@ -5,8 +5,10 @@ use super::{constants::*, pack::IdError}; use std::{ collections::{HashMap, HashSet}, - fs, io, + fs::{self, File, Permissions}, + io, io::{Read, Write}, + os::unix::prelude::PermissionsExt, path::{Path, PathBuf}, str::FromStr, sync::atomic::{AtomicBool, Ordering}, @@ -581,7 +583,11 @@ impl Repository { let threads = num_cpus::get(); let pack_entries = run_in_parallel(threads, files.into_iter(), |file_path| { - let buf = fs::read(&file_path)?; + let mut fd = File::open(&file_path)?; + let mut buf = vec![]; + fd.read_to_end(&mut buf)?; + let mode = fd.metadata()?.permissions().mode(); + drop(fd); let mut checksum = [0u8; 20]; let mut hasher = Sha1::new(); hasher.input(&buf); @@ -594,7 +600,7 @@ impl Repository { ObjectMetadata { offset: LOOSE_OBJECT_OFFSET, size: buf.len() as u64, - mode: None, + mode: Some(mode), }, )) }) @@ -1020,6 +1026,12 @@ impl Repository { ), ) })?; + + entry + .metadata + .mode + .map(Permissions::from_mode) + .map_or(Ok(()), |p| fs::set_permissions(&dest_path, p))?; } if verify {