59 lines
1.8 KiB
Rust
59 lines
1.8 KiB
Rust
use std::path::Path;
|
|
use std::sync::Arc;
|
|
|
|
use crate::GitError;
|
|
use git2::Repository;
|
|
use models::repos::repo;
|
|
|
|
#[derive(Clone)]
|
|
pub struct GitDomain {
|
|
pub(crate) repo: Arc<Repository>,
|
|
}
|
|
|
|
// SAFETY: git2's Repository uses internal locking for thread-safe operations.
|
|
// We additionally enforce exclusive access via Arc::get_mut in repo_mut().
|
|
// All mutable access is gated through the synchronous methods of HookMetaDataSync,
|
|
// which are called from a single blocking thread per sync cycle.
|
|
#[allow(unsafe_code)]
|
|
unsafe impl Send for GitDomain {}
|
|
#[allow(unsafe_code)]
|
|
unsafe impl Sync for GitDomain {}
|
|
|
|
impl GitDomain {
|
|
pub fn from_model(model: repo::Model) -> crate::GitResult<Self> {
|
|
let repo =
|
|
Repository::open(model.storage_path).map_err(|e| GitError::Internal(e.to_string()))?;
|
|
Ok(Self {
|
|
repo: Arc::new(repo),
|
|
})
|
|
}
|
|
pub fn open<P: AsRef<Path>>(path: P) -> crate::GitResult<Self> {
|
|
let repo = Repository::open(path).map_err(|e| GitError::Internal(e.to_string()))?;
|
|
Ok(Self {
|
|
repo: Arc::new(repo),
|
|
})
|
|
}
|
|
|
|
pub fn open_workdir<P: AsRef<Path>>(path: P) -> crate::GitResult<Self> {
|
|
let repo = Repository::open_bare(path).map_err(|e| GitError::Internal(e.to_string()))?;
|
|
Ok(Self {
|
|
repo: Arc::new(repo),
|
|
})
|
|
}
|
|
|
|
pub fn init_bare<P: AsRef<Path>>(path: P) -> crate::GitResult<Self> {
|
|
let repo = Repository::init_bare(path).map_err(|e| GitError::Internal(e.to_string()))?;
|
|
Ok(Self {
|
|
repo: Arc::new(repo),
|
|
})
|
|
}
|
|
pub fn repo(&self) -> &Repository {
|
|
&self.repo
|
|
}
|
|
|
|
pub fn repo_mut(&mut self) -> crate::GitResult<&mut Repository> {
|
|
Arc::get_mut(&mut self.repo)
|
|
.ok_or_else(|| GitError::Internal("GitDomain requires exclusive access".to_string()))
|
|
}
|
|
}
|