Skip to content

Commit 895d475

Browse files
committed
allow writing empty files during checkout but also query the odb (#301)
This should tell us how much time it really takes to do the ODB part, and see how much we could save by optimizing disk access, for instance by using an lstat cache.
1 parent 8d36713 commit 895d475

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

etc/check-package-size.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ echo "in root: gitoxide CLI"
4141
(enter git-packetline && indent cargo diet -n --package-size-limit 35KB)
4242
(enter git-repository && indent cargo diet -n --package-size-limit 80KB)
4343
(enter git-transport && indent cargo diet -n --package-size-limit 50KB)
44-
(enter gitoxide-core && indent cargo diet -n --package-size-limit 50KB)
44+
(enter gitoxide-core && indent cargo diet -n --package-size-limit 60KB)

git-worktree/tests/index/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,14 @@ mod checkout {
173173
let odb = git_odb::at(git_dir.join("objects"))?;
174174
let destination = tempfile::tempdir()?;
175175

176-
let outcome = index::checkout(&mut index)?;
176+
let outcome = index::checkout(
177+
&mut index,
178+
&destination,
179+
move |oid, buf| odb.find_blob(oid, buf).ok(),
180+
&mut progress::Discard,
181+
&mut progress::Discard,
182+
opts,
183+
)?;
177184
Ok((source_tree, destination, index, outcome))
178185
}
179186

gitoxide-core/src/index/mod.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,23 @@ fn parse_file(index_path: impl AsRef<Path>, object_hash: git::hash::Kind) -> any
101101
.map_err(Into::into)
102102
}
103103

104+
pub mod checkout_exclusive {
105+
pub struct Options {
106+
pub index: super::Options,
107+
/// If true, all files will be written with zero bytes despite having made an ODB lookup.
108+
pub empty_files: bool,
109+
}
110+
}
111+
104112
pub fn checkout_exclusive(
105113
index_path: impl AsRef<Path>,
106114
dest_directory: impl AsRef<Path>,
107115
repo: Option<PathBuf>,
108116
mut progress: impl Progress,
109-
Options { object_hash, .. }: Options,
117+
checkout_exclusive::Options {
118+
index: Options { object_hash, .. },
119+
empty_files,
120+
}: checkout_exclusive::Options,
110121
) -> anyhow::Result<()> {
111122
let repo = repo
112123
.map(|dir| git_repository::discover(dir).map(|r| r.apply_environment()))
@@ -124,7 +135,7 @@ pub fn checkout_exclusive(
124135
let mut index = parse_file(index_path, object_hash)?;
125136

126137
let mut num_skipped = 0;
127-
let maybe_symlink_mode = if repo.is_some() {
138+
let maybe_symlink_mode = if !empty_files && repo.is_some() {
128139
git::index::entry::Mode::DIR
129140
} else {
130141
git::index::entry::Mode::SYMLINK
@@ -161,7 +172,18 @@ pub fn checkout_exclusive(
161172
Some(repo) => git::worktree::index::checkout(
162173
&mut index,
163174
dest_directory,
164-
|oid, buf| repo.objects.find_blob(oid, buf).ok(),
175+
|oid, buf| {
176+
repo.objects.find_blob(oid, buf).ok();
177+
if empty_files {
178+
// We always want to query the ODB here…
179+
repo.objects.find_blob(oid, buf).ok();
180+
buf.clear();
181+
// …but write nothing
182+
Some(git::objs::BlobRef { data: buf })
183+
} else {
184+
repo.objects.find_blob(oid, buf).ok()
185+
}
186+
},
165187
&mut files,
166188
&mut bytes,
167189
opts,

src/plumbing/main.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ pub fn main() -> Result<()> {
7878
index_path,
7979
cmd,
8080
}) => match cmd {
81-
index::Subcommands::CheckoutExclusive { directory, repository } => prepare_and_run(
81+
index::Subcommands::CheckoutExclusive {
82+
directory,
83+
empty_files,
84+
repository,
85+
} => prepare_and_run(
8286
"index-checkout",
8387
verbose,
8488
progress,
@@ -90,7 +94,10 @@ pub fn main() -> Result<()> {
9094
directory,
9195
repository,
9296
progress,
93-
core::index::Options { object_hash, format },
97+
core::index::checkout_exclusive::Options {
98+
index: core::index::Options { object_hash, format },
99+
empty_files,
100+
},
94101
)
95102
},
96103
),

src/plumbing/options.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ pub mod index {
373373
/// in the index. Use this measure the impact on extracting objects on overall performance.
374374
#[clap(long, short = 'r')]
375375
repository: Option<PathBuf>,
376+
/// Enable to query the object database yet write only empty files. This is useful to measure the overhead of ODB query
377+
/// compared to writing the bytes to disk.
378+
#[clap(long, short = 'e', requires = "repository")]
379+
empty_files: bool,
376380
/// The directory into which to write all index entries.
377381
directory: PathBuf,
378382
},

0 commit comments

Comments
 (0)