| name | commit |
| description | Guided commit on explicit request /commit — breaks changes into atomic commits ordered by layer, passes two validations (file selection, then message), handles branch (creation/switch with stash), then executes git add + git commit. Use whenever the user says /commit, 'commit that', 'make the commit', or wants to commit finished work. Never push, merge, rebase or reset EVER. Never commit outside this skill. |
| allowed-tools | Bash(git add *) Bash(git commit *) Bash(git status *) Bash(git diff *) Bash(git log *) Bash(git branch *) Bash(git switch *) Bash(git checkout *) Bash(git stash *) Bash(git rev-parse *) |
/commit — guided commit
This skill executes commits on behalf of {USER_NAME}, which is an exception to his rule "only {USER_NAME} is master of Git". This exception only holds because two explicit validations frame each commit: {USER_NAME} keeps control over what is committed and with what message. If either of the two validations does not take place, the commit does not happen. This is the whole point of the skill — losing these guardrails would mean committing blindly.
Invariants (non-negotiable)
These rules exist because the commands below are destructive or outgoing, and {USER_NAME} wants to remain sole master of them:
- 🚫 Never
git push, git merge, git rebase, git reset. If one is necessary, suggest it to {USER_NAME}, do not execute it.
- 🚫 Never commit without the two validations (files + message).
- 🚫 Never commit outside this skill (no commit "in passing" in another task).
- ✅
git add, git commit, git switch, git checkout -b, git stash are allowed — but only in the flow below.
reset is deliberately excluded: to commit only part of the changes, stage selectively (git add <files> or git add -p) instead of staging everything then deselecting. So we never globally unstage.
Step 0 — Verify we are in a repo
git rev-parse --is-inside-work-tree
If the command fails (outside a git repo), stop immediately with a clear message ("Not in a git repo — nothing to commit"). Emit no mutant git commands.
Step 1 — Branch correctly (branch gate)
{USER_NAME} often forgets to leave main before working. The role of this step is to catch this case before the commit, not to manage branching exhaustively.
git branch --show-current
git status --short
- If the current branch is a main branch (
main, master, develop): flag the risk and propose a feature branch whose name is deduced from the diff / conversation (e.g., feat/tag-management). Request validation from {USER_NAME} (gate — do nothing without his agreement).
- If already on a feature branch: continue without proposing anything.
When {USER_NAME} validates a switch, handling of uncommitted changes depends on the case:
| Case | Command | Why |
|---|
| Create a new branch from the current one | git switch -c <name> | Uncommitted changes automatically follow — no need for stash. |
| Switch to an existing branch with a dirty working tree | git stash → git switch <name> → git stash pop | switch would refuse (or overwrite) otherwise. The stash carries changes to the target. |
After a stash pop, check git status: if pop conflicts occur, stop and flag it to {USER_NAME} (do not try to resolve blindly).
Step 2 — Break into atomic commits (gate 1: files)
Present the complete state before any decision:
git status --short
git diff # unstaged changes
git diff --staged # already staged, if any
Propose an atomic commit breakdown — one commit = one coherent logical change. Order by dependency layer, so a review reads from bottom to top:
Docs → DB migrations → Core/domain → Services → Presentation/UI → Tests
When the same file carries two distinct concerns, split it with git add -p.
Special cases to address in the proposal (do not commit silently):
- Files that should not be versioned (
.env, secrets, node_modules/, __pycache__/, .DS_Store, build artifacts, logs) → propose adding them to .gitignore and committing .gitignore first. Do not include them in a commit.
.claude/ files → these are project files, commit them normally.
- Artifacts regenerated by a git hook (post-checkout/post-commit) and versioned — typically
graphify-out/ (graph.json, GRAPH_REPORT.md, graph.html): if the repo versions them, do not mix them into the logical change. Propose a separate commit chore(graphify): refresh knowledge-graph (or equivalent scope). If they are not versioned → ignore them (do not commit). Flag that the diff may be noise from non-deterministic regeneration (Leiden community relabeling) rather than a consequence of the code — it's up to {USER_NAME} to decide commit vs git restore.
Present the proposed breakdown (which files in which commit, in which order) and wait for {USER_NAME}'s validation (gate 1). He may reorder, merge, exclude files.
Step 3 — Write each commit message (gate 2)
The message follows Angular convention, in a single line:
- structure:
type(scope): subject
- types:
feat · fix · refactor · test · docs · chore · perf · build · ci
- Never multi-line body, never bullets
fixed by XXXX in the subject when the commit fixes another's ticket
- never
Co-Authored-By trailer (useless noise — {USER_NAME}'s decision)
Deduce the type from the commit content and scope from the local convention in the repo:
git log --oneline -20
(Spot the dominant scope in history — e.g., payments in a given repo — to stay consistent.)
Example 1
Changes: adding JWT authentication on the service side
→ feat(auth): add JWT-based authentication
Example 2
Changes: fixing a margin calculation, ticket opened by a colleague
→ fix(billing): correct margin rounding fixed by TMAFR-1189
Propose the message for each commit and wait for {USER_NAME}'s validation (gate 2). For multiple atomic commits, present the full list of messages at once so he validates the whole set.
Step 4 — Execute
Once both gates are passed, for each commit from the breakdown, in order:
git add <files for this commit> # or git add -p for intra-file breakdown
git commit -m "<validated message>"
Stage just before committing each group (no global staging upfront) — that keeps file-by-file control without ever needing reset.
Step 5 — Confirm
git log --oneline -<n> # n = number of commits created
git status # must be clean (or show only files intentionally left out)
Display the created commits. If {USER_NAME} intentionally left changes out of a commit, remind him. Do not propose pushing — that's his decision, out of scope.