Skip to content
Agentmart
Submit a tool

commit

Automate the workflow of grouping unstaged changes or squashing unpushed commits into logical, high-quality conventional commits.

Skill by drlove2002

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/drlove2002-commit

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Automate the workflow of grouping unstaged changes or squashing unpushed commits into logical, high-quality conventional commits. Use to clean up git history, create smart commits from a dirty worktree, or squash many small commits.

Use cases: productivity

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/commit

What's inside

Skill name
commit
Description
Automate the workflow of grouping unstaged changes or squashing unpushed commits into logical, high-quality conventional commits. Use to clean up git history, create smart commits from a dirty worktree, or squash many small commits.
License
MIT
Instructions
184 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Git History & Smart Commits

Use this skill when the user wants to commit a dirty worktree logically, or clean up existing unpushed commits before a PR.

## 0. Discover Git Repos

The workspace root may not be a git repo (it may contain multiple sub-projects). Never assume `git` at the root works. Check the current directory first, then scan for nested repos sorted by recent activity:

```bash
# First: check if PWD itself is a git repo
if git rev-parse --show-toplevel >/dev/null 2>&1; then
  repo="$PWD"
  ts=$(git -C "$repo" log -1 --format="%at" 2>/dev/null || echo "0")
  dirty=$(git -C "$repo" status --porcelain 2>/dev/null | wc -l)
  echo "DIRECT|$ts|$repo|$dirty"
fi

# Then: scan for nested git repos
find "$PWD" -maxdepth 3 -name ".git" -not -path "*/node_modules/*" -type d 2>/dev/null | while read g; do
  repo="$(dirname "$g")"
  # Skip if it's the same as PWD (already handled above)
  [ "$repo" = "$PWD" ] && continue
  ts=$(git -C "$repo" log -1 --format="%at" 2>/dev/null || echo "0")
  dirty=$(git -C "$repo" status --porcelain 2>/dev/null | wc -l)
  echo "$ts|$repo|$dirty"
done | sort -t'|' -k1 -rn | while IFS='|' read ts repo dirty; do
  echo "--- $repo ($dirty dirty) ---"
  git -C "$repo" status --short
  echo "Recent commits:"
  git -C "$repo" log --oneline -3 2>/dev/null
  echo ""
done
```

**After running:**
- If only one repo has changes, proceed with that repo automatically.
- If multiple repos have changes, present the list to the user and ask which one to commit.
- If no repo has changes, tell the user and stop.
- All subsequent `git` commands must use `git -C <repo_path> ...` or `cd <repo_path>` first.

## 1. Determine Mode

With the target repo determined, look at its git state:
- `git -C <repo> status`
- `git -C <repo> log origin/main..HEAD --oneline` (to see unpushed commits — for reference only, never push)

If the user has **unstaged/dirty changes**, use **Smart Commit Mode**.
If the user has a clean worktree but **many unpushed small commits**, use **Squash Mode**.

## Smart Commit Mode

Goal: Create well-grouped commits based on logical boundaries from a dirty worktree.

1. **Inspect changes:**
   - `git -C <repo> status --short`
   - `git -C <repo> diff --stat`
   - `git -C <repo> diff --staged --stat`
   - `git -C <repo> diff`
   - `git -C <repo> diff --staged`
2. **Normalize the index before grouping:**
   - Read `git status --short` carefully. First-column letters mean the change is already staged.
   - If any unrelated changes are staged, run `git -C <repo> restore --staged :/` before staging logical groups. This clears the index without touching the worktree.
   - Verify with `git -C <repo> diff --staged --stat`; it should be empty before you start staging the first logical group unless the whole staged set belongs in commit 1.
3. **Group files:**
   Group by feature boundary, bug fix, refactor, or paired tests/implementation.
4. **Stage & Commit:**
   - Stage one logical group at a time (`git -C <repo> add <file>`).
   - Before every commit, verify scope with `git -C <repo> diff --staged --name-status` and `git -C <repo> diff --staged --stat`.
   - If extra files appear, stop and run `git -C <repo> restore --staged :/`, then restage only the intended group.
   - Create a conventional commit (see format below).

## Hunk-Level Commit Mode

Goal: When the same file contains unrelated changes that should land in different commits, use selective patch application instead of file-level staging.

**Only use this when a single file has two or more logically unrelated changes.** Default to file-level staging otherwise.

1. **Inspect hunks:**
   `git -C <repo> diff <file>` — review the full diff of the affected file. Use default context (`-U3`); never use `-U0` or `-U1` (too bare to anchor).
2. **Identify hunk boundaries:**
   Each hunk starts with `@@ -start,len +start,len @@`. Use these markers to split the diff into separate patch files. If two unrelated changes appear in the **same hunk**, they are too close together for `git apply` to separate. Either commit them together with a clear message, or ask the user to reorder the file first.
3. **Create curated patch files:**
   Write the target hunks (including their `@@` headers and trailing context) into `/tmp/patch-<n>.diff`. Use `write` tool; never hand-construct patch headers.
4. **Stage via apply:**
   - `git -C <repo> apply --cached /tmp/patch-1.diff` — stages only those hunks
   - Verify with `git -C <repo> diff --staged` and `git -C <repo> diff`
5. **Commit:** Create a conventional commit for this logical group.
6. **Repeat** with remaining patches until the file is clean, then clean up `/tmp/patch-*.diff`.

**Critical rule:** Every patch must apply cleanly. If `git apply --cached` fails, the hunks are overlapping or stale — re-extract them from a fresh `git diff`. Never force-apply with `--reject`. Changes that appear in the same hunk are inseparable; do not fight git to split them.

## Squash Mode

Goal: Review and squash unpushed commits into a few high-quality logical commits.

1. **Verify State:** Ensure the worktree is clean.
2. **Identify unpushed commits:** `git -C <repo> log origin/main..HEAD --oneline` to see what's unreachable from upstream.
3. **Propose plan:** Tell the user which commits you'd squash into which groups, and ask for approval before moving `HEAD`.
4. **Soft reset:** After approval, run `git -C <repo> reset --soft origin/main`. Soft reset preserves file contents and stages the squashed diff.
5. **Normalize index:** Run `git -C <repo> restore --staged :/` to clear the index, then proceed to stage and commit logical groups.

## Bad Local Commit Recovery

Use this when the last local commit accidentally mixed unrelated staged changes.

1. Inspect the bad commit: `git -C <repo> show --name-status --stat HEAD`.
2. If the commit should be split and has not been pushed, ask for approval to uncommit it.
3. After approval, run `git -C <repo> reset --soft HEAD~1`.
4. Run `git -C <repo> restore --staged :/` so all changes return to the worktree unstaged.
5. Re-enter Smart Commit Mode and create logical commits one group at a time.

## Commit Message Shape

Use the conventional commit format. Every commit has a title (the first line) and an optional body and footer.

### Title: The WHY (≤72 chars)

The title must answer: **what problem does this solve?** It describes the motivation, the bug being fixed, the user-facing gap being closed. It is NOT a diff summary — do not describe what files changed or what code was written.

From drlove2002/ai-config, MIT.

More from drlove2002/ai-config

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Jul 6, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from drlove2002

Cite this page

commit skill. Agent Mart. https://agentmart.dev/skills/drlove2002-commit (last updated 2026-10-24)