radicle: use `git fetch` over libigt2 in checkout

Similarly to pushing using the `file://` protocol and `libgit2`, fetching will
be slow – so instead use `git fetch` directly to perform the `checkout`.
This commit is contained in:
Fintan Halpenny 2025-04-03 16:24:18 +02:00 committed by Lorenz Leutgeb
parent a9fa31e5e6
commit ce8ac663f7
No known key found for this signature in database
1 changed files with 34 additions and 2 deletions

View File

@ -220,8 +220,12 @@ pub fn fork<G: Signer, S: storage::WriteStorage>(
#[derive(Error, Debug)]
pub enum CheckoutError {
#[error(
"the Git repository found at {path:?} is a bare repository, expected a working directory"
)]
BareRepository { path: PathBuf },
#[error("failed to fetch to working copy")]
Fetch(#[source] git2::Error),
Fetch(#[source] std::io::Error),
#[error("git: {0}")]
Git(#[from] git2::Error),
#[error("payload: {0}")]
@ -260,7 +264,35 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
&url,
&url.clone().with_namespace(*remote),
)?;
git::fetch(&repo, &REMOTE_NAME).map_err(CheckoutError::Fetch)?;
let fetchspec = git::Refspec {
src: git::refspec::pattern!("refs/heads/*"),
dst: git::Qualified::from(git::lit::refs_remotes(&*REMOTE_NAME))
.to_pattern(git::refspec::STAR)
.into_patternstring(),
force: false,
};
let stored = storage.repository(proj)?;
let workdir = repo.workdir().ok_or(CheckoutError::BareRepository {
path: repo.path().to_path_buf(),
})?;
git::run::<_, _, &str, &str>(
workdir,
[
"fetch",
&format!(
"{}",
stored
.path()
.canonicalize()
.map_err(CheckoutError::Fetch)?
.display()
),
&fetchspec.to_string(),
],
[],
)
.map_err(CheckoutError::Fetch)?;
{
// Setup default branch.