1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! Errors for [`super::RefStore`] operations.
use crate::refs::RefnameUnavailable;
use super::{Expected, RawRef};
/// Failure modes for reference store reads and transactions.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum RefStoreError {
/// Another prepared transaction holds the store lock.
#[error("cannot lock ref '{name}': lock held")]
LockHeld {
/// Ref name associated with the active lock (often the first update name).
name: String,
},
/// Compare-and-swap or existence check failed for an update.
#[error("ref '{name}' did not match expected state")]
ExpectedMismatch {
/// Ref that failed the check.
name: String,
/// What the caller required.
expected: Expected,
/// What was observed (`None` when the ref is absent).
actual: Option<RawRef>,
},
/// A ref name cannot be created because of a directory/file conflict.
#[error("cannot lock ref: {}", reason.lock_message_suffix())]
NameUnavailable {
/// Structured conflict reason (Git `refs_verify_refname_available` style).
reason: RefnameUnavailable,
},
/// The same ref name appears more than once in one transaction.
#[error("multiple updates for ref '{name}' not allowed")]
DuplicateUpdate {
/// Duplicate ref name.
name: String,
},
/// Symbolic reference resolution exceeded [`crate::refs::SYMREF_MAXDEPTH`].
#[error("symbolic ref loop or chain too deep")]
SymrefLoop,
/// The ref (or the target at the end of its symbolic chain) does not exist.
#[error("ref not found: {name}")]
NotFound {
/// Name of the missing ref: the requested name, or the dangling symbolic target.
name: String,
},
/// Stored data for a ref or reflog is malformed.
#[error("corrupt ref store: {0}")]
Corrupt(String),
/// Ref name is not safe to store (traversal, illegal component, etc.).
#[error("refusing to update ref with bad name '{name}'")]
InvalidRefName {
/// The rejected ref name.
name: String,
},
}
impl RefStoreError {
pub(crate) fn not_found(name: &str) -> Self {
Self::NotFound {
name: name.to_owned(),
}
}
}
impl From<RefnameUnavailable> for RefStoreError {
fn from(reason: RefnameUnavailable) -> Self {
Self::NameUnavailable { reason }
}
}