import type { NOOPAccessor } from '../../../../accessor/base.ts';
import { type PathSpec } from '../../../../types.ts';
import type { CommandFnResult, Context } from '../../../config.ts';
import type { RepoLocation } from './types.ts';
import type { Files } from '../../../../workspace/files.ts';
/** The parsed shape of a `git mv` invocation. */
export interface MvFlags {
    /** `-f`, overwrite an existing destination file. */
    readonly force: boolean;
    /** `-k`, skip a source that cannot move rather than refusing the line. */
    readonly skip: boolean;
    /** `-n`, report what would move and move nothing. */
    readonly dryRun: boolean;
    /** `-v`, print one line per move; implied by `-n`. */
    readonly verbose: boolean;
}
/** One source and where it goes. */
export interface Move {
    /** Repository-relative path being moved. */
    readonly source: string;
    /**
     * Repository-relative path it moves to, already joined with the source's
     * basename when the destination was a directory.
     */
    readonly destination: string;
    /**
     * The tracked paths that move with it: the source itself for a file,
     * everything under it for a directory.
     */
    readonly paths: readonly string[];
    /** Whether the source is a directory. */
    readonly directory: boolean;
}
/** What one refusal check found: a reason, or the paths that move. */
interface Verdict {
    readonly reason: string | null;
    readonly paths: readonly string[];
    readonly directory: boolean;
}
/** Where one tracked path lands after a move. */
export declare function movedPath(move: Move, path: string): string;
/**
 * The first path in a move that the index left unmerged.
 *
 * Named the way the collision is named, by the path itself rather than by the
 * operand that carried it, which is what git reports for a directory holding
 * one.
 */
export declare function conflicting(move: Move, conflicted: ReadonlySet<string>): [string, string] | null;
/**
 * The first path in a move that lands where an earlier one already does.
 *
 * Landings are compared one tracked path at a time rather than one operand at a
 * time, because a directory operand moves every path under it and two
 * directories sharing a child name collide there and nowhere else. git reports
 * that collision by the colliding path too, not by the operand that carried it.
 */
export declare function clashing(move: Move, claimed: ReadonlySet<string>): [string, string] | null;
/**
 * The first source that sits inside another source in the same line.
 *
 * git reads this off the whole line once every source has passed its own
 * checks, which is why a source with a fault of its own is still refused for
 * that fault first, and why `-k` skipping a source takes it out of this
 * comparison too. The pair reported is the first directory source in operand
 * order and the first source under it, named child first whatever order the
 * line put them in.
 */
export declare function overlapping(moves: readonly Move[]): [string, string] | null;
/**
 * Whether one source can move, in git's own order of refusals.
 *
 * The index is read before the destination is looked at, which is git's order
 * and observable: a conflicted source is refused as conflicted even when the
 * destination is occupied, and a directory holding an unmerged path is refused
 * for that rather than for a destination that already exists.
 */
export declare function check(vfs: Files, location: RepoLocation, source: string, destination: string, tracked: ReadonlySet<string>, conflicted: ReadonlySet<string>, force: boolean): Promise<Verdict>;
/**
 * Decide every move before making any, which is git's order too.
 *
 * The last operand is the destination. With several sources it has to be a
 * directory that exists; with one, an existing directory takes the source
 * under its own name and anything else is the new name.
 */
export declare function plan(vfs: Files, location: RepoLocation, start: string, operands: readonly string[], tracked: ReadonlySet<string>, conflicted: ReadonlySet<string>, flags: MvFlags): Promise<Move[]>;
/**
 * Move or rename a file or directory, and stage the move.
 *
 * The index entries are re-keyed with their blob ids and modes untouched, which
 * is what lets `status` read the result as a rename rather than a delete beside
 * an add.
 */
export declare function mv(_accessor: NOOPAccessor, paths: PathSpec[], texts: string[], ctx: Context): Promise<CommandFnResult>;
export {};
//# sourceMappingURL=mv.d.ts.map