clankerdiff_git/error.rs
1//! Errors produced by native Git and filesystem operations.
2
3use clankerdiff_core::{DiffError, RepoPathError};
4use std::{io, path::PathBuf};
5
6/// An error from repository discovery, Git execution, or worktree access.
7#[derive(Debug, thiserror::Error)]
8pub enum GitError {
9 /// The supplied location is not inside a Git worktree.
10 #[error("path is not inside a Git worktree")]
11 NotRepository,
12 /// Git returned a repository root that cannot be represented as UTF-8.
13 #[error("repository root is not valid UTF-8")]
14 UnsupportedRepositoryPath,
15 /// A repository-relative path failed validation.
16 #[error("invalid repository path: {0}")]
17 InvalidPath(#[from] RepoPathError),
18 /// A validated path resolved outside the repository root.
19 #[error("repository path escapes the worktree: {path}")]
20 PathEscapesRepository {
21 /// The rejected path.
22 path: String,
23 },
24 /// A file operation unexpectedly targeted a directory.
25 #[error("repository path is not a file: {path}")]
26 NotAFile {
27 /// The rejected path.
28 path: String,
29 },
30 /// A commit message was empty or only whitespace.
31 #[error("commit message must not be empty")]
32 EmptyCommitMessage,
33 /// The Git process could not be started or awaited.
34 #[error("could not execute git operation `{operation}`: {source}")]
35 Spawn {
36 /// A non-sensitive operation label.
37 operation: &'static str,
38 /// The subprocess I/O error.
39 #[source]
40 source: io::Error,
41 },
42 /// Git exited unsuccessfully.
43 ///
44 /// `stderr` is retained for diagnostics, but omitted from `Display` to
45 /// avoid leaking file contents or other sensitive command output.
46 #[error("git operation `{operation}` failed with status {status:?}")]
47 CommandFailed {
48 /// A non-sensitive operation label.
49 operation: &'static str,
50 /// The process exit code, when one was available.
51 status: Option<i32>,
52 /// Git's standard error bytes, decoded lossily.
53 stderr: String,
54 },
55 /// A filesystem operation failed.
56 #[error("filesystem operation failed for {path}")]
57 Io {
58 /// The affected host path.
59 path: PathBuf,
60 /// The filesystem error.
61 #[source]
62 source: io::Error,
63 },
64 /// A source version exceeded the per-file capture limit.
65 #[error("source version is too large ({bytes} bytes)")]
66 SourceTooLarge { bytes: u64 },
67 /// Repository metadata or worktree content changed during capture.
68 #[error("repository changed while capturing the snapshot")]
69 UnstableSnapshot,
70 /// Core diff normalization failed.
71 #[error("could not normalize Git snapshot: {0}")]
72 Diff(#[from] DiffError),
73}