Skip to main content

Repo

Struct Repo 

Source
pub struct Repo<R: ProcessRunner = JobRunner> { /* private fields */ }
Expand description

A cwd-bound, backend-agnostic VCS handle. Operations run against the bound directory (cwd); use at to get a sibling handle bound elsewhere.

Implementations§

Source§

impl Repo<JobRunner>

Source

pub fn discover(dir: impl AsRef<Path>) -> Result<Self>

Discover the repository at or above dir and open a handle bound to dir, using the real job-backed runner. Walks up from dir toward the filesystem root — see discover — so it finds a repository whose root is dir itself or any ancestor. Errors with Error::NotARepository when no .git/.jj is found, or with Error::BareRepository when the walk instead reaches a bare git repository (git init --bare) before any .jj/.git — a bare repo has no working tree for this facade to drive (issue #6).

For a strict check of exactly dir — no walking up — see Repo::open.

Source

pub fn open(dir: impl AsRef<Path>) -> Result<Self>

Open the repository at exactly dir — unlike Repo::discover, this does not walk up through parent directories: dir itself must hold the .jj/.git marker (a .jj directory with a repo entry, or a .git directory / gitlink file — the same validated markers discover uses), or this errors with Error::NotARepository(dir) even if a repository exists somewhere above dir. Mirrors the discover-vs-open split in gitoxide (gix::discover vs gix::open) and libgit2 (git_repository_discover vs git_repository_open) — see issue #8.

If dir itself is a bare git repository (git init --bare: no .git subdirectory, just HEAD/config/objects/refs directly in dir — see is_bare_git_repo_marker), this errors with Error::BareRepository(dir) instead of the generic NotARepository, matching what Repo::discover reports for the same directory (issue #6) — open still never walks up, so this only applies to dir itself, not an ancestor.

Source§

impl<R: ProcessRunner> Repo<R>

Source

pub fn from_git( root: impl Into<PathBuf>, cwd: impl Into<PathBuf>, client: Git<R>, ) -> Self

Build a git-backed handle from an explicit client — for a custom runner (e.g. a test seam) or a pre-configured Git.

Source

pub fn from_jj( root: impl Into<PathBuf>, cwd: impl Into<PathBuf>, client: Jj<R>, ) -> Self

Build a jj-backed handle from an explicit client.

Source

pub fn discover_with<G, J>(dir: impl AsRef<Path>, git: G, jj: J) -> Result<Self>
where G: FnOnce() -> Git<R>, J: FnOnce() -> Jj<R>,

Discover the repository at or above dir — exactly as Repo::discover — but build the handle from a caller-injected client instead of the plain default one. dir is absolutised and walked toward the filesystem root (see discover), then the factory for the detected backend is invoked: git for a .git repository, jj for a .jj one. Only the matching closure runs — the other is never called, so neither client is built speculatively.

This is the injected-client counterpart of Repo::discover: reach for it when the handle needs a pre-configured client — a hardened Git, a per-command timeout, a custom ProcessRunner test seam — rather than the default Git::new / Jj::new that Repo::discover uses. It shares Repo::discover’s exact detection and error classification, so a consumer no longer has to re-implement the discover walk, match BackendKind, and assemble from_git / from_jj by hand just to inject clients.

Because the match on BackendKind lives here, inside the crate that declares the enum #[non_exhaustive], adding a future backend variant is a change to this one method — callers need no wildcard/catch-all arm of their own to keep in sync.

§Errors

The same as Repo::discover: Error::NotARepository when no .git/.jj marker is found from dir up to the filesystem root, or Error::BareRepository when the walk instead reaches a bare git repository (git init --bare) first. It reuses the very same private find_bare_git_repo diagnostic path as Repo::discover, so the bare-repo distinction is reported identically no matter which entry point opened the repository.

// A hardened git client / timeout-bound jj client, injected lazily — only
// the one matching the detected backend is ever built.
let repo = Repo::discover_with(
    ".",
    || Git::hardened().default_timeout(Duration::from_secs(120)),
    || Jj::new().default_timeout(Duration::from_secs(120)),
)?;
Source

pub fn kind(&self) -> BackendKind

Which backend drives this handle.

Source

pub fn root(&self) -> &Path

The repository root detected at open time.

Source

pub fn cwd(&self) -> &Path

The directory operations run against.

Source

pub fn at(&self, dir: impl Into<PathBuf>) -> Self

A sibling handle bound to dir, sharing this handle’s client and root.

Source

pub fn git(&self) -> Option<&Git<R>>

The underlying Git client, or None when jj-backed — an escape hatch to git-only operations not on the common surface.

Source

pub fn jj(&self) -> Option<&Jj<R>>

The underlying Jj client, or None when git-backed.

Source

pub fn git_at(&self) -> Option<GitAt<'_, R>>

The git client bound to this handle’s cwd — a GitAt whose methods omit the dir argument — or None when jj-backed. The dir-free counterpart of git: repo.git_at()?.merge_continue().await?.

The returned view borrows self. To work in another worktree, bind the re-anchored handle first (the view can’t outlive a temporary at):

let wt = repo.at(wt);          // owns the re-anchored handle
let git = wt.git_at().unwrap();
git.fetch().await?;
Source

pub fn jj_at(&self) -> Option<JjAt<'_, R>>

The jj client bound to this handle’s cwd — a JjAt whose methods omit the dir argument — or None when git-backed. The dir-free counterpart of jj. For another workspace, bind the re-anchored handle first (let ws = repo.at(path); ws.jj_at()…) — see git_at.

Source

pub async fn current_branch(&self) -> Result<Option<String>>

The current branch (git) or bookmark (jj). On jj this is the nearest bookmark reachable from the working copy (heads(::@ & bookmarks())), so it stays set across a jj describe/jj new/jj commit — which leave the bookmark on the described parent while the new change carries none — matching git’s “still on my branch” reporting. When several bookmarks are equally near @, the lexicographically-smallest name is returned (deterministic). None only when detached / no bookmark on or above @.

Source

pub async fn trunk(&self) -> Result<Option<String>>

The trunk branch/bookmark. Resolution order: the backend’s own notion (git’s origin/HEAD, jj’s trunk() revset), then a fallback to a local main, then master; None when none of those resolve.

Source

pub async fn local_branches(&self) -> Result<Vec<String>>

Local branch (git) / bookmark (jj) names.

Backend divergence: on jj, a bookmark deleted locally but still tracked on a remote renders as a tombstone row (jj keeps it internally so the deletion can be propagated) until the deletion is pushed. This tombstone is filtered out here — a name a delete_branch just removed does not reappear in the result — while a conflicted bookmark (present, but with no single normal target) is still reported as existing, since dropping it too would hide a real, live bookmark that merely has a conflict (T-041; was M21).

Source

pub async fn local_branches_readonly(&self) -> Result<Vec<String>>

A read-only local_branches: the same result, but on jj it passes --ignore-working-copy, so listing the bookmarks records no jj operation and never moves @. On git it is exactly local_branches — git’s branch listing records no operation and moves no ref, so there is nothing to make read-only.

Use it (with snapshot_readonly) from an observer — a watcher or a prompt refresh — that must not perturb the state it reads. See snapshot_readonly for the jj working-copy trade-off this shares.

Source

pub async fn branch_exists(&self, name: &str) -> Result<bool>

Whether a local branch/bookmark named name exists. See local_branches for the jj deleted-but-tracked tombstone divergence: on jj, a bookmark just removed by delete_branch but still tracked on a remote does not read as existing here (the tombstone is filtered), while a conflicted bookmark still does.

Source

pub async fn has_uncommitted_changes(&self) -> Result<bool>

Whether the working copy has uncommitted changes (git: a non-empty status; jj: a non-empty working-copy change @).

Source

pub async fn has_tracked_changes(&self) -> Result<bool>

Whether the working copy has uncommitted changes to tracked files.

Backend nuance: git ignores untracked files here (status --untracked-files=no); jj auto-tracks new files, so there is no untracked concept and this equals has_uncommitted_changes.

Source

pub async fn conflicted_files(&self) -> Result<Vec<PathBuf>>

Paths with unresolved merge conflicts in the working copy, repo-relative with / separators (git diff --diff-filter=U / jj resolve --list -r @). Empty when there are none. Each path is a PathBuf carried losslessly from the backend, so a non-UTF-8 conflicted filename (legal on Unix) is not corrupted to U+FFFD.

Source

pub async fn create_branch(&self, name: &str) -> Result<()>

Create a local branch (git) / bookmark (jj) at the current head, without switching the working copy (git branch <name>; jj bookmark create <name> -r @).

Source

pub async fn delete_branch(&self, spec: BranchDelete) -> Result<()>

Delete a local branch (git) / bookmark (jj). The BranchDelete spec’s force applies to git only (branch -D vs -d); jj has no force and ignores it.

Source

pub async fn rename_branch(&self, old: &str, new: &str) -> Result<()>

Rename a local branch (git) / bookmark (jj).

Source

pub async fn changed_files(&self) -> Result<Vec<FileChange>>

The working-copy changes (git status / jj diff -r @ --summary).

Source

pub async fn diff_stat(&self) -> Result<DiffStat>

Aggregate insertion/deletion counts for the working copy.

Backend nuance: git counts the working tree against HEAD (git diff, which excludes untracked files), while jj counts the @ change against its parent (which includes newly-added files). So on git a brand-new file shows in changed_files but not here, whereas on jj it shows in both. On an unborn git repo (no commits yet) the count is taken against the empty tree, so a pre-first-commit working tree stats instead of erroring.

jj snapshot caveat: like every other jj-backed read here (status, changed_files, snapshot, log, …), this runs a plain jj diff — jj’s default mode, which first snapshots the working copy (imports any bare filesystem edit into a fresh @) and records a new operation in the op log. That is a bookkeeping side effect, not a content mutation (no tracked file/ref changes, and it is transparently undoable via jj op undo), but it is not a no-op read either. A genuinely non-recording read exists (--ignore-working-copy, wired up as vcs_jj’s _ignoring_working_copy client methods and this crate’s snapshot_readonly / local_branches_readonly, built for vcs-watch’s polling loop) but is deliberately not used here: it reports the state of the last recorded operation rather than the live working tree, so a bare edit no jj command has yet snapshotted would be silently invisible — wrong for a method whose whole purpose is reporting the current working-copy state.

Source

pub async fn diff(&self) -> Result<Vec<FileDiff>>

The full parsed diff for the working copy — the same scope as diff_stat (git: working tree vs HEAD, using the empty-tree oid on an unborn repo; jj: @ vs its parent), but returning the per-file hunks/lines (FileDiff) rather than just the aggregate counts. Dispatches to the already-existing GitApi::diff/JjApi::diff with vcs_git::DiffSpec::WorkingTree, so it inherits the backend client’s OutputBudget — an over-budget diff errors with OutputTooLarge rather than buffering (or silently truncating) an unbounded diff.

Backend nuance (same as diff_stat): git diffs the working tree against HEAD, which excludes untracked files; jj diffs @ against its parent, which includes newly-added files. So a brand-new file shows in changed_files but not here on git, whereas on jj it shows in both — don’t assume the two backends return the same file set.

Cross-backend revision-range diffs are deliberately not exposed here (see the crate docs’ “what’s deliberately not unified” — range diffs stay on the raw git/jj client, via GitApi::diff/ JjApi::diff with DiffSpec::Rev).

Same jj snapshot caveat as diff_stat: on jj this is a plain jj diff -r @ --git, jj’s default working-copy-snapshotting mode (records an operation in the op log — a reversible bookkeeping side effect, not a tracked-content mutation), deliberately not the non-recording --ignore-working-copy mode, which would make this method blind to any not- yet-snapshotted edit.

Source

pub async fn log( &self, revspec_or_revset: &str, max: usize, ) -> Result<Vec<Commit>>

Recent history: up to max commits reachable from revspec_or_revset (git revspec / jj revset), most-recent-first (git log’s default order / jj log’s topological order).

Backend nuance: Commit::author/Commit::date are Some only on git — jj’s typed log doesn’t currently surface authorship or a timestamp, so they’re None there rather than guessed (see the Commit type docs).

Source

pub async fn annotate( &self, path: &str, rev: Option<&str>, ) -> Result<Vec<AnnotationLine>>

Per-line attribution for path, optionally at rev (a git revspec / jj revset). None reads the current git HEAD / jj @; a supplied revision is passed to the selected backend without facade-level interpretation.

Backend nuance: AnnotationLine::author/AnnotationLine::date are Some only on git — jj’s typed annotation exposes only the introducing change and line content, so the facade leaves them None rather than guessing (see AnnotationLine).

Source

pub async fn show_file(&self, rev: &str, path: &str) -> Result<String>

The content of path as it exists at rev (git revspec / jj revset), e.g. HEAD:src/lib.rs on git or @- + a fileset on jj — both normalise backslash path separators and return the file’s bytes verbatim (including any trailing newline).

Source

pub async fn show_file_within( &self, rev: &str, path: &str, budget: OutputBudget, ) -> Result<String>

show_file with an explicit per-call OutputBudget, instead of the budget the backend client was built with (default_output_budget, inherited through from_git/from_jj). Reads the blob under budget: past the ceiling it errors with an OutputTooLarge-carrying Error::Vcs (actual and allowed sizes) rather than buffering an unbounded file — use it to read a legitimately large file (OutputBudget::unlimited, or a higher cap) or to tighten the cap for one call. A truncated blob is never returned as if complete.

Source

pub async fn snapshot(&self) -> Result<RepoSnapshot>

A batched RepoSnapshot of the common repo state — branch, upstream, ahead/behind, dirtiness, change count, and operation state — in a small fixed number of spawns instead of a call per field (git: status --porcelain=v2 --branch + the in-progress probe; jj: a log -r @ template for head/empty/conflict, a reachable_bookmarks query for branch, and a change count only when dirty). Built for prompt/status-bar/ TUI refreshes. Note the asymmetry: tracking (the upstream ref + ahead/behind) is always None on jj, which has no git-style upstream tracking.

Source

pub async fn snapshot_readonly(&self) -> Result<RepoSnapshot>

A read-only snapshot: the same RepoSnapshot, but on jj it never snapshots the working copy — every underlying query passes --ignore-working-copy, so the batched read records no jj operation and never moves @. On git it is exactly snapshot (git’s status query records no operation and moves no ref).

Use it for an observer — a repository watcher, a prompt/status-bar refresh — that must not perturb the state it reports: an ordinary jj query snapshots the working copy as a side effect (taking the lock, recording an operation, possibly moving @), so the observer would otherwise mutate the repo it merely means to read.

jj trade-off: because the working copy isn’t snapshotted, a bare working-tree edit that no jj command has recorded yet is not reflected — dirty/head are as of the last recorded operation. To observe such unsnapshotted edits, accept the mutation and call snapshot.

Source

pub async fn commit_paths(&self, paths: &[PathBuf], message: &str) -> Result<()>

Commit exactly paths with message (git commit --only, jj commit <filesets>). Paths are repo-relative. paths must be non-empty: an empty set is refused up front, because the backends would diverge dangerously — git errors out, while jj’s commit with no filesets would silently commit the entire working copy.

Takes PathBufs so a path obtained from changed_files / conflicted_files round-trips losslessly — on git a non-UTF-8 path (legal on Unix) reaches the commit unchanged via the NUL-safe pathspec transport; on jj the fileset language is text, so jj’s own (non-UTF-8-incapable) fileset handling applies.

Source

pub async fn fetch(&self) -> Result<()>

Fetch from the default remote (git fetch / jj git fetch).

Source

pub async fn fetch_from(&self, remote: &str) -> Result<()>

Fetch from a named remote (git fetch <remote> / jj git fetch --remote <remote>). Transient network failures are retried by the underlying client.

Source

pub async fn fetch_branch(&self, branch: &str) -> Result<()>

Fetch a single branch/bookmark from origin into its remote-tracking ref (git fetch_branch / jj git fetch -b). Transient network failures are retried by the underlying client.

Source

pub async fn push(&self, branch: &str) -> Result<()>

Push branch to origin (git push -u origin <branch> / jj git push -b <branch>).

The branch (jj: bookmark) must already exist locally. The two backends honestly differ in what “push” means: git pushes the ref and records the upstream (-u; idempotent on repeat pushes), while jj pushes the bookmark’s state — including deleting the remote branch if the bookmark was deleted locally. Renamed refspecs (local:remote) and non-origin remotes are git-only concepts; use the git() escape hatch (vcs_git::GitPush) for those.

Source

pub async fn checkout(&self, reference: &str) -> Result<()>

Switch the working copy to reference (git checkout / jj edit).

Backend divergence — this is not “detach and build on top” on jj. On git, a subsequent commit appends on top of reference (its tip is untouched). On jj, checkout maps to jj edit, which makes reference’s commit itself the working-copy change — so a following commit_paths (or any edit) rewrites that commit in place (a new change-id, a replaced description), silently amending a possibly-already-pushed commit rather than adding a new one.

So backend-agnostic “start fresh work on top of main” code must not rely on checkout alone. If you want git-like append-on-top semantics on both backends, use new_child, which maps to jj new <reference> on jj and to checkout <reference> on git.

Source

pub async fn new_child(&self, reference: &str) -> Result<()>

Start new work on top of reference without modifying it.

On git this checks out reference; the next commit naturally appends on top. On jj this runs jj new <reference>, creating an undescribed child change.

Source

pub async fn rebase(&self, onto: &str) -> Result<()>

Rebase the current line onto onto. The two backends diverge on non-linear layouts, so this is a documented least-common-denominator:

  • git (rebase <onto> = merge-base(HEAD,onto)..HEAD) moves only HEAD’s own ancestor line; commits stacked on HEAD stay put.
  • jj (rebase -d <onto> = the default -b @ = (onto..@)::) moves that line and its whole descendant closure — anything stacked on @, and any sibling off an intermediate commit of the line, move too.

They agree on a linear HEAD/@; on a stacked or intermediate-fork layout jj moves strictly more. A sibling that shares only the fork point is moved by neither. onto is a branch/bookmark name or revision the backend understands.

Source

pub async fn try_merge(&self, source: &str) -> Result<MergeProbe>

Probe whether merging source into the current work would conflict, without leaving any trace: the probe is rolled back before returning (git: merge --no-commit --no-ff then merge --abort; jj: a merge change probed and undone via op restore).

Preconditions/behaviour:

  • git: requires a clean-enough working tree — a dirty-tree refusal propagates as a plain error, not as MergeProbe::Conflicts.
  • A failing rollback propagates as an error rather than returning a result that misdescribes the on-disk state.
  • Cancellation-safe rollback: on both backends the whole rollback path — the decision of whether to roll back and the command that performs it — runs on a fresh cancellation context with its own bounded deadline (git: Git::is_merge_in_progress_detached + merge --abort via Git::merge_abort_detached; jj: the op-log probe + op restore via Jj::rollback_to), so a default_cancel_on token (the cancellation feature) that fires during the probe no longer cancels the rollback too — not even by cancelling the “is a trial merge still staged?” check before the abort is reached. The trial merge is still undone rather than left staged, closing the gap where a cancelled probe abandoned it on git. (A rollback that fails for another reason still propagates per the bullet above.)
Source

pub async fn abort_in_progress(&self) -> Result<OperationState>

Abort the in-progress operation, if any (git: merge --abort / rebase --abort; jj: a no-op — there are no paused operations, roll back explicitly via Jj::transaction / op_restore). Returns the fresh post-call OperationState; Clear when nothing was (or remains) in progress.

Source

pub async fn continue_in_progress(&self) -> Result<OperationState>

Continue the in-progress operation after conflict resolution (git: commit --no-edit for a merge, or the matching --continue for a rebase / am / cherry-pick / revert; jj: a no-op — resolving the files is the continuation). A git bisect has no such step and is refused with Error::Unsupported rather than silently reported still in progress. Returns the fresh post-call OperationState:

  • Conflict when unresolved paths still block continuing (also on git — unlike in_progress_state, this method does report Conflict for git), or when a continued rebase stops on the next patch’s conflict.
  • Clear when the operation finished.
Source

pub async fn in_progress_state(&self) -> Result<OperationState>

Whether the working copy is mid-operation or conflicted — see OperationState. Lets a caller decide between abort/continue without knowing the backend’s model. Note the asymmetry: this method reports Merge/Rebase (never Conflict) on git — a git conflict is that paused state, and the conflict itself surfaces on the failed op via Error::is_merge_conflict (or as Conflict from continue_in_progress) — while jj has no paused op and reports Conflict directly.

Source

pub async fn list_worktrees(&self) -> Result<Vec<WorktreeInfo>>

List attached worktrees (git) / workspaces (jj).

Source

pub async fn create_worktree( &self, spec: WorktreeCreate, ) -> Result<CreateOutcome>

Create a worktree/workspace at path on a new branch based on base. Always CreateOutcome::Plain; a copy-on-write strategy stays in the consumer.

branch must not already exist. The jj path is two steps (workspace add then bookmark create) and is not atomic, but a failed bookmark step rolls back: the workspace directory is removed only when workspace add created it (a pre-existing directory the caller already had is left intact), then the workspace is forgotten. Residue is no longer swallowed: if the rollback can’t remove that directory or can’t forget the workspace, the call fails with a composite Error::Io naming what still needs cleaning up (and is safe to re-run); a clean rollback instead surfaces the original bookmark-step error unchanged (its Error::Vcs classification) — so a failed call never silently leaks a half-made worktree.

Source

pub async fn remove_worktree(&self, spec: WorktreeRemove) -> Result<()>

Remove the worktree/workspace at path. For jj this resolves the workspace name by matching path, deletes the directory, then forgets it; a path that matches none of the resolvable jj workspaces returns Error::WorktreeNotFound, but when some registered workspace can’t be resolved via jj workspace root --name the path’s absence is unprovable, so a distinct diagnosable Error::Io (naming the unresolved workspaces; is_resource_not_found stays false) is returned instead. A directory that can’t be deleted is likewise surfaced (an Error::Io naming the still-registered workspace, with the forget left for the retry). (For the short-lived, blocking Drop-path variant, see cleanup_worktree_blocking.)

The WorktreeRemove spec’s force mirrors git’s worktree remove: without it a worktree that still has uncommitted changes is refused (Err) rather than deleted, so a stray edit isn’t silently lost — build WorktreeRemove::new(path).force() to remove it anyway. On jj the changes are snapshotted into the op log before the check, so a refusal keeps them recoverable; note that checking spawns a jj command in the target workspace, so a genuinely stale working copy can surface an error without force (use .force() there). The repository’s main workspace is always refused (it can’t be removed without destroying the repo), regardless of force.

Source

pub fn cleanup_worktree_blocking(&self, path: &Path) -> Result<()>

Synchronous worktree cleanup for a context that cannot .await — chiefly a Drop guard. Force-removes the worktree at path (git: worktree remove --force; jj: resolve the workspace name by path, delete the directory, then workspace forget). Short-lived and shells out directly (no job-containment), but not error-swallowing: a jj path that genuinely matches no workspace is an Ok no-op, yet a probe failure (the workspace list, or a registered workspace that won’t resolve) and a remove_dir_all failure are surfaced as Err (the forget is skipped on a failed removal, so a surviving directory isn’t orphaned). Like the async remove_worktree, it refuses the repository’s main workspace (whose directory is the main working copy) — deleting it would wipe the repo — even on this force-by-contract path.

Trait Implementations§

Source§

impl<R: ProcessRunner> Debug for Repo<R>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<R: ProcessRunner> VcsRepo for Repo<R>

Source§

fn kind(&self) -> BackendKind

Which backend drives this handle.
Source§

fn root(&self) -> &Path

The repository root detected at open time.
Source§

fn cwd(&self) -> &Path

The directory operations run against.
Source§

fn cleanup_worktree_blocking(&self, path: &Path) -> Result<()>

Source§

fn current_branch<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn trunk<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn local_branches<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn local_branches_readonly<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn branch_exists<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn has_uncommitted_changes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn has_tracked_changes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn conflicted_files<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<PathBuf>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn create_branch<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn delete_branch<'life0, 'async_trait>( &'life0 self, spec: BranchDelete, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn rename_branch<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, old: &'life1 str, new: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn changed_files<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<FileChange>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn diff_stat<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<DiffStat>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn diff<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<FileDiff>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn log<'life0, 'life1, 'async_trait>( &'life0 self, revspec_or_revset: &'life1 str, max: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<Commit>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn show_file<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, rev: &'life1 str, path: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn annotate<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, path: &'life1 str, rev: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<Vec<AnnotationLine>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn show_file_within<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, rev: &'life1 str, path: &'life2 str, budget: OutputBudget, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn snapshot<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<RepoSnapshot>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn snapshot_readonly<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<RepoSnapshot>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn commit_paths<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, paths: &'life1 [PathBuf], message: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source§

fn fetch<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn fetch_from<'life0, 'life1, 'async_trait>( &'life0 self, remote: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn fetch_branch<'life0, 'life1, 'async_trait>( &'life0 self, branch: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn push<'life0, 'life1, 'async_trait>( &'life0 self, branch: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn checkout<'life0, 'life1, 'async_trait>( &'life0 self, reference: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn new_child<'life0, 'life1, 'async_trait>( &'life0 self, reference: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn rebase<'life0, 'life1, 'async_trait>( &'life0 self, onto: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn try_merge<'life0, 'life1, 'async_trait>( &'life0 self, source: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<MergeProbe>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source§

fn abort_in_progress<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<OperationState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn continue_in_progress<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<OperationState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn in_progress_state<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<OperationState>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn list_worktrees<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<WorktreeInfo>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn create_worktree<'life0, 'async_trait>( &'life0 self, spec: WorktreeCreate, ) -> Pin<Box<dyn Future<Output = Result<CreateOutcome>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source§

fn remove_worktree<'life0, 'async_trait>( &'life0 self, spec: WorktreeRemove, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Auto Trait Implementations§

§

impl<R = JobRunner> !RefUnwindSafe for Repo<R>

§

impl<R = JobRunner> !UnwindSafe for Repo<R>

§

impl<R> Freeze for Repo<R>

§

impl<R> Send for Repo<R>

§

impl<R> Sync for Repo<R>

§

impl<R> Unpin for Repo<R>

§

impl<R> UnsafeUnpin for Repo<R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more