diff --git a/radicle/src/rad.rs b/radicle/src/rad.rs index d94665d1..ac4b1895 100644 --- a/radicle/src/rad.rs +++ b/radicle/src/rad.rs @@ -220,8 +220,12 @@ pub fn fork( #[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, 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.