Skip to main content

Git

Struct Git 

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

The real Git client. Generic over the ProcessRunner so tests can inject a fake process executor; Git::new uses the real job-backed runner.

Wraps a ManagedClient: enable lock-contention retry with with_retry (opt-in; off by default).

Every client (not just hardened) scrubs the inherited repo-redirector environment variables below, so a GIT_DIR (etc.) leaking from the parent process — e.g. running inside a git hook, which exports GIT_DIR/GIT_INDEX_FILE — can’t silently redirect commands at a different repository than the bound dir. (harden() additionally scrubs the command-hook vars and pins hooks/fsmonitor/sshCommand off.)

Implementations§

Source§

impl Git<JobRunner>

Source

pub fn new() -> Self

Create a client driving the real job-backed runner.

Source§

impl<R: ProcessRunner> Git<R>

Source

pub fn with_runner(runner: R) -> Self

Create a client driving runner — inject a fake in tests.

Source

pub fn default_timeout(self, timeout: Duration) -> Self

Apply a default timeout to every command this client builds.

Source

pub fn default_env( self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>, ) -> Self

Set an environment variable on every command this client builds.

Source

pub fn default_env_remove(self, key: impl AsRef<OsStr>) -> Self

Remove an inherited environment variable on every command this client builds.

Source

pub fn default_cancel_on(self, token: CancellationToken) -> Self

Cancel every command this client builds when token fires.

Source

pub fn default_output_budget(self, budget: OutputBudget) -> Self

Apply a default OutputBudget to the potentially large content operations this client builds — the diff/show/pr-diff verbs and the clone/fetch diagnostic capture. Inherited by any facade built over this client. The default is OutputBudget::unlimited (retain everything); a single call can still override it via the *_within method variants.

Source§

impl<R: ProcessRunner> Git<R>

Source

pub fn with_retry(self, policy: RetryPolicy) -> Self

Retry whole-repo lock-contention failures (another process holds the repo’s index.lock) per policy — opt-in, off by default. Safe even for mutating commands: that lock is acquired before any write, so a failure is pre-execution (git never ran) and a retry can’t double-apply. Per-ref lock failures are not retried (a multi-ref op can fail a ref lock mid-way). See RetryPolicy and is_lock_contention.

Source

pub fn with_credentials(self, provider: Arc<dyn CredentialProvider>) -> Self

Supply credentials for HTTPS remote operations (fetch/push/clone/ ls-remote) via a CredentialProvider — opt-in, off by default (ambient git credential helpers / SSH agent). When the provider yields a credential, each remote op runs with an inline credential.helper that feeds the secret from an environment variable, so the token never appears in argv. Local operations are unaffected. This covers HTTPS only — an SSH remote ignores the helper and authenticates via the ambient SSH agent, as before.

Source

pub fn with_token(self, token: impl Into<Secret>) -> Self

Convenience for the common case: authenticate HTTPS remotes with a single static token (a personal-access token; the default username x-access-token is used). Shorthand for with_credentials(Arc::new(StaticCredential::token(token))). For a specific username, build a Credential::userpass and use with_credentials.

Source

pub fn with_env_token(self, var: impl Into<String>) -> Self

Convenience: read the HTTPS token from environment variable var at request time; if var is unset/empty, fall back to ambient auth. Shorthand for with_credentials(Arc::new(EnvToken::new(var))).

Source§

impl<R: ProcessRunner> Git<R>

Source

pub async fn diff_text_within( &self, dir: &Path, spec: DiffSpec, budget: OutputBudget, ) -> Result<String>

diff_text with an explicit per-call OutputBudget, instead of this client’s default_output_budget. Use it to read a legitimately large diff past a tighter client default (OutputBudget::unlimited, or a higher byte cap), or to tighten the cap for one call. Past the ceiling the read errors with Error::OutputTooLarge (actual and allowed sizes) rather than buffering an unbounded diff.

Source

pub async fn diff_within( &self, dir: &Path, spec: DiffSpec, budget: OutputBudget, ) -> Result<Vec<FileDiff>>

diff with an explicit per-call OutputBudget — the parsed-model counterpart of diff_text_within.

Source

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

