From f542df1833d01ba6a50070a5b25bdbb9d575764e Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Tue, 16 Sep 2025 10:55:12 +0200 Subject: [PATCH] radicle: Use `git fetch-pack` for "local fetch" --- .../src/commands/patch/checkout.rs | 2 +- crates/radicle-remote-helper/src/fetch.rs | 2 +- crates/radicle/src/git.rs | 28 ++++++++++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/crates/radicle-cli/src/commands/patch/checkout.rs b/crates/radicle-cli/src/commands/patch/checkout.rs index 08d03691..5ea1a630 100644 --- a/crates/radicle-cli/src/commands/patch/checkout.rs +++ b/crates/radicle-cli/src/commands/patch/checkout.rs @@ -129,7 +129,7 @@ fn find_patch_commit<'a>( match working.find_commit(head) { Ok(commit) => Ok(commit), 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()), stored, [head.into()], diff --git a/crates/radicle-remote-helper/src/fetch.rs b/crates/radicle-remote-helper/src/fetch.rs index 3715402d..7c794c48 100644 --- a/crates/radicle-remote-helper/src/fetch.rs +++ b/crates/radicle-remote-helper/src/fetch.rs @@ -64,7 +64,7 @@ pub fn run( // used in the working copy, this will always result in the object // missing. This seems to only be an issue with `libgit2`/`git2` // 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. println!(); diff --git a/crates/radicle/src/git.rs b/crates/radicle/src/git.rs index 7a3db866..9c1769dc 100644 --- a/crates/radicle/src/git.rs +++ b/crates/radicle/src/git.rs @@ -78,6 +78,18 @@ impl Verbosity { 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 for Verbosity { @@ -783,13 +795,13 @@ pub mod process { use crate::storage::ReadRepository; - use super::{run, url, Oid, Verbosity}; + use super::{run, Oid, Verbosity}; - /// Perform a local fetch, i.e. `file://`. + /// Perform a local fetch, from storage using `git fetch-pack`. /// /// `oids` are the set of [`Oid`]s that are being fetched from the /// `storage`. - pub fn fetch_local( + pub fn fetch_pack( working: Option<&Path>, storage: &R, oids: impl IntoIterator, @@ -798,13 +810,9 @@ pub mod process { where R: ReadRepository, { - let mut args = vec![ - "fetch".to_string(), - // Avoid writing fetch head since we're only fetching objects - "--no-write-fetch-head".to_string(), - ]; - args.extend(verbosity.into_flag()); - args.push(url::File::new(storage.path()).to_string()); + let mut args = vec!["fetch-pack".to_string()]; + args.extend(verbosity.clamp_one().into_flag()); + args.push(dunce::canonicalize(storage.path())?.display().to_string()); args.extend(oids.into_iter().map(|oid| oid.to_string())); run(working, args) }