UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

167 lines • 8.41 kB
import type { PathSpec } from '../../../../types.ts'; import type { HeadRef, Refspec, SymbolicEnd } from './types.ts'; import type { Files } from '../../../../workspace/files.ts'; export declare const HEAD_FILE = "HEAD"; export declare const MAX_SYMREF_DEPTH = 5; export declare const SYMREF_PREFIX = "ref: "; export declare const BRANCH_PREFIX = "refs/heads/"; export declare const REMOTE_PREFIX = "refs/remotes/"; /** * Resolve `.git/HEAD` to a branch name or a detached commit. * * HEAD holds either a symbolic ref (`ref: refs/heads/main`) or a raw object id * when the checkout is detached. A ref outside `refs/heads` keeps its full name, * which is what git shows for a checked-out tag or remote-tracking ref. */ export declare function readHead(vfs: Files, gitdir: PathSpec): Promise<HeadRef>; /** * Point one ref at an object id, as a loose ref file. * * Always written loose, never into `packed-refs`: git does the same for any ref * it updates, and a loose file takes precedence over the packed copy, so a * branch that was packed is correctly overridden rather than duplicated. * * Refs live in the common directory, so a branch made from a linked worktree is * visible to the repository it was cut from, which is what makes `git worktree` * share branches at all. * * A name whose path would leave the ref tree is refused here as git's ref * transaction refuses it, whatever the caller checked: the name is joined onto * the git directory, so `refs/heads/../../config` would land on the * repository's own configuration. Every verb checks its name before it gets * here, so this is the last guard, not the refusal a user sees. * * @throws BadRefNameUpdateError a name `safeRefName` refuses */ export declare function writeRef(vfs: Files, commondir: PathSpec, ref: string, sha: string): Promise<void>; /** * `packed-refs` with one ref's lines removed, null if it held none. * * A packed ref is two lines rather than one when it is an annotated tag: the tag * object's own id, then a `^` line holding the commit it peels to. The peeled * line belongs to the ref above it, so dropping a ref drops the `^` line that * follows it and nothing else. */ export declare function withoutPacked(text: string, ref: string): string | null; /** * Remove a ref, loose copy and packed copy alike. * * Both are removed because either alone can be what holds the ref, and removing * only the loose one would report a deletion the next read undoes: after * `git pack-refs` a ref exists nowhere else, and a force-updated one exists in * both, where dropping the loose file would resurrect the older packed value. */ export declare function deleteRef(vfs: Files, commondir: PathSpec, ref: string): Promise<void>; /** Point HEAD at a branch, symbolically. */ export declare function setHead(vfs: Files, gitdir: PathSpec, ref: string): Promise<void>; /** Point HEAD straight at a commit, detaching it from any branch. */ export declare function detachHead(vfs: Files, gitdir: PathSpec, sha: string): Promise<void>; /** * Read every ref a repository publishes, packed and loose. * * Both sources are needed and neither is optional: a freshly cloned repository * keeps `refs/remotes/origin/main` only in `packed-refs`, while a branch * committed to since the last pack exists only as a loose file. Loose wins on a * collision, which is git's own precedence. * * Refs come from two directories when the two differ. A linked worktree shares * its branches with the repository it was cut from and keeps only its own HEAD * and per-checkout refs (`refs/bisect`, `refs/worktree`), so the shared table is * read first and the worktree's own overrides it, then HEAD last of all. * * @param vfs the session's files * @param gitdir this checkout's git directory, which owns HEAD * @param commondir the shared git directory, which owns the branches; null means * it is the same directory, which is every ordinary checkout */ export declare function loadRefs(vfs: Files, gitdir: PathSpec, commondir?: PathSpec | null): Promise<Map<string, string>>; export declare const TAG_PREFIX = "refs/tags/"; /** * The existing ref that stops a new one from being written. * * A ref is a path, so two of them cannot coexist when one spells a directory * the other spells a file: with `refs/tags/foo` already there, * `refs/tags/foo/bar` has no directory to live in, and with `refs/tags/foo/bar` * there, `refs/tags/foo` has a directory standing on its name. git refuses both * and names the ref already written; a repository can only ever hold one of the * two shapes, so the two searches cannot both answer. * * Nothing below git's own storage can be relied on to say so. A disk mount * raises whatever its host filesystem raises, which reaches the user as neither * git's wording nor git's exit code, and a prefix store takes both keys happily * and leaves a ref the loose-ref walk cannot find. * * @param known every ref the repository holds * @param ref the full ref name about to be written */ export declare function blockingRef(known: ReadonlySet<string>, ref: string): string | null; /** * Whether a name passes git's ref rules (`git check-ref-format`). * * The rules, in git's own order: no component may start with `.` or end with * `.lock`; `..` may not appear; no control character, space or shell * metacharacter; no leading, trailing or doubled `/`; no trailing `.`; and no * `@{`. Empty is refused too. A bare `@` is refused only as a whole ref, and a * name here always sits below `refs/`, so it passes. Pinned against git 2.50.1. * * @param name the name below `refs/heads/` or `refs/tags/` */ export declare function validRefName(name: string): boolean; /** * Whether git takes a name for a new branch: git's ref rules, and two more * that hold for a branch only: no leading `-`, which would read as an option, * and not `HEAD`, which `refs/heads/HEAD` would make ambiguous with HEAD * itself. Pinned against git 2.47.3. * * @param name the name below `refs/heads/` */ export declare function validBranchName(name: string): boolean; /** * Whether git's ref rules take a whole ref name, one level allowed, as * `git check-ref-format --allow-onelevel` judges it: a bare `@` is the one name * they refuse whole that they take below `refs/`. * * @param name the full ref name */ export declare function wholeRefName(name: string): boolean; /** * A ref's raw value, an object id or `ref: <target>`, null when there is none. * * Read from the ref table, or for a one-level name outside it (`ORIG_HEAD` and * its kin) from the checkout's git directory, which is where git keeps them. * * @param vfs the session's files * @param gitdir this checkout's git directory * @param table every ref, as loadRefs reads them * @param name the full ref name */ export declare function rawRef(vfs: Files, gitdir: PathSpec, table: ReadonlyMap<string, string>, name: string): Promise<string | null>; /** * Follow a symbolic ref the way git resolves one, without reading the object * it lands on. * * One hop when `recurse` is off, otherwise to the end of the chain, which may * name a ref that does not exist yet (an unborn branch). Null where git finds * no such ref: a name its rules refuse, or a chain more than five deep. Pinned * against git 2.47.3. * * @param vfs the session's files * @param gitdir this checkout's git directory * @param table every ref, as loadRefs reads them * @param name the full ref name to start from * @param recurse follow every hop rather than the first */ export declare function resolveSymbolic(vfs: Files, gitdir: PathSpec, table: ReadonlyMap<string, string>, name: string, recurse: boolean): Promise<SymbolicEnd | null>; /** * Whether git lets a ref update write a name it has no object for: below * `refs/`, a path with no empty, `.` or `..` component; anywhere else, capitals * and underscores only, which is HEAD and its kin. Pinned against git 2.47.3. * * @param name the full ref name about to be written */ export declare function safeRefName(name: string): boolean; /** Split a refspec into its source, destination and force flag. */ export declare function parseRefspec(text: string): Refspec; /** The local ref a refspec maps a remote ref to, null when unmatched. */ export declare function mapped(spec: Refspec, name: string): string | null; //# sourceMappingURL=refs.d.ts.map