show_file with an explicit per-call OutputBudget, instead of this client’s default_output_budget. Reads a blob’s bytes under budget: past the ceiling the read errors with Error::OutputTooLarge rather than buffering an unbounded file.

Source§

impl<R: ProcessRunner> Git<R>

Source

pub async fn run_args(&self, args: &[&str]) -> Result<String>

Run git <args> over string slices — git.run_args(&["status", "-s"]) without allocating a Vec<String>. Inherent (not on the object-safe trait), so it can take &[&str]; forwards to the same path as GitApi::run.

Source

pub async fn run_raw_args(&self, args: &[&str]) -> Result<ProcessResult<String>>

Like run_args but never errors on a non-zero exit (mirrors GitApi::run_raw).

Source

pub async fn run_in(&self, dir: &Path, args: &[String]) -> Result<String>

Run git <args> in dir (the process is spawned with dir as its working directory), returning trimmed stdout — the dir-bound twin of the process-cwd run. This is what GitAt::run forwards to; call run on the client for the process-cwd escape hatch. Argv is forwarded verbatim (the same unguarded escape hatch — only the working directory is bound, no -C/extra flag is injected).

Source

pub async fn run_raw_in( &self, dir: &Path, args: &[String], ) -> Result<ProcessResult<String>>

Like run_in but never errors on a non-zero exit — the dir-bound twin of run_raw. What GitAt::run_raw forwards to.

Source

pub async fn run_args_in(&self, dir: &Path, args: &[&str]) -> Result<String>

Like run_args but bound to dir — the &[&str] twin of run_in. What GitAt::run_args forwards to.

Source

pub async fn run_raw_args_in( &self, dir: &Path, args: &[&str], ) -> Result<ProcessResult<String>>

Like run_raw_args but bound to dir — the &[&str] twin of run_raw_in. What GitAt::run_raw_args forwards to.

Source

pub async fn empty_tree_oid(&self, dir: &Path) -> Result<String>

The empty-tree object id for the repository at dir, matching its active object format — the format-correct stand-in for HEAD when diffing/stat-ing the working tree of an unborn (no-commits-yet) repository.

Computed with git hash-object -t tree --stdin fed an empty stdin: an empty tree object is empty content, so git returns its id under whichever hash the repo uses (4b825dc… for SHA-1, a 64-hex digest for extensions.objectFormat= sha256). This asks git rather than hard-coding EMPTY_TREE_SHA1, which is wrong in a SHA-256 repo. --stdin (not -w) only computes the id — nothing is written to the object database.

Source

pub fn at<'a>(&'a self, dir: &'a Path) -> GitAt<'a, R>

Bind this client to dir, returning a GitAt handle whose methods omit the dir argument: git.at(dir).status() runs status against dir. The dir-taking GitApi methods stay on Git for driving many directories (e.g. linked worktrees) from one client.

Source

pub fn harden(self) -> Self

Harden this client for driving repositories it didn’t create: running git inside an untrusted checkout executes that repository’s hooks and honours its config — arbitrary code execution by default. The profile (applied to every command this client runs):

