Skip to main content

worktree_io/git/
clone.rs

1use anyhow::{bail, Context, Result};
2use std::path::Path;
3
4/// Clone `url` as a bare repository into `dest`.
5///
6/// Also configures `remote.origin.fetch` so that `git fetch` populates
7/// `refs/remotes/origin/*`, then runs an initial fetch.
8///
9/// # Errors
10///
11/// Returns an error if the destination directory cannot be created, or if any
12/// of the git commands fail.
13pub fn bare_clone(url: &str, dest: &Path) -> Result<()> {
14    if let Some(parent) = dest.parent() {
15        std::fs::create_dir_all(parent)
16            .with_context(|| format!("Failed to create directory {}", parent.display()))?;
17    }
18
19    let status = super::git_cmd()
20        .args(["clone", "--bare", url])
21        .arg(dest)
22        .status()
23        .context("Failed to run `git clone --bare`")?;
24
25    if !status.success() {
26        bail!("git clone --bare failed for {url}"); // LLVM_COV_EXCL_LINE
27    }
28
29    let fetch_refspec = "+refs/heads/*:refs/remotes/origin/*";
30    let status = super::git_cmd()
31        .args(["-C"])
32        .arg(dest)
33        .args(["config", "remote.origin.fetch", fetch_refspec])
34        .status()
35        .context("Failed to configure remote.origin.fetch")?;
36
37    if !status.success() {
38        bail!("Failed to set remote.origin.fetch"); // LLVM_COV_EXCL_LINE
39    }
40
41    let status = super::git_cmd()
42        .args(["-C"])
43        .arg(dest)
44        .args(["fetch", "origin"])
45        .status()
46        .context("Failed to run `git fetch origin`")?;
47
48    if !status.success() {
49        bail!("git fetch origin failed after bare clone"); // LLVM_COV_EXCL_LINE
50    }
51
52    Ok(())
53}
54
55/// Fetch the latest refs from `origin` for a bare clone at `bare`.
56///
57/// # Errors
58///
59/// Returns an error if the git command fails to spawn or exits non-zero.
60pub fn git_fetch(bare: &Path) -> Result<()> {
61    let status = super::git_cmd()
62        .args(["-C"])
63        .arg(bare)
64        .args(["fetch", "origin"])
65        .status()
66        .context("Failed to run `git fetch`")?;
67
68    if !status.success() {
69        bail!("git fetch origin failed"); // LLVM_COV_EXCL_LINE
70    }
71    Ok(())
72}