import type { CommandFnResult, Context } from '../../../config.ts';
import type { FlagView } from '../../../spec/flag_view.ts';
import { type GitError } from './errors.ts';
import { PathSpec } from '../../../../types.ts';
import type { Files } from '../../../../workspace/files.ts';
export declare const STDOUT = "stdout";
export declare const STDERR = "stderr";
export declare const MARKER = "--";
/**
 * Where repository discovery begins for this invocation.
 *
 * `-C` changes directory before anything else happens, git's own reading of the
 * option. It needs no separate session-cwd fact: the option is declared with a
 * `'.'` default, and a PATH default lands as if typed, so an absent `-C`
 * resolves to the session cwd and a relative `-C build` is already absolute by
 * the time it arrives.
 *
 * Keep the PathSpec until the directory walk is checked. Repository-relative
 * pathspec matching uses its virtual spelling after that check.
 *
 * @param fl spec-validated view over the leaf's flag bag
 */
export declare function startPoint(fl: FlagView): PathSpec;
/**
 * The revision operand a verb was given, or git's own default.
 *
 * @param texts positional text operands
 * @param fallback what an absent operand means
 */
export declare function revisionArg(texts: readonly string[], fallback?: string): string;
/**
 * The words a `--` on the line marked as operands, not options.
 *
 * `--` is exactly how a caller names a file whose name begins with a dash, and
 * git says so in every synopsis that ends `[--] [<pathspec>...]`: `git rm
 * -draft` is a refused switch and `git rm -- -draft` removes the file. The
 * parser consumes the marker, so the words themselves are what carries the fact
 * forward, read back off the verbatim argv the record already holds.
 *
 * A set is enough. A dash word before the marker was read as an option and
 * never reached the operands, so a word that is here and also spelled earlier on
 * the line is still the escaped one.
 *
 * @param argv the line's verbatim tokens after the head word, subcommand words
 *   included
 */
export declare function escaped(argv: readonly string[]): Set<string>;
/**
 * The operands before a `--` on the line and the ones after it.
 *
 * `git diff A B -- docs` reads what comes before the marker as revisions and
 * what follows as pathspecs, whatever either looks like. Every word after the
 * marker is an operand, so they are the tail of the operands, as many as the
 * verbatim argv holds past it.
 *
 * @param texts positional text operands, as typed
 * @param argv the line's verbatim tokens after the head word, subcommand words
 *   included
 */
export declare function splitMarked(texts: readonly string[], argv: readonly string[]): [string[], string[]];
/**
 * The first operand that is really an option this build lacks.
 *
 * A verb taking a revision accepts free text, so every flag mirage does not
 * declare reaches it as one. Resolving it as a revision is the wrong answer
 * twice over: it fails, and it fails saying the repository has no such commit,
 * when what happened is that mirage has no such flag. Found here, before any
 * object is read, so the refusal names the real problem.
 *
 * Unless the caller said otherwise. A word after `--` is an operand by the
 * caller's own instruction whatever it starts with, so it is never read as an
 * option here; see `escaped`, which is where the marker survives the parser.
 *
 * Which side of the marker an operand fell on says nothing about what it
 * *means* here. `diff`, `show`, `diff-tree` and the walks (`log`, `rev-list`,
 * `shortlog`) read what follows the marker as pathspecs (`splitMarked`).
 *
 * @param texts positional text operands, as typed
 * @param marked operands a `--` on the line escaped
 * @param known the verb's one-letter switches, which narrow a refused cluster to
 *   its first unknown letter the way parse-options does; absent names the whole
 *   word
 */
export declare function offending(texts: readonly string[], marked?: ReadonlySet<string>, known?: ReadonlySet<string>): string | null;
/**
 * The first operand that is really an option, once `-h` is out.
 *
 * `-h` asks for the verb's usage block, which git prints on stdout for most
 * verbs and on stderr for a few (`diff`); every other word is the caller's to
 * refuse in the verb's own words. See `offending` for which words count.
 *
 * @param ctx the line's context, carrying its leaf
 * @param texts positional text operands, as typed
 * @param helpStream where `-h` puts the usage block
 * @throws UsageError the line asked for the usage block
 */
export declare function optionOperand(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): string | null;
/**
 * Where `-h` puts the usage block for a verb that takes it as help only alone.
 *
 * `rev-list`, `rev-parse` and `diff-tree` print it on stdout, exiting 0, when
 * `-h` is their one word, and beside anything else on stderr as a refusal,
 * exiting 129 (git 2.56).
 *
 * @param ctx the line's context, carrying its leaf
 * @param texts the verb's positional text operands
 */
export declare function loneHelp(ctx: Context, texts: readonly string[]): typeof STDOUT | typeof STDERR;
/**
 * Refuse an operand that is really an option, as an unrecognized argument.
 *
 * For the verbs git words without a usage block (`log`, `show`, `reflog`),
 * whose refusal names the whole word (git 2.50.1).
 *
 * @param ctx the line's context, carrying its leaf
 * @param texts positional text operands, as typed
 * @param helpStream where `-h` puts the usage block
 */
export declare function checkOperands(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): void;
/**
 * The verb's usage block, as parse-options prints it.
 *
 * @param ctx the line's context, carrying its leaf
 */
