radicle: Use `git fetch-pack` for "local fetch"

This commit is contained in:
Lorenz Leutgeb 2025-09-16 10:55:12 +02:00
parent 20663a4e39
commit f542df1833
No known key found for this signature in database
3 changed files with 20 additions and 12 deletions

View File

@ -129,7 +129,7 @@ fn find_patch_commit<'a>(
match working.find_commit(head) { match working.find_commit(head) {
Ok(commit) => Ok(commit), Ok(commit) => Ok(commit),
Err(e) if git::ext::is_not_found_err(&e) => { Err(e) if git::ext::is_not_found_err(&e) => {
let output = git::process::fetch_local( let output = git::process::fetch_pack(
Some(working.path()), Some(working.path()),
stored, stored,
[head.into()], [head.into()],

View File

@ -64,7 +64,7 @@ pub fn run<R: ReadRepository>(
// used in the working copy, this will always result in the object // used in the working copy, this will always result in the object
// missing. This seems to only be an issue with `libgit2`/`git2` // missing. This seems to only be an issue with `libgit2`/`git2`
// and not `git` itself. // and not `git` itself.
git::process::fetch_local(working, &stored, oids, verbosity.into())?; git::process::fetch_pack(working, &stored, oids, verbosity.into())?;
// Nb. An empty line means we're done. // Nb. An empty line means we're done.
println!(); println!();

View File

@ -78,6 +78,18 @@ impl Verbosity {
Some(FLAG_PREFIX.to_string() + &flag.repeat(repetitions)) Some(FLAG_PREFIX.to_string() + &flag.repeat(repetitions))
} }
/// Clamps verbosity to a range, as some commands only accept a specific
/// number of repetitions.
fn clamp(self, min: i8, max: i8) -> Self {
Self(self.0.clamp(min, max))
}
/// Clamps verbosity to at most `-v` or `-q`, as some commands do not accept
/// repetitions.
pub fn clamp_one(self) -> Self {
self.clamp(-1, 1)
}
} }
impl From<i8> for Verbosity { impl From<i8> for Verbosity {
@ -783,13 +795,13 @@ pub mod process {
use crate::storage::ReadRepository; use crate::storage::ReadRepository;
use super::{run, url, Oid, Verbosity}; use super::{run, Oid, Verbosity};
/// Perform a local fetch, i.e. `file://<storage path>`. /// Perform a local fetch, from storage using `git fetch-pack`.
/// ///
/// `oids` are the set of [`Oid`]s that are being fetched from the /// `oids` are the set of [`Oid`]s that are being fetched from the
/// `storage`. /// `storage`.
pub fn fetch_local<R>( pub fn fetch_pack<R>(
working: Option<&Path>, working: Option<&Path>,
storage: &R, storage: &R,
oids: impl IntoIterator<Item = Oid>, oids: impl IntoIterator<Item = Oid>,
@ -798,13 +810,9 @@ pub mod process {
where where
R: ReadRepository, R: ReadRepository,
{ {
let mut args = vec![ let mut args = vec!["fetch-pack".to_string()];
"fetch".to_string(), args.extend(verbosity.clamp_one().into_flag());
// Avoid writing fetch head since we're only fetching objects args.push(dunce::canonicalize(storage.path())?.display().to_string());
"--no-write-fetch-head".to_string(),
];
args.extend(verbosity.into_flag());
args.push(url::File::new(storage.path()).to_string());
args.extend(oids.into_iter().map(|oid| oid.to_string())); args.extend(oids.into_iter().map(|oid| oid.to_string()));
run(working, args) run(working, args)
} }