| 239 | } |
| 240 | |
| 241 | fn fetch<P>( |
| 242 | repository_url: &Url, |
| 243 | into_dir: P, |
| 244 | get_credentials: &impl Fn(&str) -> Vec<(CredentialType, Cred)>, |
| 245 | commit_id: &str, |
| 246 | ) -> Result<Repository, Error> |
| 247 | where |
| 248 | P: AsRef<Path>, |
| 249 | { |
| 250 | #[cfg(not(feature = "test-git-container"))] |
| 251 | { |
| 252 | // Allow file:// in unit tests so tests can use a local repo without a network round-trip. |
| 253 | #[cfg(not(test))] |
| 254 | if repository_url.scheme() != "https" { |
| 255 | return Err(Error::from_str("Repository URL have to start with https://")); |
| 256 | } |
| 257 | #[cfg(test)] |
| 258 | if repository_url.scheme() != "https" && repository_url.scheme() != "file" { |
| 259 | return Err(Error::from_str("Repository URL have to start with https://")); |
| 260 | } |
| 261 | } |
| 262 | #[cfg(feature = "test-git-container")] |
| 263 | { |
| 264 | // http is allowed only for tests (git server on testcontainer) |
| 265 | if !(repository_url.scheme() == "https" || repository_url.scheme() == "http") { |
| 266 | // if repository_url.scheme() != "https" { |
| 267 | return Err(Error::from_str("Repository URL have to start with https://")); |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | // Prepare authentication callbacks. |
| 272 | let mut callbacks = RemoteCallbacks::new(); |
| 273 | callbacks.credentials(authentication_callback(&get_credentials)); |
| 274 | |
| 275 | // Prepare fetch options. |
| 276 | let mut fo = FetchOptions::new(); |
| 277 | fo.remote_callbacks(callbacks); |
| 278 | // Local transport doesn't support shallow fetches; skip depth for file:// (test-only path). |
| 279 | if repository_url.scheme() != "file" { |
| 280 | fo.depth(1); |
| 281 | } |
| 282 | fo.update_fetchhead(false); |
| 283 | fo.download_tags(AutotagOption::None); |
| 284 | |
| 285 | // Get our repository |
| 286 | if into_dir.as_ref().exists() { |
| 287 | let _ = std::fs::remove_dir_all(into_dir.as_ref()); |
| 288 | } |
| 289 | |
| 290 | #[cfg(not(feature = "test-git-container"))] |
| 291 | { |
| 292 | let repo = Repository::init(into_dir.as_ref())?; |
| 293 | remote_fetch(repository_url, &commit_id, &mut fo, &repo)?; |
| 294 | Ok(repo) |
| 295 | } |
| 296 | #[cfg(feature = "test-git-container")] |
| 297 | { |
| 298 | use git2::build::RepoBuilder; |