1use std::fmt;
2use std::path::Path;
3
4pub fn git_state(repo: &Path) -> Result<RepositoryState, ()> {
13 let git_dir = repo.join(".git");
14 let git_dir = if git_dir.is_dir() { &git_dir } else { repo };
15
16 if git_dir.join("rebase-merge/interactive").is_file() {
17 Ok(RepositoryState::RebaseInteractive)
18 } else if git_dir.join("rebase-merge").is_dir() {
19 Ok(RepositoryState::RebaseMerge)
20 } else if git_dir.join("rebase-apply/rebasing").is_file() {
21 Ok(RepositoryState::Rebase)
22 } else if git_dir.join("rebase-apply/applying").is_file() {
23 Ok(RepositoryState::ApplyMailbox)
24 } else if git_dir.join("rebase-apply").is_dir() {
25 Ok(RepositoryState::ApplyMailboxOrRebase)
26 } else if git_dir.join("MERGE_HEAD").is_file() {
27 Ok(RepositoryState::Merge)
28 } else if git_dir.join("REVERT_HEAD").is_file() {
29 if git_dir.join("sequencer/todo").is_file() {
30 Ok(RepositoryState::RevertSequence)
31 } else {
32 Ok(RepositoryState::Revert)
33 }
34 } else if git_dir.join("CHERRY_PICK_HEAD").is_file() {
35 if git_dir.join("sequencer/todo").is_file() {
36 Ok(RepositoryState::CherryPickSequence)
37 } else {
38 Ok(RepositoryState::CherryPick)
39 }
40 } else if git_dir.join("BISECT_LOG").is_file() {
41 Ok(RepositoryState::Bisect)
42 } else {
43 Ok(RepositoryState::Clean)
44 }
45}
46
47#[derive(Debug, PartialEq, Eq, Copy, Clone)]
52pub enum RepositoryState {
53 Clean,
54 Merge,
55 Revert,
56 RevertSequence,
57 CherryPick,
58 CherryPickSequence,
59 Bisect,
60 Rebase,
61 RebaseInteractive,
62 RebaseMerge,
63 ApplyMailbox,
64 ApplyMailboxOrRebase,
65}
66
67impl fmt::Display for RepositoryState {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(f, "{:?}", self)
70 }
71}