⚠ Requires git ≥ 2.31. The hook / fsmonitor / sshCommand pins ride git’s env-based config (GIT_CONFIG_COUNT), which older git silently ignores — so on git < 2.31 harden() still scrubs the environment and turns prompts off, but repo-local hooks/fsmonitor/sshCommand are not disabled (no error is raised). capabilities().ensure_supported() now enforces the ≥ 2.31 floor (major.minor), so a too-old git is rejected up front with a clear message instead of silently no-op-ing the pins — call it before relying on harden() against a fully untrusted repo on a host you don’t control, or add an OS-level sandbox. (docs/audit-2026-07.md H3, M29.)

  • Disables hookscore.hooksPath=/dev/null pinned via git’s env-based config (GIT_CONFIG_COUNT/KEY_n/VALUE_n, git ≥ 2.31; verified to suppress hooks on Windows too) — and core.fsmonitor (a config-driven daemon launch). Env-config overrides even the repo-local .git/config for the keys it names, so these pins beat a poisoned .git/config.
  • Neutralizes core.sshCommand (pinned empty) — the config-key twin of the scrubbed GIT_SSH_COMMAND, an arbitrary program git would run for the SSH transport. Empty is falsy to git, so the default ssh (ambient ~/.ssh/config/agent) still works; only the repo’s override is dropped.
  • Removes inherited repo redirectors so a poisoned parent environment can’t point commands at another repository: GIT_DIR, GIT_WORK_TREE, GIT_INDEX_FILE, GIT_COMMON_DIR, GIT_OBJECT_DIRECTORY, GIT_ALTERNATE_OBJECT_DIRECTORIES, GIT_NAMESPACE, GIT_CEILING_DIRECTORIES, GIT_CONFIG_PARAMETERS, GIT_CONFIG_GLOBAL, GIT_CONFIG_SYSTEM. (The first seven are also scrubbed by every client — see the type-level doc — not just here.)
  • Removes inherited command hooks that make git spawn an arbitrary program from the environment (a second code-execution path besides repo hooks): GIT_SSH_COMMAND/GIT_SSH (transport), GIT_ASKPASS (credential prompt), GIT_EXTERNAL_DIFF (diff driver), GIT_PAGER, GIT_EDITOR/GIT_SEQUENCE_EDITOR, GIT_PROXY_COMMAND (a program for a git:// connection), GIT_EXEC_PATH (relocates git’s own sub-commands), and GIT_TEMPLATE_DIR (seeds hooks/config on init/clone). It also drops the pathspec-mode vars (GIT_LITERAL_PATHSPECS / GIT_GLOB_PATHSPECS / GIT_NOGLOB_PATHSPECS / GIT_ICASE_PATHSPECS), which silently change which paths a command matches. The library’s own auth seam (with_credentials) injects credentials via a git credential.helper / token env, not these variables, so it keeps working through a hardened client; an operator who deliberately relies on an ambient GIT_SSH_COMMAND/GIT_ASKPASS should inject it per-call instead of inheriting it into an untrusted-repo run.
  • Skips system config (GIT_CONFIG_NOSYSTEM=1) and keeps terminal prompts off everywhere (GIT_TERMINAL_PROMPT=0).

Residual repo-local-config vectors (NOT neutralized). harden() closes the hooks, fsmonitor, core.sshCommand, and the env redirector/command- hook paths — but a few repo-local .git/config / .gitattributes keys still run an arbitrary program and are not pinned: filter.<drv>.clean/ smudge (run on any working-tree materialization — checkout, stash pop, worktree add), and diff.<drv>.textconv / diff.external (run when a diff is produced; diff_text defends itself with --no-ext-diff, but other diff/blame reads do not). So for a fully untrusted repo, do not materialize its working tree or run diffs through a hardened client without an OS-level sandbox — harden() is hardening, not a sandbox.

What it does NOT do beyond that: sandbox the git binary itself, or stop the repo’s content from being malicious. In a colocated jj repo, git hooks only run when git commands run — harden the Git client; Jj needs no equivalent (jj has no repo-local hooks; see the vcs-jj docs).

Chainable — Git::with_runner(rec).harden() works in tests; use Git::hardened() for the common case.

Source

pub async fn switch_with_stash( &self, dir: &Path, target: &CheckoutTarget, ) -> Result<()>

Switch to branch, carrying uncommitted changes (tracked and untracked) across via the stash: stash push -ucheckoutstash pop --index. --index restores the staged/unstaged split faithfully (a bare pop returns everything unstaged). A clean tree skips the round-trip; and because stash push can exit 0 having saved nothing (e.g. a submodule-only change), the stash-list depth is checked around the push so a no-op push doesn’t leave the later pop grabbing an older, unrelated stash.

Single-actor contract: this assumes no other process pushes or pops a stash in the same repository between this call’s own stash push and pop.

Failure behaviour:

  • checkout fails (atomic — the working copy stays on the original branch): the stash is popped back to restore the original state, and the checkout error is returned. If that restoring pop also fails, the changes stay safe in the stash (git stash list).
  • stash pop on the target branch conflicts: the error is returned with the target branch checked out; git keeps the stash entry, so the changes can be resolved or re-applied manually.

Inherent (not on the object-safe trait): a composed operation, not a 1:1 CLI verb — mock the underlying status/stash_*/checkout instead.

Source§

impl Git

Source

pub fn hardened() -> Self

A hardened real (job-backed) client — Git::new().harden(); see harden for what the profile does.

Trait Implementations§

Source§

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

Source§

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

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

impl Default for Git<JobRunner>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<R: ProcessRunner> GitApi for Git<R>

Source§

fn run<'life0, 'life1, 'async_trait>( &'life0 self, args: &'life1 [String], ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Run git <args> in the process’s current directory, returning trimmed stdout (throws on a non-zero exit). A raw escape hatch for unmodelled commands — you supply the whole argv, so target a specific repo with -C <dir> in the args. This method on the client is the process-cwd escape hatch; the at(dir) bound view’s run is instead bound to dir (it forwards to Git::run_in, so git.at(dir).run(…) runs in the bound repo). Use git.at(dir).run(…) (or Git::run_in) for the bound repo; use this for the process cwd (T-035, was M15).
Source§

fn run_raw<'life0, 'life1, 'async_trait>( &'life0 self, args: &'life1 [String], ) -> Pin<Box<dyn Future<Output = Result<ProcessResult<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like GitApi::run but never errors on a non-zero exit — returns the captured ProcessResult.
Source§

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

Installed Git version (git --version).
Source§

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

The installed binary’s parsed version, as GitCapabilities (git --version). A value type — probe once and keep it; an unrecognisable version string is an Error::Parse.
Source§

fn status<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<Vec<StatusEntry>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Working-tree status (git status --porcelain=v1 -z).
Source§

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

Raw porcelain status text (git status --porcelain=v1) — the unparsed counterpart of status, mirroring vcs_jj status_text.
Source§

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

A combined branch + working-tree snapshot in one spawn (git status --porcelain=v2 --branch -z): HEAD, branch, upstream, ahead/behind, and change counts — the data a prompt/status-bar needs without N round-trips. See BranchStatus.
Source§

fn status_tracked<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<Vec<StatusEntry>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like status but ignoring untracked files (git status --porcelain=v1 -z --untracked-files=no) — “is the tracked tree dirty”, staged or not.
Source§

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

Paths with unresolved merge conflicts, repo-relative with / separators (git diff --name-only --diff-filter=U -z). Empty when there are none. Returns PathBufs built from the raw -z bytes, so a non-UTF-8 conflicted path survives losslessly.
Source§

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

Current branch name, or None on a detached HEAD (git symbolic-ref --quiet --short HEAD). Returns the branch name for a normal branch and for an unborn branch (a fresh init/clone before the first commit); None only when HEAD is detached. Mirrors JjApi::current_bookmark’s Option shape, so cross-backend code treats “no named branch/bookmark” the same way on both wrappers.
Source§

fn branches<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<Vec<Branch>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Local branches, current one flagged (git branch).
Source§

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

Up to max commits reachable from revspec, newest first (git log <revspec>). Pass "HEAD" for the current branch’s history, or a range like "main..HEAD" / "origin/main..HEAD" to scope it. Mirrors JjApi::log’s revset argument, so cross-backend code uses one signature. The revspec is a validated RevSpec, so it can never be parsed as a flag.
Source§

fn log_paths<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, revspec: &'life2 RevSpec, max: usize, paths: &'life3 [String], ) -> Pin<Box<dyn Future<Output = Result<Vec<Commit>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Like log, but scoped to commits that touched paths (git --literal-pathspecs log <revspec> -n <max> -- <paths>) — e.g. “who changed this module”. --literal-pathspecs matches a path containing */?/[] literally rather than as pathspec glob magic (R-02); the -- separator keeps a path from being read as a flag (same convention as add/commit_paths). An empty paths is refused before spawning: silently falling back to log’s unrestricted history would defeat the “scoped to these paths” contract. Mirrors JjApi::log_paths, which takes filesets instead of pathspecs. Read more
Source§

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

