diff --git a/skills/commit/SKILL.md b/skills/commit/SKILL.md index 00b3217..6d172c6 100644 --- a/skills/commit/SKILL.md +++ b/skills/commit/SKILL.md @@ -1,56 +1,190 @@ --- name: commit -description: Create atomic git commits following the three-pass methodology. +description: Create atomic git commits using a four-pass methodology — content, standards, final review, and post-commit verification. Use when committing code or documentation changes. Triggers on "commit", "git commit", or when the user asks to commit changes. --- -# commit +# Commit -## Trigger +> Create atomic git commits using a four-pass methodology that separates content decisions from formatting standards. -`/commit` +## Skill documents -## Process +| File | Purpose | +|:-----|:--------| +| [SKILL.md](SKILL.md) | Overview, commit format reference, atomicity rules | +| [WORKFLOW.md](WORKFLOW.md) | Four-pass execution sequence | +| [references/chris-beams-commit-style.md](references/chris-beams-commit-style.md) | The 7 rules our format is built on | -Read `./atomic-git-commits.md` in this skill's directory for the full reference. Then follow these steps. +--- + +## When to use -### 1. Content pass +- User asks to commit staged or unstaged changes +- User runs `/commit` +- Changes are ready and the user explicitly requests a commit -- Run `pre-commit run --all-files` to fix formatting first -- Check `git status` and `git diff --staged` to understand what's staged -- Identify how many distinct logical/atomic changes exist -- Summarize them: one sentence per proposed commit +## When NOT to use -### 2. Get user confirmation +- No changes exist to commit +- User has not explicitly asked for a commit -Ask the user which change(s) to proceed with. Even if there is only ONE logical change, get explicit confirmation before proceeding. +--- -### 3. Standards check +## Quick reference -For each commit: +**One logical change per commit. Separate concerns across four passes: content, standards, final review, post-commit verification.** -- Standard prefix used (feat:, fix:, docs:, refactor:, style:, test:, build:, ci:, perf:) -- Subject capitalized after colon -- Imperative mood ("Add" not "Added") -- Under 50 characters for subject -- Body explains WHY not just what -- 72 character wrap for body lines +--- + +## Required reading + +Read before executing: + +1. [references/atomic-git-commits.md](references/atomic-git-commits.md) — the full atomic commit methodology and Conventional Commits standard + +--- + +## Key principles + +| Principle | What it means | +|:----------|:-------------| +| Atomic | One complete logical change per commit — not by size, by coherence | +| Imperative mood | "Add feature" not "Added feature" — completes "If applied, this commit will..." | +| WHY not what | Body explains the reasoning, not just a list of files | +| Working state | All tests pass after the commit | +| Selective staging | Stage files per logical change, not everything at once | + +### Test-driven commits + +Every commit should pass all tests: -### 4. Final review +1. Write failing tests for new functionality +2. Implement the feature +3. Ensure all tests pass +4. Commit the complete change -- Re-read the commit message. Does it tell a complete story? -- Check the diff one more time. Are all changes intentional? -- Can this be reverted independently? +This ensures each commit represents a working state of the codebase. -### 5. Commit +--- + +## The coherence test + +> If you removed any file from this commit, would the remaining files still represent the same complete logical change? + +- If removing a file leaves a hole → it belongs +- If removing a file leaves a perfectly coherent commit → it does not belong + +--- + +## Common AI atomicity mistakes -Use `git commit -e -m "your message"` so the message is pre-filled but the user can edit it in their editor before finalizing. +**These are not valid reasons for combining changes into one commit:** -NEVER add a co-author credit. +- **Modified in the same session** — files changed during one conversation are not automatically one atomic commit +- **Sharing a prefix** — using `docs:` on two unrelated documentation changes does not make them atomic +- **Requested as one task** — "update the docs and fix the bug" is two tasks and two commits +- **Touching the same area** — editing three files in `src/auth/` for different reasons is three commits +- **"While I was in there" changes** — noticing a typo while fixing a bug does not make the typo part of the bug fix -### 6. Output +**Example of mixed changes that should be separated**: -Display the full commit message: +```bash +# BAD: Two different logical changes in one commit +git add TODO.md docs/research/ai-coding/what-is-a-frame.md +# This mixes: project management (TODO) + documentation (frame concept) +# GOOD: Separate atomic commits +git add TODO.md +git commit -m "build: Add TODO.md with AI frame loading system entry" + +git add docs/research/ai-coding/what-is-a-frame.md +git commit -m "docs: Create comprehensive frame concept documentation" ``` -git log -1 --format="%h %s%n%n%b" + +--- + +## Content focus blindness + +Both people and AI consistently miss formatting standards while focused on content logic. The four-pass approach solves this by making standards verification a dedicated step (Pass 2) separate from content decisions (Pass 1). + +--- + +## Commit message format + +```text +: + + + +- Bullet points for specific changes +``` + +### Standard prefixes + +| Prefix | Use for | +|:-------|:--------| +| `feat:` | New features or functionality | +| `fix:` | Bug fixes and corrections | +| `docs:` | Documentation only changes | +| `refactor:` | Code restructuring without changing behaviour | +| `style:` | Formatting, white-space changes | +| `test:` | Adding or updating tests | +| `build:` | Build system or dependency changes | +| `chore:` | Maintenance tasks | +| `perf:` | Performance improvements | +| `ci:` | CI configuration changes | + +### Subject line rules + +- Standard prefix, lowercase (e.g. `feat:`, `fix:`) +- Capitalize first word after colon ("Add" not "add") +- Imperative mood ("Add" not "Added") +- No period at end +- Under 50 characters total + +### Body rules + +- Blank line after subject +- Wrap at 72 characters +- Explain WHY, not just what +- Start with explanatory paragraph before bullets +- Add warmth — show care for users and future developers + +### Example + +```text +fix: Fix null pointer in payment validation + +When users had incomplete billing data, validation would crash +instead of showing helpful errors. This adds proper null checks +and returns meaningful validation messages. + +- Add null checks for all required fields +- Return validation errors instead of exceptions +- Include tests for edge cases with missing data ``` + +--- + +## The pre-commit atomicity trap + +Pre-commit hooks can accidentally cause you to commit multiple unrelated files together: + +1. You stage one file: `git add file1.js` +2. You run `git commit` and hooks fix OTHER files +3. You run `git add -A` to include the fixes +4. **Result**: your commit now includes unrelated files + +**Prevention**: Run `pre-commit run --all-files` in Pass 0. This fixes all formatting upfront so hooks have nothing to fix during the actual commit. + +--- + +## Execution + +**Read and follow every step in [WORKFLOW.md](WORKFLOW.md).** + +--- + +## The governing principle + +> Make each commit a gift to your future self — one complete idea, clearly explained, independently revertible. diff --git a/skills/commit/WORKFLOW.md b/skills/commit/WORKFLOW.md new file mode 100644 index 0000000..8ec5076 --- /dev/null +++ b/skills/commit/WORKFLOW.md @@ -0,0 +1,223 @@ +# Commit workflow + +**Follow these steps in order. Do not skip any step.** + +--- + +## Execution sequence + +| Pass | Action | Goal | +|:-----|:-------|:-----| +| 0 | **Pre-flight** | Fix formatting, identify atomic changes | +| 1 | **Content** | Stage selectively, verify one logical change | +| 2 | **Standards** | Verify message format against checklists | +| 3 | **Final review** | Sanity check before committing | +| 4 | **Post-commit** | Verify atomicity after committing | + +--- + +## Before you start + +Read [SKILL.md](SKILL.md) first — it contains the coherence test, AI atomicity mistakes, commit format reference, and the pre-commit atomicity trap. + +--- + +## Pass 0: Pre-flight + +**Goal**: Clean slate before staging. + +1. Run `pre-commit run --all-files` to fix formatting issues +2. Stage any formatting fixes: `git add .` then commit as `style: Fix formatting issues` +3. Run `git status` to see all changed files +4. Run `git diff` to understand the changes +5. Identify how many **logical changes** exist + +### Multiple logical changes? + +Ask: could any subset of these changes be reverted independently and still make sense? + +| Signal | Action | +|:-------|:-------| +| All changes serve one purpose | Proceed as one commit | +| Changes serve different purposes | Separate into multiple commits | +| Bug fix + unrelated feature | Two commits | +| Code change + unrelated formatting | Two commits | + +Check the [common AI atomicity mistakes](SKILL.md#common-ai-atomicity-mistakes) — do not group changes just because they were made in the same session, share a prefix, or touch the same area. + +**Common multi-change scenarios**: + +- Bug fix + unrelated feature improvement +- Documentation updates + code changes +- Refactoring + new functionality +- Multiple unrelated bug fixes +- New file creation + existing file modifications for different purposes + +--- + +## Pass 1: Content + +**Goal**: Stage the right files for one atomic change. + +1. **Stage selectively** — `git add` specific files, not `git add -A` +2. **Review staged changes** — `git diff --cached` +3. **Verify completeness** — are all files needed for this change staged? +4. **Apply the [coherence test](SKILL.md#the-coherence-test)** — does removing any file leave a hole? + +### Staging techniques + +**Stage specific files**: + +```bash +git add file1.js file2.js +``` + +**Stage partial file changes** (when one file contains changes for multiple commits): + +```bash +git add -p filename.js +# Select which hunks belong to each atomic change +``` + +--- + +## Pass 2: Standards + +**Goal**: Draft the commit message and verify formatting against [SKILL.md](SKILL.md#commit-message-format). + +This is a dedicated pass because of [content focus blindness](SKILL.md#content-focus-blindness) — both people and AI miss formatting rules while focused on content logic. + +### Subject line checklist (50 chars max) + +- [ ] **Standard prefix used** (feat:, docs:, fix:, refactor:, style:, test:, build:, etc.) — **AI frequently misses this** +- [ ] **Subject capitalized after colon** ("feat: Add feature" not "feat: add feature") +- [ ] **Imperative mood** ("Add" not "Added" or "Adds") +- [ ] **Under 50 characters** total length +- [ ] **No period at end** of subject line +- [ ] **Completes**: "If applied, this commit will [your subject]" + +### Body and content checklist (72 chars per line) + +- [ ] **Blank line after subject** line +- [ ] **Wrap at 72 characters** maximum per line +- [ ] **Explains WHY** not just what changed +- [ ] **Start with explanatory paragraph** before bullet points +- [ ] **Use bullet points for lists** of changes +- [ ] **One atomic change** (can be reverted independently) +- [ ] **Add warmth** — show care for users and future developers + +### Commit execution + +Use multiple `-m` flags to avoid heredoc issues with special characters: + +```bash +git commit -m "type: Subject line here" -m "Explanatory paragraph about +why this change was needed. Keep lines under +72 characters. + +- Specific change one +- Specific change two" +``` + +### Pre-commit hook failures + +If the commit fails because hooks fix files: + +1. Review what the hooks changed +2. Stage the hook-fixed files **only if they belong to this atomic change** +3. If hooks fixed unrelated files, commit your atomic change first, then handle hook fixes separately (see [the pre-commit atomicity trap](SKILL.md#the-pre-commit-atomicity-trap)) +4. Re-run the commit + +--- + +## Pass 3: Final review + +**Goal**: Last sanity check before the commit lands. + +- [ ] Does this commit represent one complete idea? +- [ ] Do all tests pass? +- [ ] Re-read the commit message — does it tell a complete story? +- [ ] Check the diff one more time — are all changes intentional? +- [ ] Can this be reverted independently? +- [ ] Is anything missing? +- [ ] Would this make sense to someone reviewing it in 6 months? + +This is the crucial last moment to catch anything that slipped through while focused on content (Pass 1) and formatting (Pass 2). + +If any check fails, go back to Pass 1 or Pass 2 as needed. + +--- + +## Pass 4: Post-commit verification + +**Goal**: Verify the commit is truly atomic after it lands. + +```bash +git diff --stat HEAD~1 HEAD +git log -1 +``` + +- [ ] All files serve the single purpose described in the commit message +- [ ] No hitchhikers — could any file be removed and still leave a coherent change? +- [ ] No stowaways — are there files that serve a different purpose? +- [ ] Clean revert — if reverted, would it remove exactly one logical improvement? + +### If verification fails + +```bash +# Undo the commit but keep all changes staged +git reset --soft HEAD~1 + +# Unstage everything +git reset HEAD . + +# Now re-stage and commit each logical change separately +git add +git commit -m "prefix: First logical change" + +git add +git commit -m "prefix: Second logical change" +``` + +### Folding mistakes + +If a commit has a small error (typo, missed file) that belongs to the same logical change: + +```bash +git add . +git commit --amend --no-edit +``` + +Only use `--amend` for unpushed commits. + +--- + +## Output + +After a successful commit, display the result: + +```bash +git log -1 --format="%h %s%n%n%b" +``` + +Format: + +```text +Committed: + + + + +``` + +--- + +## Verification gate + +**All four passes must complete before the commit is final.** + +- [ ] Pre-flight: formatting fixed, atomic changes identified +- [ ] Content: files staged selectively, coherence test passed +- [ ] Standards: message format verified against checklists +- [ ] Final review: sanity check passed +- [ ] Post-commit: atomicity verified, output displayed diff --git a/skills/commit/atomic-git-commits.md b/skills/commit/references/atomic-git-commits.md similarity index 100% rename from skills/commit/atomic-git-commits.md rename to skills/commit/references/atomic-git-commits.md diff --git a/skills/commit/references/chris-beams-commit-style.md b/skills/commit/references/chris-beams-commit-style.md new file mode 100644 index 0000000..3a8333f --- /dev/null +++ b/skills/commit/references/chris-beams-commit-style.md @@ -0,0 +1,71 @@ +# Chris Beams commit style + +Chris Beams is a software engineer who wrote one of the most widely cited articles on how to write good Git commit messages. His influential post ["How to Write a Git Commit Message"](https://chris.beams.io/posts/git-commit/) established what has become the de facto style guide for many development teams. + +--- + +## The 7 rules of great commit messages + +1. **Separate subject from body with a blank line** +2. **Limit the subject line to 50 characters** +3. **Capitalize the subject line** +4. **Do not end the subject line with a period** +5. **Use the imperative mood in the subject line** +6. **Wrap the body at 72 characters** +7. **Use the body to explain what and why vs. how** + +--- + +## Example git commit message + +```text +Summarize changes in around 50 characters or less + +More detailed explanatory text, if necessary. Wrap it to about 72 +characters or so. In some contexts, the first line is treated as the +subject of the commit and the rest of the text as the body. The +blank line separating the summary from the body is critical (unless +you omit the body entirely); various tools like log, shortlog +and rebase can get confused if you run the two together. + +Explain the problem that this commit is solving. Focus on why you +are making this change as opposed to how (the code explains that). +Are there side effects or other unintuitive consequences of this +change? Here's the place to explain them. + +Further paragraphs come after blank lines. + + - Bullet points are okay, too + + - Typically a hyphen or asterisk is used for the bullet, preceded + by a single space, with blank lines in between, but conventions + vary here + +If you use an issue tracker, put references to them at the bottom, +like this: + +Resolves: #123 +See also: #456, #789 +``` + +--- + +## Why the Chris Beams style works + +Written during his time in software engineering and leadership roles, Beams' guidelines address the practical realities of collaborative development: + +- **Tool compatibility** — the character limits work perfectly with git's built-in formatting +- **Human readability** — natural English structure that reads like proper sentences +- **Scalability** — works for small personal projects and large enterprise codebases +- **Timeless principles** — focus on clear communication rather than specific tooling + +--- + +## Adoption and influence + +The Chris Beams style has become the standard because it: + +- Balances structure with flexibility +- Prioritizes human understanding over automation +- Has stood the test of time across different development eras +- Provides clear, actionable rules that teams can adopt immediately