RepoError variants¶
Every Repo method returns Result<_, RepoError>. The enum is
#[non_exhaustive], so match with a _ arm.
What can I match on?¶
The variant shape is the public contract. The cause string is not: it
carries whatever gix or git stderr said, and it changes when the backend
changes. Assert on matches!(err, RepoError::OpenFailed { .. }), never on the
text.
RepoError does not implement Clone, unlike ProviderError. It holds a
live std::io::Error in the Io variant and a CredentialError in Auth.
Which method produces which variant?¶
| Variant | Produced by |
|---|---|
Io |
reserved; no method in the crate constructs it today |
OpenFailed |
open |
InitFailed |
init |
CloneFailed |
clone |
FetchFailed |
fetch |
CheckoutFailed |
checkout |
CommitFailed |
commit |
StatusFailed |
status |
WalkFailed |
walk, and blame |
DiffFailed |
diff |
PushFailed |
push |
RevspecNotFound |
walk, diff, blame, checkout |
DirtyWorkingTree |
checkout |
Auth |
clone, fetch, push |
OpenFailed / InitFailed¶
Codes rtb_forge::git::open_failed and rtb_forge::git::init_failed. path is
the path you passed. cause is gix's stringified error, or a
spawn_blocking join error: … string if the background task itself failed.
OpenFailed is what you get for a directory that is not a repository, and for
a repository whose .git cannot be read.
CloneFailed¶
Code rtb_forge::git::clone_failed. The cause prefix tells you how far it
got:
| Prefix | Stage |
|---|---|
prepare: … |
gix could not parse the URL or prepare the destination |
fetch: … |
gix refs negotiation or object download failed |
checkout: … |
gix could not write the working tree |
spawn \git clone`: …| thegit` binary could not be launched (authenticated clones only) |
|
git clone: … |
git clone exited non-zero; the rest is its stderr |
open post-clone: … |
the clone succeeded but the result could not be opened |
FetchFailed / PushFailed¶
Codes rtb_forge::git::fetch_failed and rtb_forge::git::push_failed. cause
is either spawn \git …`: orgit …:
When a spawn_blocking join fails, remote and refspec are the empty
string rather than the values you passed, because the owned copies were moved into
the failed task. Do not rely on those fields being populated in every case.
CheckoutFailed¶
Code rtb_forge::git::checkout_failed. Reached when git checkout exits
non-zero for a reason that does not look like a missing revspec. See
RevspecNotFound below for how that call is made.
CommitFailed¶
Code rtb_forge::git::commit_failed. There is no path or message field;
everything is in cause:
cause |
Meaning |
|---|---|
no paths supplied — commit requires at least one path to stage |
you passed an empty slice |
spawn \git add`: …| thegit` binary is missing or not executable |
|
git add: … |
git add rejected a path |
git commit: … |
nothing staged, no configured identity, a hook refused, … |
git rev-parse: … |
the commit was created but its OID could not be read |
oid utf-8: … |
git rev-parse produced non-UTF-8 output |
Note the ordering: a git rev-parse failure means the commit did happen.
Do not treat CommitFailed as proof the repository is unchanged.
StatusFailed / WalkFailed / DiffFailed¶
Codes rtb_forge::git::status_failed, rtb_forge::git::walk_failed,
rtb_forge::git::diff_failed.
WalkFailed covers more than its name suggests. It is produced by:
walkfor an unsupported revspec kind, withunsupported revspec kind: ….walkfor object-store failures partway through, delivered as anErritem on the stream rather than from thewalk()call itself.blamefor every failure that is not a missing revspec: resource-cache setup, commit lookup, gix-blame internals. There is noBlameFailedvariant.
RevspecNotFound¶
Code rtb_forge::git::revspec_not_found. Produced by walk, diff, blame
and checkout.
The revspec field is not always a bare revspec:
- From
blame, a missing file is reported asRevspecNotFoundwith arevspecof the form<file path> at <revspec>. There is no separate file-not-found variant, so you cannot distinguish "bad revision" from "file absent at that revision" by variant alone. - From
checkout, the classification comes from matchinggit's stderr againstdid not match any,unknown revision,not a valid object nameandpathspec. Under a non-English locale those phrases do not appear and the same situation arrives asCheckoutFailedinstead.
DirtyWorkingTree¶
Code rtb_forge::git::dirty_working_tree. Carries paths: Vec<PathBuf>, the
staged bucket first, then the unstaged one.
Only checkout with force = false produces it. Because
RepoStatus::staged is always empty,
the staged half contributes nothing and the list is effectively the unstaged
paths.
Auth¶
Code rtb_forge::git::auth. Wraps rtb_credentials::CredentialError as a
#[source], so the underlying reason (env var unset, keychain locked, literal
refused under CI=true) is available through std::error::Error::source.
This variant means the credential could not be resolved locally. It does
not mean the remote rejected it: a token the server refuses produces
CloneFailed / FetchFailed / PushFailed carrying git's stderr.