import type { FileDiff, FileHunks, NumstatEntry } from "../commit/types"; export interface GitCommandResult { exitCode: number; stdout: string; stderr: string; } export interface GitRepository { commonDir: string; gitDir: string; gitEntryPath: string; headPath: string; repoRoot: string; } export interface GitStatusSummary { staged: number; unstaged: number; untracked: number; } export type HunkSelection = { path: string; hunks: { type: "all"; } | { type: "indices"; indices: number[]; } | { type: "lines"; start: number; end: number; }; }; export interface StageHunksOptions { readonly diffCached?: boolean; readonly rawDiff?: string; readonly signal?: AbortSignal; } export interface DiffOptions { readonly allowFailure?: boolean; readonly base?: string; readonly binary?: boolean; readonly cached?: boolean; readonly env?: Record; readonly files?: readonly string[]; readonly head?: string; readonly nameOnly?: boolean; readonly noIndex?: { left: string; right: string; }; readonly numstat?: boolean; readonly signal?: AbortSignal; readonly stat?: boolean; } export interface StatusOptions { readonly pathspecs?: readonly string[]; readonly porcelainV1?: boolean; readonly signal?: AbortSignal; readonly untrackedFiles?: "all" | "no" | "normal"; readonly z?: boolean; } export interface CommitOptions { readonly allowEmpty?: boolean; readonly files?: readonly string[]; readonly signal?: AbortSignal; } export interface PushOptions { readonly forceWithLease?: boolean; readonly refspec?: string; readonly remote?: string; readonly signal?: AbortSignal; } export interface PatchOptions { readonly cached?: boolean; readonly check?: boolean; readonly env?: Record; readonly signal?: AbortSignal; } export interface RestoreOptions { readonly files?: readonly string[]; readonly signal?: AbortSignal; readonly source?: string; readonly staged?: boolean; readonly worktree?: boolean; } export interface CloneOptions { readonly ref?: string; readonly sha?: string; readonly signal?: AbortSignal; } interface GitHeadBase extends GitRepository { headContent: string; } export interface GitRefHead extends GitHeadBase { branchName: string | null; commit: string | null; kind: "ref"; ref: string; } export interface GitDetachedHead extends GitHeadBase { commit: string | null; kind: "detached"; } export type GitHeadState = GitRefHead | GitDetachedHead; export interface GitWorktreeEntry { branch?: string; detached: boolean; head?: string; path: string; } export declare class GitCommandError extends Error { readonly args: readonly string[]; readonly result: GitCommandResult; constructor(args: readonly string[], result: GitCommandResult); } interface CommandOptions { readonly env?: Record; readonly readOnly?: boolean; readonly signal?: AbortSignal; readonly stdin?: string | Uint8Array | ArrayBuffer | SharedArrayBuffer; } /** * Serialize an async block that mutates a git repository against other * in-process callers operating on the same repository. The lock is keyed by * the primary repo root so worktrees of the same repo share a single queue. * Failures in one block do not poison the queue for the next caller. * * Not reentrant: do NOT nest acquisitions for the same repo. Helpers in this * module never auto-acquire — callers wrap the critical section themselves. */ export declare function withRepoLock(cwd: string, fn: () => Promise, signal?: AbortSignal): Promise; declare function parseStatusPorcelain(text: string): GitStatusSummary; /** Run `git diff` with the given options. Returns raw diff text. */ export declare const diff: ((cwd: string, options?: DiffOptions) => Promise) & { /** List changed file paths. */ changedFiles(cwd: string, options?: Pick): Promise; /** Parsed per-file add/remove counts. */ numstat(cwd: string, options?: Pick): Promise; /** Parsed diff hunks for the given files. */ hunks(cwd: string, files: readonly string[], options?: { cached?: boolean; signal?: AbortSignal; }): Promise; /** Check whether a diff exists (uses `--quiet` for efficiency). */ has(cwd: string, options?: Pick): Promise; /** Diff between two tree-ish objects (`git diff-tree`). */ tree(cwd: string, base: string, headRef: string, options?: { binary?: boolean; signal?: AbortSignal; allowFailure?: boolean; }): Promise; /** Parse raw diff text into per-file diffs. */ parseFiles(text: string): FileDiff[]; /** Parse raw diff text into per-file hunks. */ parseHunks(text: string): FileHunks[]; }; /** Run `git status --porcelain`. Returns raw status text. */ export declare const status: ((cwd: string, options?: StatusOptions) => Promise) & { /** Parsed status counts (staged, unstaged, untracked). */ summary(cwd: string, signal?: AbortSignal): Promise; /** Parse porcelain status text into counts. */ parse: typeof parseStatusPorcelain; }; export declare const stage: { /** Stage files. Empty array stages all (`git add -A`). */ files(cwd: string, files?: readonly string[], signal?: AbortSignal): Promise; /** Selectively stage hunks from the provided diff or the current working tree diff. */ hunks(cwd: string, selections: HunkSelection[], options?: StageHunksOptions): Promise; /** Unstage files. Empty array unstages all (`git reset`). */ reset(cwd: string, files?: readonly string[], signal?: AbortSignal): Promise; }; /** Create a commit with the given message (passed via stdin). */ export declare function commit(cwd: string, message: string, options?: CommitOptions): Promise; /** Push the current branch. */ export declare function push(cwd: string, options?: PushOptions): Promise; /** Checkout a ref. */ export declare function checkout(cwd: string, ref: string, signal?: AbortSignal): Promise; /** Fetch a specific refspec from a remote. */ export declare function fetch(cwd: string, remote: string, source: string, target: string, signal?: AbortSignal): Promise; /** Read a tree-ish into the index. */ export declare function readTree(cwd: string, treeish: string, options?: Pick): Promise; /** Write the current index as a tree and return its object id. */ export declare function writeTree(cwd: string, options?: Pick): Promise; /** Run `git show` on a revision. */ export declare const show: ((cwd: string, revision: string, options?: { format?: string; signal?: AbortSignal; }) => Promise) & { /** Get the path prefix of the current directory relative to the repo root. */ prefix(cwd: string, signal?: AbortSignal): Promise; }; export declare const log: { /** Recent commit subjects (one-line each). */ subjects(cwd: string, count: number, signal?: AbortSignal): Promise; /** Recent commits as ` ` onelines. */ onelines(cwd: string, count: number, signal?: AbortSignal): Promise; }; export declare const branch: { /** Current branch name, or null if detached/unavailable. */ current(cwd: string, signal?: AbortSignal): Promise; /** Default branch name (from remote HEAD refs). */ default(cwd: string, signal?: AbortSignal): Promise; /** Create a new branch at the given start point. */ create(cwd: string, name: string, startPoint?: string, signal?: AbortSignal): Promise; /** Force-move a branch to a new start point. */ force(cwd: string, name: string, startPoint: string, signal?: AbortSignal): Promise; /** Delete a branch. Throws on failure. */ delete(cwd: string, name: string, options?: { force?: boolean; signal?: AbortSignal; }): Promise; /** Delete a branch. Returns false on failure instead of throwing. */ tryDelete(cwd: string, name: string, options?: { force?: boolean; signal?: AbortSignal; }): Promise; /** Create and checkout a new branch. */ checkoutNew(cwd: string, name: string, signal?: AbortSignal): Promise; /** List branches. Pass `{ all: true }` to include remotes. */ list(cwd: string, options?: { all?: boolean; signal?: AbortSignal; }): Promise; }; export declare const remote: { /** List remote names. */ list(cwd: string, signal?: AbortSignal): Promise; /** Get the URL for a remote. */ url(cwd: string, name: string, signal?: AbortSignal): Promise; /** * Add a remote pointing at `url`. Idempotent: if a remote named `name` * already exists with the same URL (e.g. an in-process race or a leftover * remote from a previous run), this is treated as success. Throws when the * remote exists with a different URL — that's a real conflict the caller * needs to resolve, not paper over. */ add(cwd: string, name: string, url: string, signal?: AbortSignal): Promise; }; export declare const ref: { /** Check if a ref exists. */ exists(cwd: string, refName: string, signal?: AbortSignal): Promise; /** Resolve a ref to its commit SHA. */ resolve(cwd: string, refName: string, signal?: AbortSignal): Promise; /** Tags pointing at a ref. */ tags(cwd: string, refName?: string, signal?: AbortSignal): Promise; }; export declare const config: { get(cwd: string, key: string, signal?: AbortSignal): Promise; set(cwd: string, key: string, value: string, signal?: AbortSignal): Promise; getBranch(cwd: string, branchName: string, key: string, signal?: AbortSignal): Promise; setBranch(cwd: string, branchName: string, key: string, value: string, signal?: AbortSignal): Promise; }; export declare const worktree: { add(cwd: string, worktreePath: string, refName: string, options?: { detach?: boolean; signal?: AbortSignal; }): Promise; remove(cwd: string, worktreePath: string, options?: { force?: boolean; signal?: AbortSignal; }): Promise; tryRemove(cwd: string, worktreePath: string, options?: { force?: boolean; signal?: AbortSignal; }): Promise; list(cwd: string, signal?: AbortSignal): Promise; prune(cwd: string, signal?: AbortSignal): Promise; }; export declare const patch: { /** Apply a patch file. */ apply(cwd: string, patchPath: string, options?: PatchOptions): Promise; /** Apply a patch from a string (writes to a temp file). */ applyText(cwd: string, patchText: string, options?: PatchOptions): Promise; /** Check if a patch file can be applied cleanly. */ canApply(cwd: string, patchPath: string, options?: Omit): Promise; /** Check if a patch string can be applied cleanly. */ canApplyText(cwd: string, patchText: string, options?: Omit): Promise; /** Join patch parts into a single patch string. */ join(parts: string[]): string; }; export declare const cherryPick: ((cwd: string, revision: string, signal?: AbortSignal) => Promise) & { abort(cwd: string, signal?: AbortSignal): Promise; }; export declare const stash: { /** Stash working tree + index changes. Returns true when git created a new stash entry. */ push(cwd: string, message?: string): Promise; /** Pop the most recent stash entry, optionally restoring its staged state. */ pop(cwd: string, options?: { index?: boolean; }): Promise; }; export declare function clone(url: string, targetDir: string, options?: CloneOptions): Promise; export declare function restore(cwd: string, options?: RestoreOptions): Promise; /** * Run `git reset` with options. Default is a soft reset (no flag); pass `hard: true` for a destructive reset. * * NOTE: stage.reset() handles the per-file unstaging case. This helper exists for tree-wide resets. */ export declare function reset(cwd: string, options?: { hard?: boolean; mixed?: boolean; soft?: boolean; target?: string; signal?: AbortSignal; }): Promise; export declare function clean(cwd: string, options?: { ignoredOnly?: boolean; paths?: readonly string[]; signal?: AbortSignal; }): Promise; export declare const ls: { /** List files tracked or untracked by git. */ files(cwd: string, options?: { others?: boolean; excludeStandard?: boolean; signal?: AbortSignal; }): Promise; /** List untracked files (excludes ignored). */ untracked(cwd: string, signal?: AbortSignal): Promise; /** List submodule paths (recursive). */ submodules(cwd: string, signal?: AbortSignal): Promise; }; export declare const head: { /** Full HEAD state (branch, commit, repo info). */ resolve(cwd: string): Promise; /** Full HEAD state (synchronous). */ resolveSync(cwd: string): GitHeadState | null; /** Current HEAD commit SHA. */ sha(cwd: string, signal?: AbortSignal): Promise; /** Abbreviated HEAD commit SHA. */ short(cwd: string, length?: number, signal?: AbortSignal): Promise; }; export declare const repo: { /** Resolve the repository root (may be a worktree root). */ root(cwd: string, signal?: AbortSignal): Promise; /** Resolve the primary repository root (not a worktree — the main checkout). */ primaryRoot(cwd: string, signal?: AbortSignal): Promise; /** Full GitRepository metadata (sync). */ resolveSync(cwd: string): GitRepository | null; /** Full GitRepository metadata. */ resolve(cwd: string): Promise; }; export interface GhCommandResult { exitCode: number; stdout: string; stderr: string; } export interface GhCommandOptions { repoProvided?: boolean; trimOutput?: boolean; } export declare const github: { /** Check if `gh` CLI is installed. */ available(): boolean; /** Run a raw `gh` CLI command. Does not throw on non-zero exit. */ run(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise; /** Run `gh` and parse stdout as JSON. Throws on non-zero exit or invalid JSON. */ json(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise; /** Run `gh` and return stdout as text. Throws on non-zero exit. */ text(cwd: string, args: string[], signal?: AbortSignal, options?: GhCommandOptions): Promise; }; export {};