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<R: ProcessRunner> Git<R>
impl<R: ProcessRunner> Git<R>
Sourcepub fn with_runner(runner: R) -> Self
pub fn with_runner(runner: R) -> Self
Create a client driving runner — inject a fake in tests.
Sourcepub fn default_timeout(self, timeout: Duration) -> Self
pub fn default_timeout(self, timeout: Duration) -> Self
Apply a default timeout to every command this client builds.
Sourcepub fn default_env(
self,
key: impl AsRef<OsStr>,
value: impl AsRef<OsStr>,
) -> Self
pub fn default_env( self, key: impl AsRef<OsStr>, value: impl AsRef<OsStr>, ) -> Self
Set an environment variable on every command this client builds.
Sourcepub fn default_env_remove(self, key: impl AsRef<OsStr>) -> Self
pub fn default_env_remove(self, key: impl AsRef<OsStr>) -> Self
Remove an inherited environment variable on every command this client builds.
Sourcepub fn default_cancel_on(self, token: CancellationToken) -> Self
pub fn default_cancel_on(self, token: CancellationToken) -> Self
Cancel every command this client builds when token fires.
Sourcepub fn default_output_budget(self, budget: OutputBudget) -> Self
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>
impl<R: ProcessRunner> Git<R>
Sourcepub fn with_retry(self, policy: RetryPolicy) -> Self
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.
Sourcepub fn with_credentials(self, provider: Arc<dyn CredentialProvider>) -> Self
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.
Sourcepub fn with_token(self, token: impl Into<Secret>) -> Self
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.
Sourcepub fn with_env_token(self, var: impl Into<String>) -> Self
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>
impl<R: ProcessRunner> Git<R>
Sourcepub async fn diff_text_within(
&self,
dir: &Path,
spec: DiffSpec,
budget: OutputBudget,
) -> Result<String>
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.
Sourcepub async fn diff_within(
&self,
dir: &Path,
spec: DiffSpec,
budget: OutputBudget,
) -> Result<Vec<FileDiff>>
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.
Sourcepub async fn show_file_within(
&self,
dir: &Path,
rev: &RevSpec,
path: &str,
budget: OutputBudget,
) -> Result<String>
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>
impl<R: ProcessRunner> Git<R>
Sourcepub async fn run_args(&self, args: &[&str]) -> Result<String>
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.
Sourcepub async fn run_raw_args(&self, args: &[&str]) -> Result<ProcessResult<String>>
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).
Sourcepub async fn run_in(&self, dir: &Path, args: &[String]) -> Result<String>
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).
Sourcepub async fn run_raw_in(
&self,
dir: &Path,
args: &[String],
) -> Result<ProcessResult<String>>
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.
Sourcepub async fn run_args_in(&self, dir: &Path, args: &[&str]) -> Result<String>
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.
Sourcepub async fn run_raw_args_in(
&self,
dir: &Path,
args: &[&str],
) -> Result<ProcessResult<String>>
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.
Sourcepub async fn empty_tree_oid(&self, dir: &Path) -> Result<String>
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.
Sourcepub fn harden(self) -> Self
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 hooks —
core.hooksPath=/dev/nullpinned via git’s env-based config (GIT_CONFIG_COUNT/KEY_n/VALUE_n, git ≥ 2.31; verified to suppress hooks on Windows too) — andcore.fsmonitor(a config-driven daemon launch). Env-config overrides even the repo-local.git/configfor the keys it names, so these pins beat a poisoned.git/config. - Neutralizes
core.sshCommand(pinned empty) — the config-key twin of the scrubbedGIT_SSH_COMMAND, an arbitrary program git would run for the SSH transport. Empty is falsy to git, so the defaultssh(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 agit://connection),GIT_EXEC_PATH(relocates git’s own sub-commands), andGIT_TEMPLATE_DIR(seeds hooks/config oninit/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 gitcredential.helper/ token env, not these variables, so it keeps working through a hardened client; an operator who deliberately relies on an ambientGIT_SSH_COMMAND/GIT_ASKPASSshould 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.
Sourcepub async fn switch_with_stash(
&self,
dir: &Path,
target: &CheckoutTarget,
) -> Result<()>
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 -u → checkout →
stash 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:
checkoutfails (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 popon 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.
Trait Implementations§
Source§impl<R: ProcessRunner> Debug for Git<R>
impl<R: ProcessRunner> Debug for Git<R>
Source§impl<R: ProcessRunner> GitApi for Git<R>
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,
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,
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,
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,
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,
fn version<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
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,
fn capabilities<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<GitCapabilities>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
/ 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,
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,
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,
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,
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,
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,
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,
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,
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 moreSource§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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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 --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,
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 --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,
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,
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,
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 [-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,
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,
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,
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 [--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,
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 --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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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 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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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 --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,
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,
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,
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,
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,
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,
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,
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,
config <key> <value>). Read moreSource§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,
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,
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,
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,
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,
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,
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,
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,
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,
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 --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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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.