1use crate::cmd::cmd;
6use color_eyre::Result;
7use std::path::{Path, PathBuf};
8
9pub struct Repository {
11 path: Option<PathBuf>,
13 dirty: bool,
15}
16
17impl Repository {
18 pub fn new(path: Option<PathBuf>) -> Self {
23 Repository { path, dirty: false }
24 }
25
26 pub fn add(&mut self, path: &Path) -> Result<()> {
28 let changed = !cmd!([git diff] ["-s" "--exit-code" "--" (path)] -> bool in &self.path)?;
29 if changed {
30 self.dirty = true;
31 cmd!([git add] [(path)] in &self.path)?;
32 }
33 Ok(())
34 }
35
36 pub fn current_commit(&self) -> Result<String> {
38 cmd!([git "rev-parse"] [HEAD] -> String in &self.path)
39 }
40
41 pub fn commit(&mut self, message: &str) -> Result<Option<String>> {
46 if !self.dirty {
47 return Ok(None);
48 }
49 cmd!([git commit] ["-m" (message)] in &self.path)?;
50 self.dirty = false;
51 Ok(Some(self.current_commit()?))
52 }
53
54 pub fn current_branch_or_commit(&self) -> Result<String> {
56 let branch = cmd!([git branch] ["--show-current"] -> String in &self.path)?;
57 if !branch.is_empty() {
58 Ok(branch)
59 } else {
60 Ok(self.current_commit()?)
61 }
62 }
63
64 pub fn checkout(&mut self, target: &str) -> Result<()> {
66 cmd!([git "checkout"] [(target)] in &self.path)
67 }
68}