Skip to main content

rtb_vcs/git/
init.rs

1//! `Repo::init` — initialise a fresh repository.
2//!
3//! v0.5 commit 1. Scaffolder context: `rtb new` (planned v0.6) uses
4//! this to git-init a freshly generated project before its initial
5//! commit. See spec §3.1 for the option set; v0.5 ships with a
6//! minimal [`InitOptions`] and grows the surface as concrete consumer
7//! needs arrive.
8
9use std::path::{Path, PathBuf};
10
11use super::{Repo, RepoError};
12
13/// Options for [`Repo::init`].
14///
15/// v0.5 ships an empty default. Knobs (bare init, initial branch
16/// name, template path) land alongside the first consumer that asks
17/// for them — kept off the API until then so the foundation surface
18/// stays tight.
19#[derive(Debug, Default, Clone)]
20#[non_exhaustive]
21pub struct InitOptions {}
22
23impl Repo {
24    /// Initialise a new repository at `path`. The directory is
25    /// created if it doesn't already exist (mirroring `git init <path>`
26    /// semantics).
27    ///
28    /// # Errors
29    ///
30    /// - [`RepoError::InitFailed`] — gix could not create the
31    ///   repository (filesystem permission, an existing repository
32    ///   that conflicts, etc.). `cause` carries the backend's
33    ///   stringified error.
34    pub async fn init(path: impl AsRef<Path>, _opts: InitOptions) -> Result<Self, RepoError> {
35        let path: PathBuf = path.as_ref().to_path_buf();
36        let path_for_task = path.clone();
37        tokio::task::spawn_blocking(move || {
38            // `gix::init` returns a `Repository`; wrap it as a
39            // thread-safe handle so `Repo` is Send + Sync.
40            let repo = gix::init(&path_for_task).map_err(|e| RepoError::InitFailed {
41                path: path_for_task.clone(),
42                cause: e.to_string(),
43            })?;
44            Ok::<_, RepoError>(Self::from_thread_safe(repo.into_sync(), path_for_task))
45        })
46        .await
47        .map_err(|join_err| RepoError::InitFailed {
48            path: path.clone(),
49            cause: format!("spawn_blocking join error: {join_err}"),
50        })?
51    }
52}