Commit Hygiene logo

Commit Hygiene

Community
alinaqi
commit-hygiene

Atomic commits, PR size limits, commit thresholds, stacked PRs

Overview

Publisheralinaqi
Repositorymaggy
Skill namecommit-hygiene
Stars
707
Forks
57
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by alinaqi on GitHub. Read the source before you install it.

Installation

Install the Commit Hygiene AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/alinaqi/maggy/tree/main/skills/commit-hygiene
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/alinaqi/maggy.git /tmp/maggy
mkdir -p .claude/skills
cp -r /tmp/maggy/skills/commit-hygiene .claude/skills/commit-hygiene
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Commit Hygiene in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Commit Hygiene on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Commit Hygiene is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Commit Hygiene Skill

Purpose: Keep commits atomic, PRs reviewable, and git history clean. Advise when it's time to commit before changes become too large.


Core Philosophy

┌─────────────────────────────────────────────────────────────────┐
│  ATOMIC COMMITS                                                  │
│  ─────────────────────────────────────────────────────────────  │
│  One logical change per commit.                                  │
│  Each commit should be self-contained and deployable.            │
│  If you need "and" to describe it, split it.                     │
├─────────────────────────────────────────────────────────────────┤
│  SMALL PRS WIN                                                   │
│  ─────────────────────────────────────────────────────────────  │
│  < 400 lines changed = reviewed in < 1 hour                      │
│  > 1000 lines = likely rubber-stamped or abandoned               │
│  Smaller PRs = faster reviews, fewer bugs, easier reverts        │
├─────────────────────────────────────────────────────────────────┤
│  COMMIT EARLY, COMMIT OFTEN                                      │
│  ─────────────────────────────────────────────────────────────  │
│  Working code? Commit it.                                        │
│  Test passing? Commit it.                                        │
│  Don't wait for "done" - commit at every stable point.           │
└─────────────────────────────────────────────────────────────────┘

Commit Size Thresholds

Warning Thresholds (Time to Commit!)

MetricYellow ZoneRed ZoneAction
Files changed5-10 files> 10 filesCommit NOW
Lines added150-300 lines> 300 linesCommit NOW
Lines deleted100-200 lines> 200 linesCommit NOW
Total changes250-400 lines> 400 linesCommit NOW
Time since last commit30-60 min> 60 minConsider committing

Ideal Commit Size

┌─────────────────────────────────────────────────────────────────┐
│  IDEAL COMMIT                                                    │
│  ─────────────────────────────────────────────────────────────  │
│  Files: 1-5                                                      │
│  Lines: 50-200 total changes                                     │
│  Scope: Single logical unit of work                              │
│  Message: Describes ONE thing                                    │
└─────────────────────────────────────────────────────────────────┘

Check Current State (Run Frequently)

Quick Status Check

bash
# See what's changed (staged + unstaged)
git status --short

# Count files and lines changed
git diff --stat
git diff --cached --stat  # Staged only

# Get totals
git diff --shortstat
# Example output: 8 files changed, 245 insertions(+), 32 deletions(-)

Detailed Change Analysis

bash
# Full diff summary with file names
git diff --stat HEAD

# Just the numbers
git diff --numstat HEAD | awk '{add+=$1; del+=$2} END {print "+"add" -"del" total:"add+del}'

# Files changed count
git status --porcelain | wc -l

Pre-Commit Check Script

bash
#!/bin/bash
# scripts/check-commit-size.sh

# Thresholds
MAX_FILES=10
MAX_LINES=400
WARN_FILES=5
WARN_LINES=200

