changeset_git/repository/
status.rs1use crate::{GitError, Result};
2
3use super::Repository;
4
5impl Repository {
6 pub fn current_branch(&self) -> Result<String> {
10 let head = self.inner.head()?;
11
12 if !head.is_branch() {
13 return Err(GitError::DetachedHead);
14 }
15
16 head.shorthand()
17 .map(String::from)
18 .ok_or(GitError::DetachedHead)
19 }
20
21 pub fn is_working_tree_clean(&self) -> Result<bool> {
25 let statuses = self.inner.statuses(Some(
26 git2::StatusOptions::new()
27 .include_untracked(true)
28 .recurse_untracked_dirs(true),
29 ))?;
30
31 Ok(statuses.is_empty())
32 }
33
34 pub fn require_clean_working_tree(&self) -> Result<()> {
38 if self.is_working_tree_clean()? {
39 Ok(())
40 } else {
41 Err(GitError::DirtyWorkingTree)
42 }
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::super::tests::setup_test_repo;
49 use crate::GitError;
50 use std::fs;
51
52 #[test]
53 fn current_branch_on_main() -> anyhow::Result<()> {
54 let (_dir, repo) = setup_test_repo()?;
55 let branch = repo.current_branch()?;
56 assert!(branch == "main" || branch == "master");
57 Ok(())
58 }
59
60 #[test]
61 fn clean_working_tree() -> anyhow::Result<()> {
62 let (_dir, repo) = setup_test_repo()?;
63 assert!(repo.is_working_tree_clean()?);
64 Ok(())
65 }
66
67 #[test]
68 fn dirty_working_tree_with_untracked_file() -> anyhow::Result<()> {
69 let (dir, repo) = setup_test_repo()?;
70 fs::write(dir.path().join("new_file.txt"), "content")?;
71 assert!(!repo.is_working_tree_clean()?);
72 Ok(())
73 }
74
75 #[test]
76 fn require_clean_fails_on_dirty() -> anyhow::Result<()> {
77 let (dir, repo) = setup_test_repo()?;
78 fs::write(dir.path().join("new_file.txt"), "content")?;
79
80 let result = repo.require_clean_working_tree();
81 assert!(result.is_err());
82 Ok(())
83 }
84
85 #[test]
86 fn current_branch_detached_head_fails() -> anyhow::Result<()> {
87 let (_dir, repo) = setup_test_repo()?;
88 let head_commit = repo.inner.head()?.peel_to_commit()?;
89 repo.inner.set_head_detached(head_commit.id())?;
90
91 let result = repo.current_branch();
92 assert!(matches!(result, Err(GitError::DetachedHead)));
93 Ok(())
94 }
95}