export declare function verbUsage(ctx: Context): string;
/**
 * Refuse an operand that is really an option, as parse-options does.
 *
 * The verbs built on parse-options (`status`, `add`, `branch`, `commit` and
 * most others) name an unknown option or switch and follow it with the usage
 * block, refuse a boolean handed a value on one line, and print the usage block
 * on stdout for `-h`; see `gitOptionRefusal`. Measured on git 2.50.1.
 *
 * @param ctx the line's context, carrying its leaf
 * @param texts positional text operands, as typed
 */
export declare function checkSwitches(ctx: Context, texts: readonly string[]): void;
/**
 * The one-letter switches the leaf declares, without their dash.
 *
 * Read off the spec the line was parsed against, so the set is the verb's
 * own and never a copy of it; empty where no executor built the record.
 *
 * @param ctx the line's context, carrying its leaf
 */
export declare function switches(ctx: Context): ReadonlySet<string>;
/**
 * The part of a dash word parse-options would refuse.
 *
 * git reads a short cluster letter by letter, consumes the ones the verb
 * declares and stops at the first it does not, so `git mv -nx` says `x' and
 * `git mv -draft` says `d' (git 2.50.1); a verb that declares no switch at
 * all (`reset`) still names the first letter. A long option is refused as
 * typed, and so is a cluster for a verb that hands over no set: log, show
 * and diff word the whole argument.
 *
 * @param text the dash word as the user spelled it
 * @param known the verb's one-letter switches, absent for a verb that
 *   refuses the word whole
 */
export declare function offendingSwitch(text: string, known: ReadonlySet<string> | undefined): string;
/**
 * The session's files, which every verb reads and writes through. Only a leaf
 * called directly, outside a workspace, has none; git words that the way it
 * words a bare repository. Mirrors Python's `require_vfs`.
 */
export declare function requireVfs(ctx: Context): Files;
/**
 * Render a git error: `<prefix>: <message>`, on its own stream.
 *
 * git uses 128 for a fatal, which is neither the dispatcher's usage exit (2) nor
 * its generic handler-error exit (1), so leaves return the code rather than
 * throwing into the catch-all. A refused option carries its own prefix and code
 * instead, which is git's own split, and a refusal that is really a report
 * ("nothing to commit") carries no prefix and goes to stdout.
 *
 *
 * An error carrying a `report` puts that on stdout beside the stderr line,
 * because git writes some refusals to both streams at once: `<path>: needs
 * merge` is the diagnosis and "you need to resolve your current index first" is
 * the refusal.
 *
 * @param exc the error to render
 */
export declare function fatal(exc: GitError): CommandFnResult;
/**
 * A config boolean read the way git's config callbacks read one.
 *
 * Every occurrence is parsed and the last one wins, so a value git cannot read
 * fails even when a later line would have read fine. A value is
 * `true`/`yes`/`on` or `false`/`no`/`off` in any case, empty for false, or an
 * integer for whether it is nonzero (pinned against git 2.54).
 *
 * @param values every value the variable takes, in file order; a bare name
 *   arrives as `true`
 * @param key the variable, section and name lowercased
 * @param fallback the answer when the variable is unset
 */
export declare function gitBool(values: readonly string[], key: string, fallback: boolean): boolean;
/**
 * A config boolean as git reads it: `true`/`yes`/`on` or `false`/`no`/`off`
 * in any case, empty for false, or an integer for whether it is nonzero; null
 * for anything else, which each caller answers in its own way.
 *
 * @param value the value as typed or as the config spells it
 */
export declare function maybeBool(value: string): boolean | null;
/**
 * One `[section "name"]` block the way git's config writer spells it.
 *
 * The subsection escapes `"` and `\`; a value escapes those plus newline and
 * tab, and is quoted when it starts or ends with a space or holds `;` or `#`.
 * A branch may be named `a"b` or `a#b`, and either one written raw reads back
 * as a different name (pinned against git 2.50.1).
 *
 * @param section the section, e.g. `branch`
 * @param name the subsection, e.g. the branch name
 * @param pairs variables and values, in order
 */
export declare function configSection(section: string, name: string, pairs: readonly (readonly [string, string])[]): string;
/**
 * A config's text with every block for `section.name` taken out.
 *
 * `git branch -d` drops the deleted branch's settings this way, so a branch
 * made again under the same name starts with no upstream rather than with two.
 * A header names the block the way git matches it,
 * spelled exactly: `[branch "x"]` with its escapes, or the older `[branch.x]`.
 * `[Branch "x"]` and `[branch.X]` are left, as git leaves them, and a line
 * opening with `[` ends a block (pinned against git 2.50.1).
 *
 * With `keys` only those variables leave the blocks, and a block they leave
 * holding no variable leaves with them, header and all, as
 * `git branch --delete-merged` clears an upstream (git 2.56.0). A variable
 * sharing its header's line leaves the header behind.
 *
 * A value continued onto the next line by a trailing backslash is followed, so
 * a continuation that opens with `[` is still part of the block. git 2.50.1
 * reads it as a header there and leaves the rest of the block behind, which it
 * then refuses as a bad config line; mirage keeps the file readable instead.
 *
 * @param text the config file's contents
 * @param section the section as git writes it, e.g. `branch`
 * @param name the subsection, e.g. the branch name
 * @param keys the variables to take out, lowercase; null takes the whole block
 */
export declare function withoutSection(text: string, section: string, name: string, keys?: ReadonlySet<string> | null): string;
//# sourceMappingURL=util.d.ts.map