/** * Args prepended to every git invocation. Empty `credential.helper` resets the * helper chain for this child process only — prevents macOS git's osxkeychain * helper from popping a "Keychain Not Found" dialog when qfg-managed creds are * embedded in the URL. */ export declare const GIT_SAFE_ARGS: readonly string[]; /** * Env additions for every git invocation. Suppress tty prompts and Git * Credential Manager interactive flows. */ export declare const GIT_SAFE_ENV: Readonly; /** * Redact a token from a URL string so it is safe to display to users. */ export declare const redactToken: (url: string) => string; export interface RunGitOptions { cwd?: string; /** Extra env vars merged on top of `process.env` and `GIT_SAFE_ENV`. */ env?: NodeJS.ProcessEnv; } /** * Canonical entry point for shelling out to git from the CLI. Always prepends * `GIT_SAFE_ARGS` and merges `GIT_SAFE_ENV` so credential prompts never leak * to the user. Errors are re-thrown with tokens redacted from message/stderr. */ export declare const runGit: (args: string[], options?: RunGitOptions) => Promise<{ stdout: string; stderr: string; }>; export interface SpawnGitOptions { cwd?: string; env?: NodeJS.ProcessEnv; /** If set, written to the child's stdin and then stdin is closed. */ stdin?: string; } /** * Spawn-based git invocation for cases where stdin needs to be piped (e.g. * `git commit -F -`). Same safe-args/env injection as `runGit`. */ export declare const spawnGit: (args: string[], options?: SpawnGitOptions) => Promise; export declare const gitClone: (repoUrl: string, dir: string) => Promise; /** * True only when `dir` is itself the root of a git repo. Uses `--show-prefix` * (relative path from enclosing toplevel down to `dir`, empty when `dir` IS * the toplevel) to avoid cross-platform path-string pitfalls — see the * matching comment in cli/src/migrate/local-write.ts (qfg-wu85). */ export declare const isGitRepo: (dir: string) => Promise; export declare const getRemoteUrl: (dir: string) => Promise; /** * Return every configured remote URL (one per remote name). Walks the * output of `git remote` and resolves each name's URL via `remote get-url`. * * Returns an empty array when the dir isn't a git repo or has no remotes. * Multi-remote support (qfg-glrd.3): the identity check accepts as long as * any configured remote points at the backend's repo URL. */ export declare const getAllRemoteUrls: (dir: string) => Promise; export declare const isWorkingTreeClean: (dir: string) => Promise; /** * Returns true if `file` (relative to `dir`) has any working-tree or * staged change, false if its tracked content matches HEAD. */ export declare const hasFileChanges: (dir: string, file: string) => Promise; /** * Returns the list of tracked files (relative paths) with working-tree * or staged modifications. Untracked files (`??`) are excluded — they * are not considered "dirty" by callers that want to know whether the * user has work-in-progress that should not be swept into a commit. */ export declare const dirtyTrackedFiles: (dir: string) => Promise; /** * Stage and commit a single file with the given message. The path argument * to `git commit` ensures only this file is committed even if other files * are already staged in the index. * * Returns true if a commit was created, false if there was nothing to * commit (file matches HEAD already). Throws on real git errors. */ export declare const addAndCommitFile: (dir: string, file: string, message: string) => Promise; /** * Read the contents of `file` (relative to `dir`) at HEAD. Returns * `undefined` if the file does not exist at HEAD or if HEAD itself is * unset (empty repo). */ export declare const readFileAtHead: (dir: string, file: string) => Promise; /** * Result of `commitPinFixIfPinOnly`. Tells callers whether a commit was * made and, if not, why — useful for verbose logging without throwing on * the migration path. */ export type PinFixResult = { kind: 'committed'; slug: string; } | { kind: 'clean'; } | { kind: 'skipped'; reason: string; }; /** * Migration helper for legacy state where `qfg pull` wrote the workspace * pin to the working tree but never committed it (qfg-0fn). If * `quonfig.json` is dirty AND its only diff vs HEAD is an added or * changed `workspace` key matching `expectedSlug`, stage and commit the * file so push's HEAD-vs-origin delta picks it up. * * Skips (returns `kind: 'skipped'`) when the dirty file has any other * changes, when the pin doesn't match the backend slug, or when JSON * parsing fails — leaving the user's working tree alone. */ export declare const commitPinFixIfPinOnly: (dir: string, file: string, expectedSlug: string) => Promise; export declare const gitFetch: (dir: string) => Promise; /** * Returns true if origin/main has commits that can be fast-forwarded into the local branch. */ export declare const canFastForward: (dir: string) => Promise; /** * Returns true iff origin/main is NOT an ancestor of the local HEAD — * covering both "local strictly behind" and "diverged" in one boolean. * * Used by the clone-path stale-HEAD guard in `qfg push` (qfg-fboj): * either of those two states would otherwise produce a `HEAD..origin/main` * diff that ships REVERSAL deltas to the server, silently undoing * remote-newer commits. Both must refuse. * * Returns false on any git failure (no `origin/main` ref yet, no `.git/`, * etc.) so the caller falls through to its other guards rather than * aborting on an opaque error. */ export declare const isLocalBehindOrDivergedFromRemote: (dir: string) => Promise; /** * Returns true if local has commits not reachable from origin/main (diverged). */ export declare const hasDivergedFromRemote: (dir: string) => Promise; /** * Performs a fast-forward-only merge of origin/main. Returns list of new commit subjects. */ export declare const gitMergeFfOnly: (dir: string) => Promise; /** * Adds or updates the origin remote for a repo. */ export declare const gitSetRemote: (dir: string, url: string) => Promise; export declare const gitPushForceLease: (dir: string) => Promise; export declare const gitPushForce: (dir: string) => Promise; export declare const hasAtLeastOneCommit: (dir: string) => Promise; /** * Get the URL stripped of credentials for display purposes. */ export declare const displayUrl: (url: string) => string; /** * Outcome of `gitPullRebase`. Three branches the caller MUST distinguish * — silent failure here is what made qfg-4tey a P1 (qfg pull exit 0 with * no recovery path). */ export type GitPullRebaseResult = { kind: 'clean'; commitsRebased: number; } | { kind: 'conflicts'; conflictedFiles: string[]; } | { kind: 'failed'; reason: string; }; /** * `git pull --rebase origin main`. Replays local commits on top of the * remote tip. On conflicts, leaves the repo in rebase-in-progress state * with `<<<<<<<` / `=======` / `>>>>>>>` markers planted by git so the * user can resolve via standard git tools (`git rebase --continue` / * `git rebase --abort`). * * Caller is responsible for surfacing recovery instructions; this function * only reports the outcome. */ export declare const gitPullRebase: (dir: string) => Promise; /** * Returns the local SHA of `origin/main` (i.e. the remote tip we last * fetched), or undefined if the repo has no `origin/main` ref. * * Used as the `expectedSha` passed to the server-side `configs.push` * optimistic lock (qfg-gj3i): the server compares the value we send * against the current Gitea workspace HEAD and rejects the push if * origin advanced between fetch and push. Belt-and-suspenders next to * the CLI-side stale-HEAD guard from qfg-fboj — closes the gap for * non-CLI clients and CLI regressions. * * Returns undefined on bare-path pushes (no `.git/`) and on any git * error so the caller can fall back to other locks rather than aborting * on an opaque rev-parse failure. */ export declare const getOriginMainSha: (dir: string) => Promise;