agentleFS
johnqtcgjohnqtcg/awesome-skills/skills/git-commit/SKILL.md

git-commit

Skill30 starsChanged 4 months agoMITView on GitHub

Safely create a git commit by validating repository state, staging intended changes, scanning for secrets/conflicts, generating a Conventional Commits message (repository convention first, else an English Angular default) from the staged diff, and committing without amend.

  • Reads credentials

174 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use git-pr, github-pr-create and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • klauswgSkill

    git-pr

    Prepare, review, publish, or update a complete GitHub pull request for the current repository, including local commit readiness, safe push strategy, semantic title validation, repository-native PR templates, issue linking, and checks verification. Use when the user asks to draft, create, submit, publish, open, or update a pull request. Always require the user to review and explicitly approve the exact final PR before any push or GitHub write.

    Also in 11 projects that use this

  • mjun0812Skill

    github-pr-create

    Pull Requestを作成するSkill。現在のbranchからpull requestを作成する。言語指定可能。 ユーザーが「PR作って」「pull request作成して」のように依頼したら使うこと。

    Also in 3 projects that use this

  • MicrosoftSkill

    git-branch

    Branch management for implementation. Use when you need to create a branch, switch branches, checkout, or verify branching strategy before implementing code. Do not use for commits (use git-commit), pull requests (use pull-request), or advanced git operations (rebase, merge).

    Also in 4 projects that use this

  • klauswgSkill

    git-issue

    Prepare, review, create, or update evidence-based GitHub issues for the current repository with duplicate detection, repository-native templates, valid labels, and post-publication verification. Use when the user asks to draft, file, submit, publish, edit, or refine a GitHub issue, bug report, feature request, performance issue, or technical proposal. Always require the user to review and explicitly approve the exact final issue before any GitHub write.

    Also in 3 projects that use this

  • gologo13Skill

    git-push

    Push current branch to origin and sync with remote updates; keywords: git, rebase. Use only on explicit request; before execution, review diffs and list impact scope.

    Also in 6 projects that use this

  • GoogleSkill

    github-pr-review

    Review a GitHub pull request and leave inline comments in a natural human reviewing voice, indistinguishable from comments typed by hand on the GitHub web UI. Deliberately bounded to defects a reader can settle by looking at the anchored line, rather than a deep audit, so every comment is cheap for the author to check. Scales to 2-20 comments by PR size, parallelises analysis across sub-agents, drafts for approval, then posts individually with human pacing. Use when the user says "review this PR", "review PR 123", pastes a github.com/.../pull/N link, or asks for comments on a pull request. Don't use for reviewing local uncommitted changes or a diff against a branch (use the `review` skill for that).

    Also in 4 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