Resolve a revision to a full hash (git rev-parse --verify <rev>). --verify requires rev to name exactly one object, so a non-revision (e.g. a filename) errors instead of being echoed back as a fake id.
Source§

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

Resolve a revision to its abbreviated hash (git rev-parse --short <rev>) — e.g. to label a detached HEAD.
Source§

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

Initialise a repository (git init).
Source§

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

Stage paths (git --literal-pathspecs add -- <paths>) — --literal-pathspecs applies regardless of path-set size, so a path containing */?/[] always matches literally rather than as pathspec glob magic (R-01). A path set whose combined length would risk exceeding the OS command-line limit (ARGV_PATHSPEC_BUDGET; Windows’ CreateProcess caps out around 32,767 characters) instead goes over stdin via --pathspec-from-file=- --pathspec-file-nul — the paths never touch argv at all in that case, so there is no upper bound left to exceed (T-052).
Source§

fn commit<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, 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,

Commit staged changes (git commit -m).
Source§

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

Create a branch without switching to it (git branch <name>).
Source§

fn checkout<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, target: &'life2 CheckoutTarget, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Switch to a branch/revision, or the previous branch (git checkout <target>); see CheckoutTarget.
Source§

fn checkout_detach<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, commit: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Check out a commit as a detached HEAD (git checkout --detach <commit>).
Source§

