Skip to main content

git_semantic/git/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum GitError {
5    #[error("not a git repository or unable to open")]
6    RepositoryNotFound(#[source] git2::Error),
7
8    #[error("commit {0} not found in history — index may be stale after a rebase or force push")]
9    CommitNotFound(String),
10
11    #[error("failed to walk commit history: no HEAD found")]
12    NoHead,
13
14    #[error("failed to read repository history")]
15    RevwalkFailed(#[source] git2::Error),
16
17    #[error("git operation failed")]
18    Git(#[from] git2::Error),
19}
20
21impl GitError {
22    /// Returns a user-facing hint for how to resolve this error.
23    pub fn hint(&self) -> Option<&'static str> {
24        match self {
25            Self::RepositoryNotFound(_) => {
26                Some("Make sure you're inside a git repository, or use --path to specify one.")
27            }
28            Self::CommitNotFound(_) => Some(
29                "The index references commits that no longer exist. Run: git-semantic index --force",
30            ),
31            Self::NoHead => {
32                Some("The repository has no commits yet. Make at least one commit before indexing.")
33            }
34            Self::RevwalkFailed(_) => {
35                Some("The git history may be corrupted. Try running: git fsck")
36            }
37            Self::Git(_) => None,
38        }
39    }
40
41    /// Returns an error code for programmatic identification.
42    pub fn code(&self) -> &'static str {
43        match self {
44            Self::RepositoryNotFound(_) => "E2001",
45            Self::CommitNotFound(_) => "E2002",
46            Self::NoHead => "E2003",
47            Self::RevwalkFailed(_) => "E2004",
48            Self::Git(_) => "E2005",
49        }
50    }
51}