23 rules. 0 are common, 12 are distinctive, and 11 are very specific to this project.

  • 0

    Common

    Most of the 134 edited versions we read keep these.

  • 12

    Distinctive

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Create a commit from the current working tree with safety gates first, then generate a concise Angular-style message in English.

    line 12
  2. Distinctive:

    Never commit with unresolved conflicts.

    line 18
  3. Very specific:

    Never commit secrets, credentials, keys, or .env sensitive values.

    line 19
  4. Very specific:

    Do not use --amend unless explicitly requested.

    line 21
  5. Distinctive:

    If any safety gate fails, stop and report clearly.

    line 22
  6. Distinctive:

    STOP (hard block — report which one and what to resolve) if any of these hold:

    line 43
  7. Very specific:

    If the user names exact files, stage those only with git add -- <paths> (the -- keeps a path that starts with - from being parsed as an …

    line 53
  8. Very specific:

    If the user says "commit my changes", start from git -c core.quotePath=false status --short.

    line 54
  9. Very specific:

    If <= 8 files, read the diffs and split by logical intent.

    line 56
  10. Distinctive:

    If unstaged or untracked changes remain after staging, the quality gate MUST run through the isolation wrapper (§4) so it sees exactly the …

    line 58
  11. Distinctive:

    Verify staging with git diff --cached --stat.

    line 59
  12. Very specific:

    Run git diff --cached --submodule=short.

    line 60
  13. Very specific:

    If a check fails, stop and report it.

    line 100
  14. Distinctive:

    Isolation (guaranteed restore): when unstaged or untracked changes are present, wrap the enforcer in the stash guard so those changes are …

    line 105
  15. Distinctive:

    If a convention is found, adopt its type set, language, and subject length in place of the Angular / English / 50-char defaults.

    line 116
  16. Distinctive:

    Never invent a scope from filenames or issue text.

    line 126
  17. Very specific:

    Add required trailers when repo policy or the user asks: Signed-off-by: (git commit -s), Co-authored-by:, and issue refs (Closes #123).

    line 129
  18. Very specific:

    Prefer git commit -F - for any multi-paragraph body.

    line 158
  19. Distinctive:

    If commitlint, pre-commit, husky, or lefthook rejects the commit, read the error and adapt the message.

    line 162
  20. Very specific:

    Never use --no-verify unless explicitly requested.

    line 163
  21. Very specific:

    If the file at git rev-parse --git-path SQUASH_MSG exists (worktree-safe — never read .git/ directly), warn that this may be a squash-merge …

    line 192
  22. Distinctive:

    No staged changes → stop and report.

    line 197
  23. Distinctive:

    Commit failure → report the git error and leave staging untouched.

    line 199

“Common” is measured: kept by at least 6 in 10 of the 134 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Git Commit (Safety Enhanced, Angular Convention)

Create a commit from the current working tree with safety gates first, then generate a concise Angular-style message in English.

Maintaining this skill (not needed to run it): references/design-evidence.md records the measured evidence behind every contract below and the verified environment matrix; scripts/run_cross_env_probe.sh, scripts/run_portability_matrix.sh and scripts/eval/ re-derive it.

Hard Rules

  • Never commit with unresolved conflicts.
  • Never commit secrets, credentials, keys, or .env sensitive values.
  • Subject line must fit the repo's limit — default <= 50 chars total (including type(scope): ). A commitlint/CONTRIBUTING limit discovered in §5 replaces that default; the §6 guard enforces whichever applies. There is no separate absolute 50.
  • Do not use --amend unless explicitly requested. If already pushed, warn about force push.
  • If any safety gate fails, stop and report clearly.
  • One commit = one logical change. Do not mix unrelated fixes, features, or formatting.

Workflow

Bundled scripts are always invoked as bash "<path-to-skill>/scripts/<name>.sh" — <path-to-skill> is the absolute skill directory (where this SKILL.md was loaded from), never a path relative to the repository. Keep the working directory at the target repo root; the scripts read the repo through git.

1. Preflight

git rev-parse --is-inside-work-tree                 # must print "true"
git -c core.quotePath=false status --short           # quotePath=false: see the raw path
BRANCH=$(git rev-parse --abbrev-ref HEAD)            # "HEAD" means detached (allowed)

# In-progress operation? Worktree-safe: resolve real paths, never read .git/ directly.
for state in rebase-merge rebase-apply MERGE_HEAD CHERRY_PICK_HEAD REVERT_HEAD; do
  [ -e "$(git rev-parse --git-path "$state")" ] && echo "IN_PROGRESS $state"
done

# Unresolved conflicts: this diff exits 0 regardless, so act on OUTPUT, not exit code.
git -c core.quotePath=false diff --name-only --diff-filter=U

STOP (hard block — report which one and what to resolve) if any of these hold:

  • --is-inside-work-tree did not print true;
  • any IN_PROGRESS <state> line printed (rebase / merge / cherry-pick / revert in progress);
  • the conflict diff printed any path (unresolved merge conflicts).

A detached HEAD is not a stop condition — proceed and note it in the report.

2. Staging

  • Snapshot what is already staged first: git -c core.quotePath=false diff --cached --name-only. If files are already staged that the user did not ask to commit, STOP and ask — commit them together, keep them staged for later, or split. Never silently fold pre-staged files into this commit.
  • If the user names exact files, stage those only with git add -- <paths> (the -- keeps a path that starts with - from being parsed as an option).
  • If the user says "commit my changes", start from git -c core.quotePath=false status --short. Use -c core.quotePath=false on any git command whose paths you show the user or pass back to git: the default escapes non-ASCII paths to "\346\272\220…", unreadable and not a path git add -- accepts.
  • Count changed paths. If > 8 files, list the full file set and confirm before staging — unless the user already authorized that exact set (named the files, said "commit all of these", or confirmed it earlier in this session). The prompt resolves scope ambiguity; it is not a second ask for a question already answered.
  • If <= 8 files, read the diffs and split by logical intent. If one file mixes intents, use git add -p.
  • Stage task-related untracked files only when they clearly belong to the same change.
  • If unstaged or untracked changes remain after staging, the quality gate MUST run through the isolation wrapper (§4) so it sees exactly the staged snapshot and your changes are restored on every exit path.
  • Verify staging with git diff --cached --stat. If nothing is staged, stop.
  • Run git diff --cached --submodule=short. If a submodule pointer changed, confirm it is intentional.

3. Secret/sensitive-content gate

bash "<path-to-skill>/scripts/secret-scan.sh"

Uses the repo's gitleaks when installed, and always runs a built-in regex fallback over added staged lines only — removing a secret is never blocked. Exit code: 0 = the scan completed (clean, or findings printed for triage — "no secret" is never a gate failure); 2 = it could not complete, and every stage that failed names itself. Treat 2 as a gate failure, never as clean. Output lines:

  • SECRET_CANDIDATE: <file>:<line>: <redacted> — real source line numbers, cut at the match so only its first 4 chars survive.
  • CONTEXT: <file>:<line>: <text> — 2 lines around each candidate, cut by the same rule.

A line is reported when it holds a known credential shape, or a sensitive key name followed by : or = (case-insensitive). It is cut at the earliest of those or any 20+ char token-ish run. Residual risk: a short literal not attached to a sensitive key still prints — context is a triage aid, not a sanitiser; do not paste it into a public channel.

  • ALLOWLISTED: … — matched a glob in the committed .commit-secret-allowlist (HEAD version; a staged-but-uncommitted allowlist is ignored).
  • SENSITIVE_FILE: <path> — staged filename that is key material by name (.env, id_rsa, *.pem, …).
  • SCANNER_ERROR: … — gitleaks misconfiguration or crash (script exits 2); the regex fallback still ran but is NOT equivalent coverage — fix the scanner or get explicit user sign-off.

Triage every match. Path/type never auto-dismisses a match — real keys do get committed into tests and docs. Only a committed allowlist hard-dismisses; everything else lowers confidence and is still surfaced.

#FilterEffect
1ALLOWLISTED: line (committed .commit-secret-allowlist glob)Hard-dismiss — but confirm the entry's scope/provenance; treat an unfamiliar allowlist as untrusted
2Test/fixture path (/test(s)/, /__tests__/, /spec/, /mock(s)/, /fixture(s)/, /example(s)/, /testdata/, /snapshot(s)/, or a common test suffix)Downgrade to low confidence — still report
3Documentation file (.md, .rst, .adoc, .mdx)Downgrade — still report
4Comment line (after stripping +/whitespace: //, # not #!/, --, /*, *, %, ;;, REM )Downgrade — still report

High-confidence matches are blockers; downgraded matches need a human decision (never silently dropped). Binary files and high-entropy strings are out of scope for the regex fallback — rely on gitleaks/detect-secrets for those.

4. Quality gate

Detect ecosystems — extensions and dependency-manifest markers, so staging only go.mod or package.json still selects the right gate:

bash "<path-to-skill>/scripts/detect-ecosystems.sh"   # one per line, most staged files first

Deletions count. Empty output = none; exit 2 = unknown — never treat exit 2 as "nothing to gate".

  • go → load references/quality-gate-go.md; node → references/quality-gate-node.md; python → references/quality-gate-python.md; java → references/quality-gate-java.md; rust → references/quality-gate-rust.md
  • Run the gate for EVERY detected ecosystem, largest first — a 5-Go-file + 1-TS-file stage runs both the Go and the Node gates (scope each gate to its own files where the reference allows). Never skip a minority ecosystem.
  • The marker list is not exhaustive. Detector prints nothing but the stage clearly belongs to an ecosystem (an unlisted marker such as an uncommon lockfile) → pick that gate by judgment and say so in the report; otherwise try make test / make check, else report quality gate: not detected.
  • Makefile wrappers take precedence over raw ecosystem commands.
  • If a check fails, stop and report it. The user may explicitly skip; report quality gate: skipped by user.
  • Timeout (enforced, not advisory): default 120 seconds per gate command (each invocation bounds one command). If the repo wrapper or environment sets COMMIT_TEST_TIMEOUT, QUALITY_GATE_TIMEOUT_SECONDS, or SKILL_QUALITY_GATE_TIMEOUT_SECONDS, use it and report the chosen timeout before running long tests. Exit 124 = timed out (one code on every host); exit 2 = the timeout could not be enforced, so no gate ran. Both block the commit.
    bash "<path-to-skill>/scripts/run-gate.sh" [-t <repo-wrapper-seconds>] <gate command>
  • Isolation (guaranteed restore): when unstaged or untracked changes are present, wrap the enforcer in the stash guard so those changes are stashed and restored exactly once on every exit path — gate pass, gate failure, timeout, or interrupt (SIGINT/SIGTERM exit 130/143 after restore, never 0):
    bash "<path-to-skill>/scripts/stash-guard.sh" bash "<path-to-skill>/scripts/run-gate.sh" make test
    Its exit code is the gate's. Every non-zero path preserves the stash and prints recovery instructions (git stash apply --index <OID>) — data is never lost, but a restore conflict can leave a partial worktree, so follow the instructions rather than assume a clean tree. It fails closed on both isolation edges: unstashable state (dirty submodule content) → exit 2 without running the gate; tracked-file drift while the gate ran → keeps the stash, refuses the reset.

5. Compose commit message

First discover the repo's own convention — it overrides the defaults below:

  • commitlint config (.commitlintrc*, commitlint.config.*, or a commitlint key in package.json) → follow its type-enum, case, and length rules.
  • .gitmessage template (git config --get commit.template), or commit rules in CONTRIBUTING/AGENTS.md → follow them.
  • If a convention is found, adopt its type set, language, and subject length in place of the Angular / English / 50-char defaults. If none is found, use the defaults.
  • Carry the discovered subject-length limit into the §6 guard as SUBJECT_MAX (default 50) so the executable check enforces the repo's actual limit, not a hardcoded 50.

Scope discovery — these rules are mechanical, so run them rather than re-deriving them:

bash "<path-to-skill>/scripts/resolve-scope.sh"   # SCOPE: <name>|(none) + SCOPE_SOURCE:
  • canonical — a scope used >= 3 times in the last 50 commits that matches a staged path and is not contradicted by a second canonical scope. A stage spanning two known scopes is a mixed commit: scope is omitted, never resolved to whichever is more frequent. A staged path matching no canonical scope (CHANGELOG.md) does not block.
  • bootstrap — fewer than 10 conventional commits total, so the convention is not established; the scope comes from the staged directories with generic containers (src, pkg, internal, services, tests, …) stripped, and only when one stable directory remains.
  • omitted — use <type>: <subject>. Exit 2 = the repo could not be read: omit the scope and say so.
  • Never invent a scope from filenames or issue text. If the answer looks wrong for this change, omit — do not substitute your own.
  • Format is <type>(<scope>): <subject> or <type>: <subject>; for a breaking change use <type>!: and/or a BREAKING CHANGE: <what> footer.
  • Subject must be imperative, no trailing period, and <= 50 chars (or the repo's discovered limit); body explains why and wraps at 72 chars.
  • Add required trailers when repo policy or the user asks: Signed-off-by: (git commit -s), Co-authored-by:, and issue refs (Closes #123).

6. Commit

Single-line commit:

SUBJECT='<type>(<scope>): <subject>'
SUBJECT_MAX=${SUBJECT_MAX:-50}   # 50 default; set from the repo convention (§5)
[ ${#SUBJECT} -le "$SUBJECT_MAX" ] || { echo "subject too long (${#SUBJECT}/$SUBJECT_MAX)"; exit 1; }
case "$SUBJECT" in *.) echo "subject must not end with ."; exit 1 ;; esac
git commit -m "$SUBJECT"

Multi-line commit — the heredoc is the single source; the guard checks the exact first line that will be committed (no separate SUBJECT variable to drift):

SUBJECT_MAX=${SUBJECT_MAX:-50}   # 50 default; set from the repo convention (§5)
MSG=$(cat <<'EOF'
<type>(<scope>): <subject>

<body — explain why, wrap at 72 chars>

<footer>
EOF
)
SUBJECT=${MSG%%$'\n'*}
[ ${#SUBJECT} -le "$SUBJECT_MAX" ] || { echo "subject too long (${#SUBJECT}/$SUBJECT_MAX)"; exit 1; }
case "$SUBJECT" in *.) echo "subject must not end with ."; exit 1 ;; esac
printf '%s\n' "$MSG" | git commit -F -

Prefer git commit -F - for any multi-paragraph body. Multiple -m flags do work — each becomes its own paragraph — but give no control over 72-char wrapping within a paragraph and are quoting-fragile for footers, so -F - is the reliable choice.

Hook awareness:

  • If commitlint, pre-commit, husky, or lefthook rejects the commit, read the error and adapt the message.
  • Never use --no-verify unless explicitly requested.
  • Report the hook name and the adjustment made.

7. Post-commit report

git rev-parse --short HEAD
git show -s --format='%h %s' HEAD          # hash + subject
git -c core.quotePath=false show --name-status --format= HEAD   # changed files (NOT --no-patch: it disables --name-status)

Report the hash, final subject, changed files summary, and quality gate status.

Message Examples

  • fix(account): guard nil balance map before merge
  • refactor(service): simplify aggregation flow
  • test: add case for tail-mapping loss
fix(auth): prevent token refresh race condition

Two concurrent requests could both trigger a refresh, causing one to
use an invalidated token. Add mutex to serialize refresh calls.

Closes #245

Edge Cases

  • --allow-empty: only if the user explicitly requests it. Note it in the post-commit report.
  • If the file at git rev-parse --git-path SQUASH_MSG exists (worktree-safe — never read .git/ directly), warn that this may be a squash-merge residual state.
  • Submodule pointer changes are never auto-assumed safe.

Failure Handling

  • No staged changes → stop and report.
  • Safety gate failure → stop and report the exact blocker.
  • Commit failure → report the git error and leave staging untouched.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.