Skip to content

CLI reference

text
Usage: git why <query> [-- <path>...] [options]
       git why --query <query> [options]
       git why index|status|rebuild|gc [options]

Use git why -h for this from the terminal — see the note on --help for why git why --help does not reach the tool.

Options

FlagMeaning
-n <count>Number of distinct commits to return (default 5, max 50)
--textFull-text search only
--semanticVector search only (default is hybrid)
--sort=<order>relevance (default), oldest, or newest. Reorders the selected commits; never changes which are returned
--first --last --removedResolve/order an introduction, last change, or removal
--timelineReturn the history-oriented retrieval view
--before=<anchor>Temporal anchor when non-ISO (tags, SHA, or a query); ISO dates remain history filters
--after=<anchor>Temporal anchor when non-ISO (tags, SHA, or a query)
--between=<a>,<b>Prefer commits between two temporal anchors
--around=<anchor>Prefer commits near a date, tag, or SHA
--ownersWho established this area, ranked by relevance of their commits rather than by surviving lines or commit count
--group <query>Additional retrieval group; fuse groups at commit level
--after=<date>Only commits at or after this date (UTC, ISO-8601)
--before=<date>Only commits strictly before this date (UTC, ISO-8601)
--author=<substring>Case-insensitive substring of author name or email
--jsonEmit the versioned JSON envelope on stdout
--refresh=<mode>off: never create, mutate, or repair the index; requires one to exist. wait: refresh normally (the default); spelled out for scripts that want to say so explicitly
--no-refreshAlias for --refresh=off
--offlineAlso forbid model downloads
--max-bytes=<n>Bound rendered output, including JSON framing (default 16384)
--lock-timeout=<sec>Seconds to wait for another process (default 30)
--verboseAlso report model loading and download progress on stderr
--query <text>Explicit query text, for text that looks like a command or option
--helpShow this help
--versionShow the version

Flags below that apply to a subcommand rather than to a query:

FlagMeaning
--if-neededWith index: exit 0 immediately if the index is already current, so it is cheap to run unconditionally
--check-readyWith status: exit non-zero unless the index exists, is current for the repository's refs, and covers every reachable commit. For scripts that gate on readiness
--use-default-modelWith rebuild: re-embed with the default model rather than the one recorded in the existing index

These two tables are generated from git why -h by site/scripts/gen-cli-reference.mjs, and CI fails if they drift. The hand-maintained version of this page documented fourteen flags while the tool had twenty-six.

Default mode is hybrid (both --text and --semantic branches, fused with RRF); passing either flag runs a single branch instead.

--sort only reorders the commits retrieval already selected — asking --sort=oldest cannot surface a commit that ranked below the -n cutoff. For "when was this first introduced?" questions, widen the pool first (e.g. -n 20 --sort=oldest). See Ordering results.

Lifecycle commands

CommandEffect
git why indexCreate or reconcile the index.
git why statusReport index state without mutating anything.
git why status --jsonSame, machine-readable.
git why rebuildReplace derived index data.
git why gcReconcile and compact, without downloading embeddings.

Exit codes

ExitMeaning
0Successful command, including zero results
2Invalid invocation
3No usable Git repository
4Index, model, storage, compatibility, or extraction failure
5Index lock wait exceeded (see --lock-timeout)
130User interruption

Exit 4 is intentionally broad; with --json the machine-readable error code distinguishes the cause. The full set is GitWhyErrorCode in src/types.ts.

JSON output

With --json, stdout carries exactly one valid JSON object and everything else (progress, diagnostics) goes to stderr. --max-bytes clipping is reported explicitly in the envelope and can never produce invalid JSON.

Output safety

Every repository-sourced string — subject, body, author, path, diff line — is sanitized of terminal control sequences before human rendering. A commit message is untrusted input. NO_COLOR, terminal capability, and whether stdout is a TTY are all respected; Git Why never launches a pager.

For the full operational contract (durability, concurrency, freshness, history scope), see Operations & guarantees.

Released under the Apache-2.0 License.