Commit Skill
Create conventional commits with branch protection, semantic correlation, and user confirmation.
When to Use
-
After completing a task or logical unit of work
-
When the user requests a commit
-
After significant documentation updates
-
After implementing a feature or fix
-
When the user says they're "done", "finished editing", or wants to "wrap up"
Procedure
Step 1: Gather Changes
git status git diff --stat git diff --cached --stat
If there are no changes (nothing staged, modified, or untracked), inform the user and stop.
Step 2: Branch Safety Check (mandatory)
Detect the current branch and the default branch:
git symbolic-ref --short HEAD git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null || echo ""
If refs/remotes/origin/HEAD is not set, check whether main or master exists as fallback.
If on the default branch:
-
Warn the user: "You're committing directly to <default-branch> . Consider creating a feature branch."
-
Run Step 3 (Ticket Tracking) to check for an associated ticket before proposing a branch.
-
Detect the repo's branch naming convention by inspecting existing branches: git branch -a --format='%(refname:short)'
-
Analyze naming patterns:
-
Separator style: / vs - vs _
-
Type prefixes: feat , fix , chore , docs , etc.
-
Nested patterns: user/type/desc , type/desc
-
Issue ID patterns: PROJ-123-desc
-
Default to type/short-description if no clear pattern found
-
Propose a new branch name following the detected convention. If a ticket was found/created in Step 3, incorporate the ticket ID into the branch name (e.g., feat/PROJ-123-add-auth ).
-
Ask user to: confirm the proposed name, suggest an alternative, or continue on the default branch
If the user chooses to create a branch, run:
git checkout -b <branch-name>
Step 3: Ticket Tracking (when on default branch or no ticket in branch name)
Detect whether the project uses a ticket tracking system and ensure changes are associated with a ticket.
Detection — check for ticket system indicators (in order):
GitHub/GitLab Issues — Check if remote is GitHub/GitLab:
git remote get-url origin
If GitHub: use gh issue list --limit 5 --state open to confirm issues are enabled. If GitLab: note that GitLab issues are likely available.
Jira — Look for Jira-style ticket IDs in existing branch names ([A-Z]+-\d+ pattern like PROJ-123 ). Check for .jira config or Jira URL references in the repo.
Linear — Check for Linear-style IDs in branches ([A-Z]+-\d+ with short prefixes like ENG-123 ). Check for linear references in the repo.
No ticket system detected — Skip this step entirely and proceed.
If a ticket system is detected:
-
Check if the current changes are already associated with a ticket:
-
Parse the current branch name for a ticket ID
-
If on default branch, there is no ticket association
-
If no ticket is associated, analyze the changes (from Step 1) to understand their nature, then:
-
Warn: "This project uses [system] for tracking. No ticket is associated with these changes."
-
Propose creating a ticket first:
-
Draft a ticket title and description based on the changes
-
For GitHub: offer to run gh issue create --title "..." --body "..."
-
For other systems: show the suggested title/description and ask user to create it manually
-
Ask user to: create the ticket, provide an existing ticket ID, or skip (commit without ticket)
-
If user provides or creates a ticket, use the ticket ID when constructing the branch name in Step 2.
Step 4: Semantic Correlation (feature branches only)
Only when on a feature branch (not the default branch):
-
Parse the branch name into tokens (split on / , - , _ )
-
Compare tokens against the nature of the changes (file paths, change type, scope)
-
If there is zero semantic overlap between branch name and changes, warn:
"Changes appear to be about X, but branch branch-name suggests Y. Continue?"
- Wait for user confirmation before proceeding
Step 5: Analyze Changes
Identify:
-
Files modified, added, or deleted
-
Type of change (feat , fix , docs , refactor , style , test , chore )
-
Scope (which module/area affected)
-
Breaking changes (if any)
Step 6: Draft Commit Message
Use conventional commits format:
<type>(<scope>): <short description>
<body with details>
<footer>
Types:
-
feat : New feature
-
fix : Bug fix
-
docs : Documentation only
-
refactor : Code change that neither fixes a bug nor adds a feature
-
style : Formatting, missing semicolons, etc.
-
test : Adding or updating tests
-
chore : Maintenance tasks, dependencies
If a ticket was associated in Step 3, include it in the footer (e.g., Closes #123 or Refs: PROJ-123 ).
Step 7: Show Diff and Confirm
Before committing, ALWAYS:
- Show the staged diff (or unstaged diff if nothing is staged yet):
git diff --staged
Show the proposed commit message
Ask: "Ready to commit these changes? (yes/no)"
Wait for explicit user approval
Step 8: Execute Commit (only after approval)
Stage files — prefer specific files over git add -A :
git add <specific-files> git commit -m "<message>"
Step 9: Verify
git log -1 --stat
Rules
-
NEVER push — Only commit locally, never run git push
-
ALWAYS confirm — Never commit without explicit user approval
-
Show diff first — User must see changes before approving
-
One logical unit — Each commit should represent one complete change
-
Conventional format — Always use type(scope): description format
-
Branch safety — Always check if on default branch before committing
-
Ticket alignment — If project has ticket tracking, ensure changes are associated with a ticket
-
Semantic alignment — Warn if changes don't match branch purpose
-
Proactive suggestion — After completing edits, suggest committing
Output Format
Proposed Commit
Branch: feat/add-auth Type: feat Scope: auth Files:
- src/auth/reset.ts (new)
- src/components/ResetForm.tsx (new)
- src/api/routes.ts (modified)
Message: feat(auth): add password reset flow
- Add forgot password endpoint
- Implement email verification token
- Add password reset form component
Closes #123
Diff summary: 3 files changed, 245 insertions(+)
Ready to commit these changes?