pub mod operations;
pub mod remote;
use std::path::PathBuf;
use anyhow::{Context, Result};
use gix::bstr::ByteSlice;
pub struct GitRepo {
pub path: PathBuf,
repo: gix::ThreadSafeRepository, }
impl GitRepo {
pub fn discover() -> Result<Self> {
let repo = gix::discover(".")
.context("Failed to discover git repository")?
.into_sync();
let path = repo
.work_dir()
.ok_or_else(|| anyhow::anyhow!("Repository has no working directory"))?
.to_path_buf();
Ok(GitRepo { path, repo })
}
pub fn open(path: &std::path::Path) -> Result<Self> {
let repo = gix::open(path)
.context("Failed to open git repository")?
.into_sync();
let path = repo
.work_dir()
.ok_or_else(|| anyhow::anyhow!("Repository has no working directory"))?
.to_path_buf();
Ok(GitRepo { path, repo })
}
pub fn current_branch(&self) -> Result<String> {
let repo = self.repo.to_thread_local();
let head = repo.head().context("Failed to get HEAD reference")?;
if let Some(name) = head.referent_name() {
let name_str = name
.as_bstr()
.to_str()
.context("Invalid UTF-8 in branch name")?;
if let Some(branch) = name_str.strip_prefix("refs/heads/") {
return Ok(branch.to_string());
}
}
Ok("HEAD".to_string())
}
pub fn git_dir(&self) -> PathBuf {
self.path.join(".git")
}
pub(crate) fn gix_repo(&self) -> gix::Repository {
self.repo.to_thread_local()
}
}