fn commit_paths<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: CommitPaths, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Commit exactly the spec’s paths’ working-tree content, ignoring the index (git --literal-pathspecs commit [--amend] -m <message> --only -- <paths>); see CommitPaths. --literal-pathspecs applies regardless of path-set size, so a glob-magic character (*/?/[]) in a path is matched literally rather than expanded — otherwise commit_paths’s “exactly these paths” contract could be violated (R-01). Like add, a path set that would risk exceeding the OS argv limit is instead routed over stdin (--pathspec-from-file=- --pathspec-file-nul) — always as a single git commit invocation either way, so the one-atomic-commit contract is unaffected by the path set’s size (T-052).
Source§

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

The last commit’s full message (git log -1 --format=%B) — e.g. to pre-fill an amend.
Source§

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

Whether HEAD is unborn — a fresh repo with no commits yet (git rev-parse --verify -q HEAD, exit-code mapped).
Source§

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

Whether the working tree has no unstaged modifications to tracked files (git diff --quiet). Untracked files are not counted — this is not a full “is the working tree clean?” check; use status for that.
Source§

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

The repository’s common git directory (rev-parse --git-common-dir) — stable across linked worktrees.
Source§

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

This worktree’s git directory (rev-parse --git-dir).
Source§

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

Resolve a revision to a commit hash, peeling tags (rev-parse --verify <rev>^{commit}).
Source§

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

The remote’s default branch from symbolic-ref refs/remotes/origin/HEAD (short name only); None when origin/HEAD is unset.
Source§

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

Whether a local branch exists (show-ref --verify --quiet refs/heads/<name>).
Source§

fn remote_branch_exists<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, name: &'life2 RefName, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Whether origin has name, without fetching (ls-remote origin refs/heads/<name> — the fully-qualified ref, so foo can’t tail-match bar/foo). Runs with GIT_TERMINAL_PROMPT=0 and a 10s timeout so a missing credential or a flaky network can’t hang the call.
Source§

fn remote_url<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, remote: &'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,

A remote’s URL (remote get-url <remote>).
Source§

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

The current attached branch’s upstream, e.g. Some("origin/main") (rev-parse --abbrev-ref --symbolic-full-name @{u}); None when unset. A detached HEAD or a directory outside a repository is an error.
Source§

fn remote_branches<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, remote: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Branch names on remote, without fetching (ls-remote --heads <remote>).
Source§

fn is_merged<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: MergeCheck, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Whether the MergeCheck’s branch is fully merged into its base (branch --merged <base>). Build it as MergeCheck::branch(RefName::new("feature")?).into_base(RevSpec::new("main")?) so the two refs can’t be transposed (a swap would invert the answer).
Source§

fn set_upstream<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, branch: &'life2 RefName, upstream: &'life3 RefName, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Set branch’s upstream to upstream (e.g. origin/main) (branch --set-upstream-to=<upstream> <branch>).
Source§

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

Delete a local branch (branch -d, or -D when forced); see BranchDelete.
Source§

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

Rename a local branch (branch -m <old> <new>).
Source§

fn rev_list_count<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, range: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Count commits in a range (rev-list --count <range>).
Source§

fn diff_range_is_empty<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, range: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Whether a diff range is empty (diff --quiet <range>).
Source§

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

Aggregate change stats for a range (diff --shortstat <range>). Named to match vcs_jj::JjApi::diff_stat.
Source§

