pub trait Vcs {
// Required methods
fn resolve_identity(&self, origin_or_path: &str) -> Result<Identity>;
fn open_session(&self, req: SessionRequest) -> Result<Session>;
fn adopt_session(&self, token: SessionToken) -> Result<Session>;
fn session(&self, token: &SessionToken) -> Result<SessionRecord>;
fn close_session(&self, token: &SessionToken) -> Result<Session>;
fn preserve(
&self,
s: &Session,
provenance: Provenance,
) -> Result<PreservedBranch>;
fn publish(
&self,
token: &SessionToken,
request: &PublishRequest,
hosting: &dyn Hosting,
) -> Result<Publication>;
fn recoverable(&self, scope: Scope) -> Result<Vec<Recoverable>>;
fn preserved(&self, scope: Scope) -> Result<Vec<Recoverable>>;
// Provided methods
fn publish_with_cancellation(
&self,
token: &SessionToken,
request: &PublishRequest,
hosting: &dyn Hosting,
cancellation: &dyn PublicationCancellation,
) -> Result<Publication> { ... }
fn recoverable_matching(
&self,
scope: Scope,
selection: &Selection,
) -> Result<Vec<Recoverable>> { ... }
fn preserved_matching(
&self,
scope: Scope,
selection: &Selection,
) -> Result<Vec<Recoverable>> { ... }
}Expand description
Everything onevcs does to a repository, independent of which version
control system is underneath.
The session record belongs here rather than beside it. It was written by Git
directly for three releases, and the cost was exact: a session a supplied
implementation had just opened was refused by publish and by session close
as a session nobody opened, so the seam was declared and those commands went
around it.
Required Methods§
Sourcefn resolve_identity(&self, origin_or_path: &str) -> Result<Identity>
fn resolve_identity(&self, origin_or_path: &str) -> Result<Identity>
Resolve an origin URL or a checkout path to the repository identity it belongs to.
Sourcefn open_session(&self, req: SessionRequest) -> Result<Session>
fn open_session(&self, req: SessionRequest) -> Result<Session>
Open a session: a clone of an execution checkout and an isolated worktree cut from it — a warm pool slot where the host keeps one, else cut for this run — held under an occupancy lease.
Sourcefn adopt_session(&self, token: SessionToken) -> Result<Session>
fn adopt_session(&self, token: SessionToken) -> Result<Session>
Re-attach to a session that already exists, claiming its free occupancy lease.
Sourcefn session(&self, token: &SessionToken) -> Result<SessionRecord>
fn session(&self, token: &SessionToken) -> Result<SessionRecord>
What this implementation recorded about a session it opened.
Sourcefn close_session(&self, token: &SessionToken) -> Result<Session>
fn close_session(&self, token: &SessionToken) -> Result<Session>
Release a session’s worktree and its lease, keeping its branch.
Sourcefn preserve(
&self,
s: &Session,
provenance: Provenance,
) -> Result<PreservedBranch>
fn preserve( &self, s: &Session, provenance: Provenance, ) -> Result<PreservedBranch>
Commit the session’s work onto a branch that outlives it, recording why.
Sourcefn publish(
&self,
token: &SessionToken,
request: &PublishRequest,
hosting: &dyn Hosting,
) -> Result<Publication>
fn publish( &self, token: &SessionToken, request: &PublishRequest, hosting: &dyn Hosting, ) -> Result<Publication>
Verify a session’s branch and land it under its repository’s policy.
The one operation that reaches both interfaces — the repository side lands the change and the host side opens and merges the change request — so the host factory travels with the request rather than being reached for.
Sourcefn recoverable(&self, scope: Scope) -> Result<Vec<Recoverable>>
fn recoverable(&self, scope: Scope) -> Result<Vec<Recoverable>>
Every preserved-but-unpublished branch in scope, and what would land each.
Unpublished is decided from history rather than inferred from content, and a
branch whose work reached the base is not one of these — including one the
base has moved a long way past since. The row that offered such a branch a
paste-ready publish-branch is what this excludes: following it re-opens a
change request for work the base already carries. A branch nothing can decide
about is still here, because it may be work nobody published; what it does not
carry is a command anybody should paste without looking.
Sourcefn preserved(&self, scope: Scope) -> Result<Vec<Recoverable>>
fn preserved(&self, scope: Scope) -> Result<Vec<Recoverable>>
Every preserved branch in scope, whatever became of its work, each saying what did become of it and what says so.
recoverable is this without the ones whose work is on
the base, and is what somebody asking “what is left to publish” wants. This is
what somebody asking “what became of all of it” wants, and it is the one place
a withheld branch is reported rather than silently dropped — an exclusion
nobody can see is how preserved work goes missing.
Required rather than defaulted to recoverable: the
default would answer the narrower question under this one’s name, and an
implementation whose wider answer is the same one has only to say so.
Provided Methods§
Sourcefn publish_with_cancellation(
&self,
token: &SessionToken,
request: &PublishRequest,
hosting: &dyn Hosting,
cancellation: &dyn PublicationCancellation,
) -> Result<Publication>
fn publish_with_cancellation( &self, token: &SessionToken, request: &PublishRequest, hosting: &dyn Hosting, cancellation: &dyn PublicationCancellation, ) -> Result<Publication>
publish, asking cancellation while it waits and ending as
FailureKind::Cancelled once it says so.
Defaulted to publish, so an implementation written before
cancellation existed still compiles and publishes — and is never cancelled,
which is the answer an implementation that cannot stop has to give: a backend
that does not override this cannot be cancelled mid-watch. Git
overrides it: every phase of its publication that waits asks the cancellation
at least once a second.
Sourcefn recoverable_matching(
&self,
scope: Scope,
selection: &Selection,
) -> Result<Vec<Recoverable>>
fn recoverable_matching( &self, scope: Scope, selection: &Selection, ) -> Result<Vec<Recoverable>>
recoverable, narrowed to the sessions a
Selection names.
Defaulted rather than required, and the default is the whole meaning: a row is
answered with when some session record of this host naming its branch is one
the selection picked — by token, by carrying every label pair asked for, or by
both. So every implementation narrows identically, and what an override buys is
not a different answer but a cheaper one: an implementation that knows where
it looks can decline to look, which is what Git does with it. A selection
that asks nothing is the whole report at Detail::Full. Detail::Decision
retains identical rows and semantic fields, including tip and the recovery
command; only presentation fields may be omitted. This is what every caller before this
existed asked for.
Sourcefn preserved_matching(
&self,
scope: Scope,
selection: &Selection,
) -> Result<Vec<Recoverable>>
fn preserved_matching( &self, scope: Scope, selection: &Selection, ) -> Result<Vec<Recoverable>>
preserved, narrowed the same way and for the same reason.
Selection::detail changes presentation cost only: both detail modes keep
the same rows, tip, landing evidence, holds, retirement and recovery command.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".