| name | recall |
| description | Use this skill whenever you start working on a coding task in a git repository — bug fixes, new features, refactors, investigations, anything substantive. It changes how you approach the work: orient on the task before touching code, consult git history when you're grounded enough to know what to look for, and distill the reasoning into a structured commit message when you're done. The goal is that the next agent opening this repo cold can recover the *why* behind every change, not just the *what*. Trigger on any non-trivial work in a project that has a git history, especially when the user mentions bug numbers, issue references, or asks you to fix/extend something that already exists. Do not trigger for one-off shell commands, pure Q&A about a codebase with no edits, or work in directories that aren't git repositories. |
Recall
What this is
A discipline for using git as the project's long-term memory. Every commit you write should record not just what changed, but why — the decisions, the rejected alternatives, the dead ends, the open questions. Every task you start should begin by consulting the relevant history, so you inherit context instead of re-deriving it.
The reader you are writing for is another agent. Do not optimize commit messages for humans skimming git log --oneline. Optimize them for an agent who needs to reconstruct your reasoning. Length is not a concern. Completeness is.
The workflow
At each of the following four points in a task, do the thing described. Scale the effort to the task: a typo fix moves through all four in seconds; a multi-day feature spends real time at each.
1. Orient
Before touching any code or reading any history, articulate the task to yourself. Identify the core of the problem, not just the surface ask. Specifically, answer:
- What is the underlying goal?
- What does success look like, concretely?
- What's the scope — focused fix or architectural?
- What do you already know vs. what do you need to learn?
Keep this short — a paragraph of thinking, not an essay. Do not write it down unless the task is large. Skipping this step makes subsequent history lookups exploratory rather than targeted, which wastes context.
2. Look up history when grounded or surprised
Consult git history at two specific moments:
Grounded lookup. Once orienting has identified the files, modules, or concepts you're about to work in, check their recent history before editing. Use:
git log -p -- <file> — show recent commits touching this file with full diffs and messages. This is the primary retrieval move.
git log --all --grep="<term>" — find commits mentioning a specific topic, bug number, or concept across the whole repo.
git log -S "<string>" — find commits where a specific string or function name was added or removed. Use this when you want to know when something was introduced.
git log --all --grep="#<NN>" — find every commit related to a specific issue number.
git blame <file> — find which commit last touched a specific line. Combine with git show <hash> to read the rationale.
Read enough to answer: has someone tried this before? Is there a decision I should respect? Is there a dead end I'd otherwise repeat? Stop when you have those answers — do not exhaustively read full history.
Surprise lookup. When something unexpected happens during the work — code structured oddly, a test failing for non-obvious reasons, a comment hinting at history, a name that doesn't match its usage — go deeper on the specific surprising thing. Surprise is the signal that prior context exists and matters.
3. Do the work
Do the engineering work. As you go, track four things so you can record them at commit time:
- What you chose, and what you rejected.
- What you tried that didn't work.
- Constraints you discovered that weren't obvious from the task description.
- Anything you left unresolved or punted on.
You do not need to take notes in real time, but you do need to remember enough to write them up at the end. If the task spans multiple commits, write up each commit's portion at its own commit boundary — do not batch all reasoning into the final commit.
4. Distill into the commit message
When you commit, write the message in the format below. Length should be whatever the reasoning requires — there is no upper bound and no need to compress.
Commit message format
<short summary line>
Fixes: #<NN> (omit if no issue is being closed)
Related: <hash>, <hash> (omit if no prior commits are relevant)
## Goal
<What this commit was trying to accomplish, in context. Not just a restatement
of the diff. The underlying problem and why this commit addresses it.>
## Decisions
- <Decision>: <Rationale>. Rejected <alternative> because <reason>.
- <Decision>: <Rationale>.
- ...
## Changes
- <File or area>: <Why it changed. Not what — the diff shows what.>
- ...
## Dead ends
- <Thing tried>: <Why it failed or was abandoned>.
- ...
## Open questions
- <Unresolved thing>: <Context the next person needs>.
- ...
Omit sections that don't apply rather than including them with "None." A pure typo fix might be just a summary line and a one-line Goal. A substantial change will have all sections, with multiple bullets each.
About each section
Summary line. Short, meaningful. Even though the body is the real memory, the summary line is the cheap retrieval surface — when an agent does git log --oneline -- <file>, the summary lines are what they scan to decide which commits to read in full. Make it specific enough to filter on. "fix bug" is useless; "fix checkout timeout when cart has >50 items" is useful.
Fixes. Use Fixes: #NN (or Closes: #NN) when this commit resolves a tracked issue. Hosting platforms (GitHub, GitLab) will auto-close the issue on merge. Agents searching for "what fixed issue #18" can find it with git log --all --grep="#18".
Related. A structured list of prior commit hashes that future readers should consult to understand this one. Use this when this commit is part of a chain — feature introduced in abc1234, bug fixed in def5678, edge case fixed here. The Related: field exists so an agent scanning history can mechanically follow the chain backward without having to parse prose. Inline references in the body are also fine and complementary — use those when you want to cite a specific past commit in context ("we chose X over Y because abc1234 documented that Y hit a connection pool limit"). The structured Related: field is for the chain; inline mentions are for in-context citation.
Goal. The single most important section after the summary line. The next agent reading this commit needs to know what problem you were solving, not just what code you wrote. If your goal was wrong or your scope shifted mid-task, say that.
Decisions. The load-bearing content. Each decision is one bullet, with rationale, and where relevant, the rejected alternatives and why they were rejected. Rejected alternatives are not optional padding — they prevent the next agent from re-deriving and re-rejecting the same options. If you considered three approaches and chose the fourth, the next agent needs to know about all four.
Changes. A rationale per logical change. Not an enumeration of files (the diff shows files). Use this when a single commit makes changes across multiple areas and each needs its own brief justification. For small focused commits, this section can be omitted or collapsed into Goal.
Dead ends. Things you tried that didn't work, with the reason they failed. This is the highest-leverage section for preventing repeated mistakes. If you spent two hours discovering that approach X is incompatible with library Y, record it. The next agent who'd otherwise spend two hours rediscovering it will instead spend ten seconds reading it.
Open questions. Things you noticed but didn't resolve. The next agent picks them up or doesn't, but at least they're not invisible.
Reading history: practical recipes
When orienting on a task, these are the moves that pay off most:
"I'm about to touch file X."
git log -p --follow -- <file> | head -300
The --follow traces renames. head -300 because you usually want recent context, not full history. Increase if recent commits look thin.
"The user mentioned issue #18."
git log --all --grep="#18"
Then git show <hash> on each result.
"Where did this function come from?"
git log -S "function_name" --source --all
Finds commits that added or removed the string. Then git show the introducing commit.
"This line looks weird, why is it like this?"
git blame -w -C -C <file>
-w ignores whitespace changes. -C -C tracks code moved or copied between files. Then git show <hash> on the commit that introduced the line.
"Has this part of the codebase changed recently?"
git log --oneline -20 -- <directory>/
A quick scan of recent activity in an area.
"I want to see the chain of commits related to this work."
Look for Related: lines in commit bodies and follow the chain. Or:
git log --all --grep="Related:.*<hash>"
Finds commits that reference a given hash in their Related field — i.e., descendants of a logical chain.
You don't need to run all of these on every task. Pick the ones that match your situation.
Edge cases and caveats
Young projects with no memory yet
On day one of a project, git log returns one commit and there's nothing to consult. That's fine — the skill does nothing on the read side, and starts accumulating memory on the write side from the first real commit forward. Don't manufacture ceremony when there's nothing to read.
Work in progress, before any commit
If you're hours into a task and haven't committed yet, the rationale doesn't exist in git. Two responses:
- Commit more often. Each logical step gets a commit with its own structured message. This is good practice independent of memory; it just becomes more important here.
- If a session might be interrupted before a commit lands, write a checkpoint commit even if the work isn't done. Mark it as such in the summary line (
wip: <thing>) and include the structured body. You can always squash later if you want a clean history, but the reasoning is preserved.
Architecture decisions that don't belong to a single commit
Rare but real. "We use Tokio across the project" or "all database access goes through the repository pattern" are choices that influence many commits and don't have a single natural home in a diff.
For these, an Architecture Decision Record (ADR) file in docs/decisions/ or similar is the right answer — committed like any other file, with the structured format inside the file rather than in the commit message. The commit that introduces the ADR can be terse; the file itself is the memory.
But: ADRs should be rare. If you find yourself writing them frequently, you're probably mistaking tactical decisions for architectural ones. The default mechanism is the commit message. Reach for an ADR only when a decision is genuinely cross-cutting, deliberately project-wide, and the next agent would otherwise be unable to find it because there's no single file to git log.
Trivial commits
A typo fix, a formatting change, a dependency bump — these don't need the full structure. A summary line and a one-line Goal is fine. The skill scales down as well as up; don't impose ceremony where there's no reasoning to preserve.
When the diff and the rationale disagree
If your understanding of the work shifts mid-commit ("I started fixing a bug but discovered the real issue was deeper"), update the message to reflect what actually happened, not the original plan. Commit messages should describe reality. If reality changed, the message should too — and that shift is itself worth recording.