fn diff_text<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: DiffSpec, ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Raw git-format unified diff text for spec (diff <spec> --no-color --no-ext-diff -M) — stable machine output, returned verbatim (a trailing blank context line is preserved, so the last hunk stays in sync with its @@ line count for a re-parse/re-apply).
Source§

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

Parsed per-file unified diff for spec, layered on diff_text.
Source§

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

Whether the index has no staged changes (diff --cached --quiet).
Source§

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

Whether a rebase is in progress (a rebase-merge dir, or a rebase-apply dir not left by git am, exists under the git dir).
Source§

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

Whether a git am (mailbox apply) is in progress (rebase-apply/applying). Distinct from a rebase, which shares the rebase-apply dir but without the applying marker — aborting an am needs am --abort, not rebase --abort.
Source§

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

Whether a merge is in progress (a MERGE_HEAD exists under the git dir).
Source§

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

Whether a cherry-pick is in progress (CHERRY_PICK_HEAD under the git dir). A cherry-pick conflict writes CHERRY_PICK_HEAD, not MERGE_HEAD, so this is distinct from a merge and is aborted/continued with cherry-pick --abort / --continue, not merge --abort.
Source§

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

Whether a revert is in progress (REVERT_HEAD under the git dir). Like a cherry-pick, a revert conflict writes its own head file, not MERGE_HEAD; it is driven with revert --abort / --continue.
Source§

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

Whether a git bisect session is in progress (BISECT_LOG under the git dir). Ended with bisect reset (there is no --continue).
Source§

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

Fetch from the default remote (fetch --quiet), with GIT_TERMINAL_PROMPT=0. Transient (network) failures are retried (3 attempts, 500 ms backoff).
Source§

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

Fetch from a named remote (fetch --quiet <remote>), with GIT_TERMINAL_PROMPT=0. Transient failures are retried like fetch.
Source§

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

Fetch a single branch from origin into its remote-tracking ref (fetch --quiet origin refs/heads/<b>:refs/remotes/origin/<b>), with GIT_TERMINAL_PROMPT=0. Transient failures are retried (3×, 500 ms).
Source§

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

Push to a remote (push [-u] <remote> <refspec>); see GitPush.
Source§

fn merge_squash<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, branch: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Stage a branch’s changes without committing (merge --squash <branch>).
Source§

fn merge_commit<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: MergeCommit, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Merge a branch (merge [--no-ff] [-m <msg> | --no-edit] <branch>); with no message it takes the default merge message non-interactively (--no-edit). See MergeCommit.
Source§

fn merge_no_commit<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: MergeNoCommit, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Merge a branch but stop before committing, so the result can be inspected (merge --no-commit [--squash | --no-ff] <branch>). With no_ff (and not squash) git records MERGE_HEAD, so the in-progress merge is abortable via merge_abort — the dry-run pattern. With squash, git stages the squashed result but records no MERGE_HEAD, so it is not an abortable merge: undo it with reset_merge / reset_hard, not merge_abort. See MergeNoCommit.
Source§

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

Abort an in-progress merge (merge --abort).
Source§

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

Finish a merge after resolving conflicts (commit --no-edit).
Source§

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

Undo an in-progress (or just-staged) merge: reset --merge resets the index and the merge-touched working-tree files back to HEAD and drops MERGE_HEAD, discarding the merge’s changes while keeping unrelated unstaged edits. Use it after merge_squash / merge_no_commit(squash), where there is no MERGE_HEAD for merge_abort to act on.
Source§

fn reset_hard<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, rev: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Hard-reset the working tree to a revision (reset --hard <rev>).
Source§

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

Rebase the current branch onto onto (rebase <onto>); the editor is suppressed (GIT_EDITOR=true) so it never hangs a headless caller.
Source§

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

Abort an in-progress rebase (rebase --abort).
Source§

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

Abort an in-progress git am (am --abort), restoring the pre-am HEAD.
Source§

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

Continue a rebase after resolving conflicts (rebase --continue); the editor is suppressed (GIT_EDITOR=true) so the message-confirm never hangs.
Source§

fn stash_push<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: StashPush, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Stash the working tree (stash push, --include-untracked when asked) — e.g. to save state before a copy-on-write restore. See StashPush.
Source§

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

