import type { GitRange, GitRangeMode, GitRepoInfo } from './types.js';
export type GitErrorCode = 'git-missing' | 'not-a-repo' | 'bad-ref' | 'merge-base-failed' | 'timeout' | 'max-buffer' | 'git-failed' | 'not-implemented';
export declare class GitError extends Error {
    readonly code: GitErrorCode;
    readonly exitCode?: number;
    readonly stderr?: string;
    constructor(code: GitErrorCode, message: string, options?: {
        cause?: unknown;
        exitCode?: number;
        stderr?: string;
    });
}
export interface RunGitOptions {
    cwd?: string;
    repoRoot?: string;
    signal?: AbortSignal;
    timeoutMs?: number;
    maxBuffer?: number;
    allowExitCodes?: readonly number[];
    /**
     * Read literal objects already present in the repository: replacement refs
     * are ignored and partial-clone promisor objects are never fetched.
     */
    physicalObjects?: boolean;
    /**
     * Written to the child's stdin, which is then closed. Required by the
     * batch-mode plumbing commands (`cat-file --batch`) that read their request
     * list from stdin instead of argv — one process for many objects rather than
     * one process per object. Callers must still validate anything interpolated
     * into the payload: the stream is newline-delimited, so an unvalidated
     * newline injects an extra request.
     */
    input?: string | Buffer;
}
export interface RunGitResult {
    stdout: string;
    stderr: string;
    exitCode: number;
    argv: string[];
    cwd: string;
}
export interface RunGitRawResult {
    stdout: Buffer;
    stderr: string;
    exitCode: number;
    argv: string[];
    cwd: string;
}
export declare const GIT_GLOBAL_ARGS: readonly ["--no-pager", "-c", "color.ui=false", "-c", "core.quotePath=false", "-c", "core.autocrlf=false", "--no-optional-locks"];
export declare function runGit(args: readonly string[], options?: RunGitOptions): Promise<RunGitResult>;
export declare function runGitRaw(args: readonly string[], options?: RunGitOptions): Promise<RunGitRawResult>;
export declare function preflightRepo(repoRoot?: string, options?: RunGitOptions): Promise<GitRepoInfo>;
export declare function gitVersion(repoRoot?: string, options?: RunGitOptions): Promise<string>;
/**
 * Resolve the git toplevel for a directory, realpathed so callers can compare
 * it against other resolved filesystem paths. Returns undefined when the
 * directory is not inside a work tree.
 */
export declare function resolveGitToplevel(repoRoot?: string, options?: RunGitOptions): Promise<string | undefined>;
export declare function detectDefaultBase(repoRoot?: string, options?: RunGitOptions): Promise<string | undefined>;
export declare function gitMergeBase(base: string, head?: string, options?: RunGitOptions): Promise<string>;
/**
 * Every parentless commit reachable from any ref, oldest first. This is the
 * stable identity of a repository: it survives renames, remote changes, and
 * relocation of the working tree, and it differs between two unrelated repos
 * that happen to share a path. Repos with grafted or unrelated histories have
 * more than one, so the full sorted set is returned rather than just the first.
 *
 * An unborn repository has no commits at all and yields an empty array; callers
 * must fall back to something else (the realpath of the root) for identity.
 */
export declare function gitRootCommits(repoRoot?: string, options?: RunGitOptions): Promise<string[]>;
/**
 * True when `ancestor` is reachable from `descendant`. Used to detect a
 * rewritten history: a cache whose recorded head is no longer an ancestor of
 * the current head was built on commits that have been rebased, amended, or
 * dropped. An unresolvable ref is reported as `false` rather than throwing,
 * because a vanished commit is exactly the rewrite case being probed for.
 */
export declare function gitIsAncestor(ancestor: string, descendant?: string, options?: RunGitOptions): Promise<boolean>;
export interface ResolveDiffRangeOptions extends RunGitOptions {
    base?: string;
    head?: string;
    staged?: boolean;
    /** Defaults to `merge-base`, which preserves the historical behaviour. */
    rangeMode?: GitRangeMode;
}
export declare function resolveDiffRange(options?: ResolveDiffRangeOptions): Promise<GitRange>;
export declare function buildDiffRangeArgs(range: GitRange, version?: string): string[];
