Generalize Git URL handling and fix repository creation flow
This commit is contained in:
@@ -44,7 +44,11 @@ impl GitCache {
|
||||
}
|
||||
|
||||
/// Open the existing clone, fetching it first.
|
||||
pub fn ensure_clone(&self, addr: &RepoAddr, clone_urls: &[String]) -> Result<gix::Repository> {
|
||||
pub fn ensure_clone<U: AsRef<str>>(
|
||||
&self,
|
||||
addr: &RepoAddr,
|
||||
clone_urls: &[U],
|
||||
) -> Result<gix::Repository> {
|
||||
let path = self.repo_path(addr);
|
||||
|
||||
if let Some(repo) = self.open(addr)? {
|
||||
@@ -122,7 +126,7 @@ pub fn find_git_repos(root: &Path) -> Vec<PathBuf> {
|
||||
/// Clone into `path` from the first working URL in `clone_urls`.
|
||||
///
|
||||
/// Unlike [`GitCache::ensure_clone`], the clone is not kept in any cache.
|
||||
pub fn clone_repo(clone_urls: &[String], path: &Path) -> Result<()> {
|
||||
pub fn clone_repo<U: AsRef<str>>(clone_urls: &[U], path: &Path) -> Result<()> {
|
||||
if path.exists() {
|
||||
bail!("destination {} already exists", path.display());
|
||||
}
|
||||
@@ -347,14 +351,14 @@ fn transport_url(url: &str) -> String {
|
||||
///
|
||||
/// Returns the last error wrapped in `failed to {verb} from any mirror`,
|
||||
/// or `no clone URLs provided` when the list is empty.
|
||||
fn try_each_url<F>(urls: &[String], verb: &str, mut attempt: F) -> Result<()>
|
||||
fn try_each_url<U: AsRef<str>, F>(urls: &[U], verb: &str, mut attempt: F) -> Result<()>
|
||||
where
|
||||
F: FnMut(&str) -> Result<()>,
|
||||
{
|
||||
let mut last_err: Option<anyhow::Error> = None;
|
||||
|
||||
for url in urls {
|
||||
match attempt(url) {
|
||||
match attempt(url.as_ref()) {
|
||||
Ok(()) => return Ok(()),
|
||||
Err(e) => last_err = Some(e),
|
||||
}
|
||||
@@ -698,7 +702,7 @@ fn edit_local_config(
|
||||
/// When no URL works, the last error is returned.
|
||||
///
|
||||
/// Never touches the checked-out refs or the worktree.
|
||||
pub fn fetch_repo_refs(repo_path: &Path, urls: &[String], refspec: &str) -> Result<()> {
|
||||
pub fn fetch_repo_refs<U: AsRef<str>>(repo_path: &Path, urls: &[U], refspec: &str) -> Result<()> {
|
||||
let repo = gix::open(repo_path)?;
|
||||
let refspec = gix::refspec::parse(
|
||||
gix::bstr::BStr::new(refspec),
|
||||
@@ -2950,9 +2954,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn working_copy_cloned_from_the_mirror_matches_head_and_origin() {
|
||||
// The mirror is a freshly initialized repository.
|
||||
// Its `origin` points at the grasp server.
|
||||
// `Backend::create_repository` leaves it in the GitCache.
|
||||
// The mirror is a freshly initialized repository, standing in for
|
||||
// the grasp server. Its `origin` points at the (fake) grasp server.
|
||||
// `GitCache::ensure_clone` lazily clones from a URL shaped like this
|
||||
// the first time a repository is opened.
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let mirror = dir.path().join("mirror");
|
||||
let commit = init_repository(&mirror, "My Repo", "Does things.").expect("init");
|
||||
@@ -3166,7 +3171,8 @@ mod tests {
|
||||
assert!(err.to_string().contains("failed to fetch"));
|
||||
|
||||
// Without any URL there is nothing to try.
|
||||
let err = fetch_repo_refs(dir, &[], "+refs/heads/*:refs/fork/x/*").expect_err("no URLs");
|
||||
let err = fetch_repo_refs(dir, &[] as &[String], "+refs/heads/*:refs/fork/x/*")
|
||||
.expect_err("no URLs");
|
||||
assert!(err.to_string().contains("no clone URLs"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user