git blame tells you who. git motive tells you why.

gitmotive records the prompt and reasoning behind every line an AI coding agent writes, then gives them back when you ask about that line. It runs on your machine. No LLM, no cloud, no account.

src/fetch.pygit blame

134d8dd9 alex 10-2931import time8c41e07a alex 09-14328c41e07a alex 09-1433from .http import _get134d8dd9 alex 10-2934from .http_errors import UpstreamBusy8c41e07a alex 09-14358c41e07a alex 09-14368c41e07a alex 09-1437def fetch(url, attempts=3):134d8dd9 alex 10-2938    for attempt in range(attempts):134d8dd9 alex 10-2939        try:134d8dd9 alex 10-2940            return _get(url, timeout=10)134d8dd9 alex 10-2941        except UpstreamBusy:134d8dd9 alex 10-2942            time.sleep(2 ** attempt)134d8dd9 alex 10-2943    raise TimeoutError(url)8c41e07a alex 09-1444

intent for line 42git motive

git motive src/fetch.py:42
src/fetch.py:42
  |             time.sleep(2 ** attempt)
  commit   134d8dd9e6  alex  2026-10-29  add retry
  edited   2026-10-29 06:19  by Edit  session 3f9a2c1e  [same commit, line text in edit]  via claude  model claude-sonnet-4-5
  prompt
    add retry with exponential backoff to fetch()
  reasoning
    Wrapping the call in a retry loop; 3 attempts with backoff since the upstream flakes
    under load.
  also changed for same prompt
    src/http_errors.py
    tests/test_fetch.py
Blame names the commit. Motive adds the prompt, the reasoning and the session that wrote line 42.

The why ends with the session

AI agents now write more code than reviewers can absorb. Every line came from a prompt and a chain of reasoning, but that context lives in a chat window. When the session ends, it is gone.

Weeks later, git blame points to a commit and a person, who may not know why the line is there either. The commit message is one sentence. The thinking that produced the code was never saved.

@@ session 3f9a2c1e ended @@  time.sleep(2 ** attempt)- prompt     add retry with exponential backoff to fetch()- reasoning  3 attempts with backoff; upstream flakes under load- session    3f9a2c1e  claude  2026-10-29 06:19

gitmotive keeps those deleted lines.

How it works

  1. Install the CLI

    pipx install gitmotive

    Python 3.10 or newer. No runtime dependencies.

  2. Hook up your agent, once per repo

    gitmotive install --agent claude

    Adds the agent's hooks and a git post-commit hook, and keeps .gitmotive/ out of git. Then use your agent as usual.

  3. Ask any line why it exists

    git motive path/to/file.py:42

    Prints the prompt, the agent's reasoning, the session, the model and the commit. If no hook saw the edit, it says none recorded instead of guessing.

Install

With pipx

pipx install gitmotive

Without pipx

curl -fsSL https://gitmotive.tech/install.sh | sh

Creates a venv in ~/.gitmotive/venv and puts gitmotive and git-motive in ~/.local/bin. Read the script first if you like; it is plain shell.

Agents

Agent--agentStatus
Claude CodeclaudeSupported
CursorcursorSupported
GitHub Copilot CLIcopilotExperimental
oh-my-piompExperimental

Experimental agents record prompts and edits only; their hook payloads are not fully documented yet.

Nothing is guessed

deterministic
Lines are matched to edits through git blame and the recorded edit text. No model reads your code.
local
Events are append-only JSONL in .gitmotive/, or under ~/.gitmotive/ with --scope user. No network calls, no telemetry.
open source
MIT licensed. Read the code, file an issue or send a patch on GitHub.

See it on its own source

The demo is gitmotive's own repository, blamed line by line with the prompts that wrote it. Pick a line and read why it exists.