# Get stats
FILES=$(git status --porcelain | wc -l | tr -d ' ')
STATS=$(git diff --shortstat HEAD 2>/dev/null)
INSERTIONS=$(echo "$STATS" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
DELETIONS=$(echo "$STATS" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
TOTAL=$((INSERTIONS + DELETIONS))

echo "📊 Current changes: $FILES files, +$INSERTIONS -$DELETIONS ($TOTAL total lines)"

# Check thresholds
if [ "$FILES" -gt "$MAX_FILES" ] || [ "$TOTAL" -gt "$MAX_LINES" ]; then
    echo "🔴 RED ZONE: Commit immediately! Changes are too large."
    echo "   Consider splitting into multiple commits."
    exit 1
elif [ "$FILES" -gt "$WARN_FILES" ] || [ "$TOTAL" -gt "$WARN_LINES" ]; then
    echo "🟡 WARNING: Changes getting large. Commit soon."
    exit 0
else
    echo "🟢 OK: Changes are within healthy limits."
    exit 0
fi

When to Commit

Commit Triggers (Any One = Commit)

TriggerExample
Test passesJust got a test green → commit
Feature completeFinished a function → commit
Refactor doneRenamed variable across files → commit
Bug fixedFixed the issue → commit
Before switching contextAbout to work on something else → commit
Clean compileCode compiles/lints clean → commit
Threshold hit> 5 files or > 200 lines → commit

Commit Immediately If

  • ✅ Tests are passing after being red
  • ✅ You're about to make a "big change"
  • ✅ You've been coding for 30+ minutes
  • ✅ You're about to try something risky
  • ✅ The current state is "working"

Don't Wait For

  • ❌ "Perfect" code
  • ❌ All features done
  • ❌ Full test coverage
  • ❌ Code review from yourself
  • ❌ Documentation complete

Atomic Commit Patterns

Good Atomic Commits

✅ "Add email validation to signup form"
   - 3 files: validator.ts, signup.tsx, signup.test.ts
   - 120 lines changed
   - Single purpose: email validation

✅ "Fix null pointer in user lookup"
   - 2 files: userService.ts, userService.test.ts
   - 25 lines changed
   - Single purpose: fix one bug

✅ "Refactor: Extract PaymentProcessor class"
   - 4 files: payment.ts → paymentProcessor.ts + types
   - 180 lines changed
   - Single purpose: refactoring

Bad Commits (Too Large)

❌ "Add authentication, fix bugs, update styles"
   - 25 files changed
   - 800 lines changed
   - Multiple purposes mixed

❌ "WIP"
   - Unknown scope
   - No clear purpose
   - Hard to review/revert

❌ "Updates"
   - 15 files changed
   - Mix of features, fixes, refactors
   - Impossible to review properly

Splitting Large Changes

Strategy 1: By Layer

Instead of one commit with:
  - API endpoint + database migration + frontend + tests

Split into:
  1. "Add users table migration"
  2. "Add User model and repository"
  3. "Add GET /users endpoint"
  4. "Add UserList component"
  5. "Add integration tests for user flow"

Strategy 2: By Feature Slice

Instead of one commit with:
  - All CRUD operations for users

Split into:
  1. "Add create user functionality"
  2. "Add read user functionality"
  3. "Add update user functionality"
  4. "Add delete user functionality"

Strategy 3: Refactor First

Instead of:
  - Feature + refactoring mixed

Split into:
  1. "Refactor: Extract validation helpers" (no behavior change)
  2. "Add email validation using new helpers" (new feature)

Strategy 4: By Risk Level

Instead of:
  - Safe changes + risky changes together

Split into:
  1. "Update dependencies" (safe, isolated)
  2. "Migrate to new API version" (risky, separate)

PR Size Guidelines

Optimal PR Size

MetricOptimalAcceptableToo Large
Files1-1010-20> 20
Lines changed50-200200-400> 400
Commits1-55-10> 10
Review time< 30 min30-60 min> 60 min

PR Size vs Defect Rate

┌─────────────────────────────────────────────────────────────────┐
│  RESEARCH FINDINGS (Google, Microsoft studies)                  │
│  ─────────────────────────────────────────────────────────────  │
│  PRs < 200 lines: 15% defect rate                               │
│  PRs 200-400 lines: 23% defect rate                             │
│  PRs > 400 lines: 40%+ defect rate                              │
│                                                                 │
│  Review quality drops sharply after 200-400 lines.              │
│  Large PRs get "LGTM" rubber stamps, not real reviews.          │
└─────────────────────────────────────────────────────────────────┘

When PR is Too Large

bash
# Check PR size before creating
git diff main --stat
git diff main --shortstat

# If too large, consider:
# 1. Split into multiple PRs (stacked PRs)
# 2. Create feature flag and merge incrementally
# 3. Use draft PR for early feedback

Commit Message Format

Structure

<type>: <description> (50 chars max)

[optional body - wrap at 72 chars]

[optional footer]

Types

TypeUse For
featNew feature
fixBug fix
refactorCode change that neither fixes nor adds
testAdding/updating tests
docsDocumentation only
styleFormatting, no code change
choreBuild, config, dependencies

Examples

feat: Add email validation to signup form

fix: Prevent null pointer in user lookup

refactor: Extract PaymentProcessor class

test: Add integration tests for checkout flow

chore: Update dependencies to latest versions

Git Workflow Integration

Pre-Commit Hook for Size Check

bash
#!/bin/bash
# .git/hooks/pre-commit

MAX_LINES=400
MAX_FILES=15

FILES=$(git diff --cached --name-only | wc -l | tr -d ' ')
STATS=$(git diff --cached --shortstat)
INSERTIONS=$(echo "$STATS" | grep -oE '[0-9]+ insertion' | grep -oE '[0-9]+' || echo 0)
DELETIONS=$(echo "$STATS" | grep -oE '[0-9]+ deletion' | grep -oE '[0-9]+' || echo 0)
TOTAL=$((INSERTIONS + DELETIONS))

if [ "$TOTAL" -gt "$MAX_LINES" ]; then
    echo "❌ Commit too large: $TOTAL lines (max: $MAX_LINES)"
    echo "   Consider splitting into smaller commits."
    echo "   Use 'git add -p' for partial staging."
    exit 1
fi

if [ "$FILES" -gt "$MAX_FILES" ]; then
    echo "❌ Too many files: $FILES (max: $MAX_FILES)"
    echo "   Consider splitting into smaller commits."
    exit 1
fi

echo "✅ Commit size OK: $FILES files, $TOTAL lines"

Partial Staging (Split Large Changes)

bash
# Stage specific hunks interactively
git add -p

# Stage specific files
git add path/to/specific/file.ts

# Stage with preview
git add -N file.ts  # Intent to add
git diff            # See what would be added
git add file.ts     # Actually add

Unstage If Too Large

bash
# Unstage everything
git reset HEAD

# Unstage specific files
git reset HEAD path/to/file.ts

# Stage just what you need for THIS commit
git add -p

Claude Integration

Periodic Check During Development

Claude should run this check after every significant change:

bash
# Quick status
git diff --shortstat HEAD

Thresholds for Claude to advise committing:

ConditionClaude Action
> 5 files changedSuggest: "Consider committing current changes"
> 200 lines changedSuggest: "Changes are getting large, commit recommended"
> 10 files OR > 400 linesWarn: "⚠️ Commit now before changes become unmanageable"
Test just passedSuggest: "Good checkpoint - commit these passing tests"
Refactoring completeSuggest: "Refactoring done - commit before adding features"

Claude Commit Reminder Messages

📊 Status: 7 files changed, +180 -45 (225 total)
💡 Approaching commit threshold. Consider committing current work.

---

📊 Status: 12 files changed, +320 -80 (400 total)
⚠️ Changes are large! Commit now to keep PRs reviewable.
   Suggested commit: "feat: Add user authentication flow"

---

📊 Status: 3 files changed, +85 -10 (95 total)
✅ Tests passing. Good time to commit!
   Suggested commit: "fix: Validate email format on signup"

Stacked PRs (For Large Features)

When a feature is genuinely large, use stacked PRs:

┌─────────────────────────────────────────────────────────────────┐
│  STACKED PR PATTERN                                             │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  main ─────────────────────────────────────────────────────────│
│    └── PR #1: Database schema (200 lines) ← Review first       │
│         └── PR #2: API endpoints (250 lines) ← Review second   │
│              └── PR #3: Frontend (300 lines) ← Review third    │
│                                                                 │
│  Each PR is reviewable independently.                           │
│  Merge in order: #1 → #2 → #3                                   │
└─────────────────────────────────────────────────────────────────┘

Creating Stacked PRs

bash
# Create base branch
git checkout -b feature/auth-schema
# ... make changes ...
git commit -m "feat: Add users table schema"
git push -u origin feature/auth-schema
gh pr create --base main --title "feat: Add users table schema"

# Create next branch FROM the first
git checkout -b feature/auth-api
# ... make changes ...
git commit -m "feat: Add authentication API endpoints"
git push -u origin feature/auth-api
gh pr create --base feature/auth-schema --title "feat: Add auth API endpoints"

# And so on...

Checklist

Before Every Commit

  • Changes are for ONE logical purpose
  • Tests pass (if applicable)
  • Lint/typecheck pass
  • < 10 files changed
  • < 400 lines total
  • Commit message describes ONE thing

Before Creating PR

  • Total lines < 400 (ideal < 200)
  • All commits are atomic
  • No "WIP" or "fixup" commits
  • PR title describes the change
  • Description explains why, not just what

Red Flags (Stop and Split)

  • ❌ Commit message needs "and"
  • ❌ > 10 files in one commit
  • ❌ > 400 lines in one commit
  • ❌ Mix of features, fixes, and refactors
  • ❌ "I'll clean this up later"

Quick Reference

Thresholds

Files:  ≤ 5 = 🟢  |  6-10 = 🟡  |  > 10 = 🔴
Lines:  ≤ 200 = 🟢  |  201-400 = 🟡  |  > 400 = 🔴
Time:   ≤ 30min = 🟢  |  30-60min = 🟡  |  > 60min = 🔴

Commands

bash
# Quick status
git diff --shortstat HEAD

# Detailed file list
git diff --stat HEAD

# Partial staging
git add -p

# Check before PR
git diff main --shortstat

Commit Now If

  • ✅ Tests just passed
  • ✅ > 200 lines changed
  • ✅ > 5 files changed
  • ✅ About to switch tasks
  • ✅ Current state is "working"

Frequently asked questions

What does the Commit Hygiene AI skill do?

Atomic commits, PR size limits, commit thresholds, stacked PRs

Why use Commit Hygiene on TypingMind?

Because you install it once and use it with any model. Commit Hygiene is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Commit Hygiene in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/alinaqi/maggy/tree/main/skills/commit-hygiene. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Commit Hygiene?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Commit Hygiene?

As many as you like. As long as a model supports skills, you can use Commit Hygiene with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Commit Hygiene AI skill free?

Yes. It is published on GitHub by alinaqi under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