Restore the most recent stash and drop it (stash pop).
Source§

fn worktree_list<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, ) -> Pin<Box<dyn Future<Output = Result<Vec<Worktree>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List worktrees (worktree list --porcelain).
Source§

fn worktree_add<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: WorktreeAdd, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Add a worktree (worktree add [-b <branch>] <path> [<commitish>]).
Source§

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

Remove a worktree (worktree remove [--force] <path>); see WorktreeRemove.
Source§

fn worktree_move<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, from: &'life2 Path, to: &'life3 Path, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Move a worktree (worktree move <from> <to>).
Source§

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

Prune stale worktree admin entries (worktree prune).
Source§

fn clone_repo<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, url: &'life1 str, dest: &'life2 Path, spec: CloneSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Clone url into dest (git clone <url> <dest> + CloneSpec flags). Runs without a working directory — pass an absolute dest.
Source§

fn tag_create<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, name: &'life2 RefName, rev: Option<RevSpec>, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Create a lightweight tag at rev (tag <name> [<rev>]; None = HEAD).
Source§

fn tag_create_annotated<'life0, 'life1, 'async_trait>( &'life0 self, dir: &'life1 Path, spec: AnnotatedTag, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Create an annotated tag (tag -a <name> -m <message> [<rev>]); see AnnotatedTag.
Source§

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

Tag names, sorted by git’s default ordering (tag --list).
Source§

fn tag_delete<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, name: &'life2 RefName, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Delete a tag (tag -d <name>).
Source§

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

A file’s content at a revision (git show <rev>:<path>). path is repo-relative; backslashes are normalised to / (git requires it). Content is decoded lossily — binary files come back mangled rather than erroring — and returned verbatim: the blob’s trailing newline(s) are preserved (not trimmed), so a read-modify-write round-trip is byte-exact.
Source§

fn config_get<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

The value of a config key, or None when unset (config --get <key>, whose exit 1 covers both “unset” and “no such section” — git doesn’t distinguish). A multi-valued key errors; read those via run.
Source§

fn config_set<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, key: &'life2 str, value: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Set a config key in the repository’s local config (config <key> <value>). Read more
Source§

fn remote_add<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, name: &'life2 str, url: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Add a remote (remote add <name> <url>).
Source§

fn remote_set_url<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, dir: &'life1 Path, name: &'life2 str, url: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Change a remote’s URL (remote set-url <name> <url>).
Source§

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

Per-line authorship of path (blame --line-porcelain [<rev>] -- <path>; None = the working tree’s HEAD).
Source§

fn cherry_pick<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, rev: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Apply a commit onto the current branch (cherry-pick <rev>). A conflict surfaces as an error classified by is_merge_conflict.
Source§

fn revert<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, dir: &'life1 Path, rev: &'life2 RevSpec, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Revert a commit with the default message (revert --no-edit <rev>).
Source§

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

Skip the current patch of a paused rebase (rebase --skip). Mainly for the apply backend’s “nothing to commit” stop — the default merge backend auto-drops emptied patches on --continue.
Source§

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

Abort an in-progress cherry-pick (cherry-pick --abort), restoring the pre-cherry-pick state.
Source§

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

Continue a cherry-pick after resolving conflicts (cherry-pick --continue); the editor is suppressed (GIT_EDITOR=true) so the message-confirm never hangs a headless caller. On a multi-commit pick it can stop again on the next commit’s conflict (exit non-zero) — a conflict, not a hard error.
Source§

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

Abort an in-progress revert (revert --abort), restoring the pre-revert state.
Source§

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

Continue a revert after resolving conflicts (revert --continue); the editor is suppressed like cherry_pick_continue, and it too can stop on the next commit’s conflict.
Source§

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

End a git bisect session (bisect reset), returning to the branch/commit that was checked out before it started. This is the “abort” for a bisect; bisect has no --continue.

Auto Trait Implementations§

§

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

§

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

§

impl<R> Freeze for Git<R>
where R: Freeze,

§

impl<R> Send for Git<R>

§

impl<R> Sync for Git<R>

§

impl<R> Unpin for Git<R>
where R: Unpin,

§

impl<R> UnsafeUnpin for Git<R>
where R: UnsafeUnpin,

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> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

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