grm/repo/worktree/
error.rs1use std::fmt;
2
3use super::{BranchName, RemoteName, RepoChanges, WorktreeName, config, path, repo};
4
5use camino::Utf8PathBuf as PathBuf;
6use thiserror::Error;
7
8#[derive(Debug, Error)]
9pub enum Error {
10 #[error(transparent)]
11 Libgit(#[from] git2::Error),
12 #[error(transparent)]
13 Repo(#[from] repo::Error),
14 #[error(transparent)]
15 Config(#[from] config::Error),
16 #[error(transparent)]
17 InvalidWorktreeName(#[from] WorktreeValidationError),
18 #[error("Remote \"{name}\" not found")]
19 RemoteNotFound { name: RemoteName },
20 #[error("Cannot push to non-pushable remote \"{name}\"")]
21 RemoteNotPushable { name: RemoteName },
22 #[error(transparent)]
23 Io(#[from] std::io::Error),
24 #[error("Current directory does not contain a worktree setup")]
25 NotAWorktreeSetup,
26 #[error("Worktree {name} already exists")]
27 WorktreeAlreadyExists { name: WorktreeName },
28 #[error("Branch \"{0}\" not found")]
29 BranchNotFound(BranchName),
30 #[error("Worktree name is not valid utf-8")]
31 WorktreeNameNotUtf8,
32 #[error("Worktree name is empty")]
33 WorktreeNameEmpty,
34 #[error(transparent)]
35 Path(#[from] path::Error),
36 #[error("Could not determine base directory from \"{git_dir}\"")]
37 InvalidBaseDirectory { git_dir: PathBuf },
38}
39
40#[derive(Debug, Error)]
41#[error("invalid worktree name \"{name}\": {reason}")]
42pub struct WorktreeValidationError {
43 pub(super) name: String,
44 pub(super) reason: WorktreeValidationErrorReason,
45}
46
47#[derive(Debug)]
48pub enum WorktreeValidationErrorReason {
49 SlashAtStartOrEnd,
50 ConsecutiveSlashes,
51 ContainsWhitespace,
52}
53
54impl fmt::Display for WorktreeValidationErrorReason {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(
57 f,
58 "{}",
59 match *self {
60 Self::SlashAtStartOrEnd => "Cannot start or end with a slash",
61 Self::ConsecutiveSlashes => "Cannot contain two consecutive slashes",
62 Self::ContainsWhitespace => "Cannot contain whitespace",
63 }
64 )
65 }
66}
67
68#[derive(Debug, Error)]
69pub enum WorktreeRemoveError {
70 #[error(transparent)]
71 RepoError(repo::Error),
72 #[error("Worktree at {0} does not exist")]
73 DoesNotExist(PathBuf),
74 #[error(
75 "Branch \"{branch_name}\" is checked out in worktree \"{worktree_name}\", this does not look correct"
76 )]
77 BranchNameMismatch {
78 worktree_name: WorktreeName,
79 branch_name: BranchName,
80 },
81 #[error("Branch {0} not found")]
82 BranchNotFound(BranchName),
83 #[error("Changes found in worktree: {0}")]
84 Changes(RepoChanges),
85 #[error("Branch {branch_name} is not merged into any persistent branches")]
86 NotMerged { branch_name: BranchName },
87 #[error("Branch {branch_name} is not in line with remote branch")]
88 NotInSyncWithRemote { branch_name: BranchName },
89 #[error("Removing {path} failed: {error}")]
90 RemoveError {
91 path: PathBuf,
92 error: std::io::Error,
93 },
94 #[error("Error getting directory entry {path}: {error}")]
95 ReadDirectoryError {
96 path: PathBuf,
97 error: std::io::Error,
98 },
99}
100
101impl From<repo::Error> for WorktreeRemoveError {
102 fn from(value: repo::Error) -> Self {
103 Self::RepoError(value)
104 }
105}
106
107#[derive(Debug, Error)]
108pub enum WorktreeConversionError {
109 #[error(transparent)]
110 RepoError(repo::Error),
111 #[error("Changes found in worktree: {0}")]
112 Changes(RepoChanges),
113 #[error("Ignored files found")]
114 Ignored,
115 #[error("{}", .0)]
116 RenameError(String),
117 #[error(transparent)]
118 Path(#[from] path::Error),
119 #[error("Opening directory failed: {0}")]
120 OpenDirectoryError(std::io::Error),
121 #[error("Removing {path} failed: {error}")]
122 RemoveError {
123 path: PathBuf,
124 error: std::io::Error,
125 },
126 #[error("Error getting directory entry: {0}")]
127 ReadDirectoryError(std::io::Error),
128}
129
130impl From<repo::Error> for WorktreeConversionError {
131 fn from(value: repo::Error) -> Self {
132 Self::RepoError(value)
133 }
134}
135
136#[derive(Debug, Error)]
137pub enum CleanupWorktreeError {
138 #[error(transparent)]
139 RepoError(#[from] Error),
140 #[error(transparent)]
141 RemoveError(#[from] WorktreeRemoveError),
142 #[error("Could not get default branch: {0}")]
143 DefaultBranch(repo::Error),
144 #[error("Branch name error: {0}")]
145 BranchName(repo::Error),
146 #[error("Branch \"{branch_name}\" not found")]
147 BranchNotFound { branch_name: BranchName },
148}
149
150pub struct CleanupWorktreeWarning {
151 pub worktree_name: WorktreeName,
152 pub reason: CleanupWorktreeWarningReason,
153}
154
155pub enum CleanupWorktreeWarningReason {
156 UncommittedChanges(RepoChanges),
157 NotMerged { branch_name: BranchName },
158 NoDirectory,
159}