Creates meaningful git commits by analyzing changes and committing in logical units. Use when the user wants to commit changes to git, requests commit creation, or asks to save changes to version control. Supports --english and --japanese for commit language selection and --branch to create a new branch before committing.
Resources
1Install
npx skillscat add shuymn/dotfiles/commit Install via the SkillsCat registry.
Path Resolution
<skill-root>means the directory containing thisSKILL.md.- Resolve
scripts/...andreferences/...relative to<skill-root>, not the caller's current working directory. - When executing local helpers, use explicit paths such as
<skill-root>/scripts/....
Commit in Meaningful Units
Not in Scope
git push— this skill creates local commits only.- Creating pull requests — use the
create-prskill. - Merging or rebasing branches.
Invocation Guard
This skill runs only via /commit. Never create commits automatically or as part of another task.
Core Principle: One Logical Change Per Commit
Every commit represents exactly one meaningful unit of change. Bundling unrelated changes makes reverts dangerous (reverting one fix undoes an unrelated feature), makes code review noisy, and makes git bisect useless. A meaningful unit:
- Has one clear purpose
- Can be reverted independently without breaking other functionality
- Can be described with a single, specific commit message (no "and")
For examples of good/bad groupings and common scenarios, see examples.md.
Context
- Status: !
git status --short - Branch: !
git branch --show-current - Recent: !
git log --oneline -10 - Unstaged: !
git diff --stat - Staged: !
git diff --cached --stat
Always verify actual git state with live commands — cached snapshots from skill context may be stale.
Language Support
--english: Creates commit messages with English types and English descriptions:
- Format:
<type>(<scope>): <english description>or<type>: <english description> - Examples:
feat(auth): add OAuth2 loginfix(api): handle null user responsesfeat: harden MySQL and CLI input validation
- Use imperative mood, keep under 50 chars, start subject with lowercase
--japanese: Creates commit messages with English types and optional scope plus Japanese descriptions:
- Format:
<type>(<scope>): <日本語の説明>or<type>: <日本語の説明> - Examples:
feat(auth): OAuth2ログインを追加fix(api): ユーザーエンドポイントのnull処理を修正feat: MySQLとCLIの入力検証を強化
- Use である調, keep under 50 chars, use カタカナ for tech terms
Default when neither --english nor --japanese is set:
- Inspect recent commit subjects first, for example:
git log --format='%s' -10 - Match the dominant recent description language in this repository
- If recent commits do not show a clear language preference, ask the user before committing
Branch Support
--branch: Creates a new branch before committing:
- When
--branchis specified, branch creation is mandatory — skipping it defeats the purpose of the flag - Branch name is automatically determined from the primary change in the diff
- Creates branch using
git switch -c <branch-name> - Branch names use descriptive names without abbreviations
- Default base: current branch
- Use
--base=<branch>to specify a different base branch - Examples:
/commit --branch→ Auto-generates name likefeature/add-oauth-support/commit --branch --base=main→ Create from main branch/commit --branch --base=develop→ Create from develop branch
Commit Format
Types:
feat: New featurefix: Bug fixdocs: Documentationstyle: Code stylerefactor: Refactoringperf: Performancetest: Testschore: Maintenancebuild: Build systemci: CI changes
Rules:
- Max 50 characters for subject line
- Imperative mood (English) / である調 (Japanese)
- Start English subject with lowercase (e.g.,
fix bug, notFix bug) - No period at end
- Allowed formats:
type(scope): subjectandtype: subject scopeis optional, but when present it must name exactly one area- Never use multiple scopes such as
feat(mysql,cli,testkit): ... - If a change appears to need multiple scopes, first try splitting it into separate commits
- If splitting would break one logical change, omit scope and use
type: subject
Process
Standard Process
- Analyze first:
git diff— identify every logical unit before making any commits- Group changes by their purpose and plan separate commits for each unit
- If changes are mixed, split them before proceeding
- If the message seems to need multiple scopes, treat that as a signal to split commits first
- If uncertain about grouping: use AskUserQuestionTool
- Check state:
git status - Choose commit language:
--english: use English descriptions--japanese: use Japanese descriptions- No language flag: inspect recent commit subjects and follow the dominant recent language
- If recent commit language is mixed or unclear: ask the user before committing
- For EACH logical unit separately:
- Stage ONLY related files:
- For whole-file commits:
git add <specific-files> - For partial staging within a file: follow Patch-Based Partial Staging
- For whole-file commits:
- Verify staged changes:
git diff --cached— ensure only one logical change is staged - If staging is wrong: stop and ask user before proceeding (see Prohibited Commands)
- Commit:
git commit -m "<type>(<scope>): description"orgit commit -m "<type>: description" - Confirm:
git log --oneline -1
- Stage ONLY related files:
- Repeat for next logical unit until all changes are committed
With --branch Option
- Analyze first:
git diff— identify every logical unit and determine primary change - Check state:
git status - Choose commit language:
--english: use English descriptions--japanese: use Japanese descriptions- No language flag: inspect recent commit subjects and follow the dominant recent language
- If recent commit language is mixed or unclear: ask the user before committing
- Determine branch name: Analyze diff to generate descriptive branch name based on primary change
- Format:
<type>/<descriptive-name> - Examples:
feature/add-oauth-support,fix/handle-null-values,refactor/extract-validation
- Format:
- Switch to base branch (if
--basespecified):git switch <base-branch> - Create branch:
git switch -c <branch-name> - For EACH logical unit separately:
- Stage ONLY related files:
- For whole-file commits:
git add <specific-files> - For partial staging within a file: follow Patch-Based Partial Staging
- For whole-file commits:
- Verify staged changes:
git diff --cached— ensure only one logical change is staged - If staging is wrong: stop and ask user before proceeding (see Prohibited Commands)
- Commit:
git commit -m "<type>(<scope>): description"orgit commit -m "<type>: description" - Confirm:
git log --oneline -1
- Stage ONLY related files:
- Repeat for next logical unit until all changes are committed
Patch-Based Partial Staging
When a file contains multiple logical changes, use the patch-based approach. See examples.md for the full procedure.
Prohibited Commands During Partial Commit Preparation
To prevent accidental data loss, the following are NOT allowed while splitting changes into logical commits:
- Any
git restore ...command - Any
git reset ...command - Any
git checkout -- ...command (orgit checkout -f) - Any
git switch --discard-changes ...command - Any
git clean ...command (e.g.git clean -fd,git clean -fdx)
If these commands seem necessary, pause and ask the user for explicit direction instead of executing them.
Identifying Meaningful Units
Ask These Questions:
- Can this change stand alone? If reverted, would the codebase still make sense?
- Does it have a single purpose? Can you describe it in one sentence without "and"?
- Are all parts necessary for each other? Would removing any part break the change?
- Would a future developer understand it? Is the change's scope immediately clear?
Scope Decision Order
- If the change spans multiple areas, try to split it into separate logical commits first.
- If it still forms one inseparable logical change, use
type: subject. - Use
type(scope): subjectonly when the logical unit is clearly centered on one area.
When Uncertain About Grouping
When uncertain about grouping, present the changes and options to the user. Include: (1) which grouping options are under consideration, (2) how the decision affects commit count and independent revertibility. If AskUserQuestionTool is available, use it; if multiple independent grouping decisions are needed, batch them into the questions array. If AskUserQuestionTool is unavailable, ask in a single message using QID labels (Q1, Q2, ...); require QID: <answer> responses and allow QID: OTHER(<concise detail>) when no option fits. See examples.md for an example prompt.
Common Scenarios
For scenarios requiring separate commits (refactoring + feature, bug fix + test, etc.), see examples.md.
Character Count
# Check length
echo -n "feat: harden CLI input validation" | wc -cHandling @ Symbols
When commit messages contain @ symbols:
- Wrap code/paths in backticks to prevent GitHub mentions:
@importorpath/@file - This prevents unintended user notifications
Hook Errors
If commit-msg hook fails:
- Read error carefully
- Show full error to user
- Ask how to proceed
- Don't bypass hooks
Signing Errors (1Password/GPG/SSH)
If commit signing fails (for example with 1Password or other signing agents):
- Read and show the exact error to the user
- STOP the commit workflow and ask the user how to proceed
- Do NOT modify git signing config to force commit success
- Do NOT run
git configchanges for signing bypass (e.g.git config commit.gpgsign false,git config --global commit.gpgsign false) - Do NOT run bypass options such as
--no-gpg-signor-c commit.gpgsign=false - Wait for user instruction after reporting the failure
Anti-Patterns
Red flags that indicate multiple logical changes are bundled:
- Commit message contains "and" (except in detailed descriptions)
- Using vague messages like "various fixes" or "multiple improvements"
- Using comma-separated scopes like
feat(mysql,cli,testkit): ...instead of splitting commits or omitting scope - Staging all changed files without reviewing each one
- Making a "cleanup" commit that includes functional changes
- Bundling a hotfix with a feature because "it's just one line"
Final Reminders
- When in doubt, make separate commits — you can always squash later
- For Japanese commits, ensure UTF-8 support in your environment