commit skill
저장소 컨벤션을 추론하고, 논리적 변경 사항을 분할하며, 민감한 데이터를 스크리닝하여 변경 사항을 스테이징하고 커밋합니다.
- GitHub 스타
- 5
- 파일
- 1
- 마지막 커밋
- 2026년 11월 8일
- 라이선스
- MIT
- 허용된 도구
- 10
commit skill은 무엇을 하나요?
commit은(는) agent skill입니다. 저장소 컨벤션을 추론하고, 논리적 변경 사항을 분할하며, 민감한 데이터를 스크리닝하여 변경 사항을 스테이징하고 커밋합니다.
skill의 SKILL.md에서 생성된 요약입니다.
commit skill 정보
고품질의 git history를 유지하려는 개발자는 이 SKILL을 사용하여 스테이징 및 커밋 프로세스를 자동화할 수 있습니다. 이 도구는 일반적인 스타일을 적용하는 대신, 기존 git log와 저장소 구조를 분석하여 Conventional Commits, 특정 scope 또는 고유한 trailer와 같은 프로젝트별 컨벤션을 그대로 따릅니다. 또한 워킹 트리를 분할하여 모든 커밋이 단일 논리적 변경 사항을 나타내도록 보장하며, 관련 없는 버그 수정과 리팩토링이 섞이는 흔한 실수를 방지합니다.
안전성은 워크플로우의 핵심 요소입니다. 이 SKILL은 main이나 production과 같은 보호된 브랜치에서의 커밋을 거부하고, 자격 증명, 환경 파일 또는 대규모 데이터 덤프와 같은 민감한 데이터를 스크리닝하는 가드레일 역할을 합니다. git add -A 또는 --no-verify와 같은 위험한 명령어를 피하고, 정밀도를 높이기 위해 파일 이름을 지정하여 스테이징하는 방식을 선택합니다. 메시지를 작성할 때는 단순히 diff를 설명하는 것이 아니라 변경 사항의 근거를 설명하는 데 집중하여, 향후 개발자를 위한 지속 가능한 기록을 생성합니다.
agent가 수행할 수 있는 작업
- 1논리적 변경 사항 기록에이전트가 복잡한 워킹 트리를 각 변경 목적에 따라 별도의 깨끗한 커밋으로 분할할 수 있습니다.
- 2저장소 컨벤션 강제 적용프로젝트 history에서 발견된 기존 커밋 형식, scope 및 trailer를 자동으로 채택합니다.
- 3자격 증명 유출 방지API key 또는 .env 파일과 같은 민감한 파일의 스테이징을 식별하고 차단합니다.
- 4공용 브랜치 보호사용자가 master 또는 develop과 같은 보호된 브랜치에 있는 경우 커밋 시도를 중단합니다.
skill의 SKILL.md를 기반으로 작성되었습니다. 모든 사용 사례는 해당 문서의 인용구와 대조 확인되었습니다.
commit skill 설치 방법
각 명령은 skill 폴더를 클라이언트의 skills 디렉터리에 복사합니다. 클라이언트를 재시작하거나 새 세션을 시작하여 로드하세요.플러그인에 commit skill 설치
/plugin marketplace add pappcorn/universe /plugin install best-practices-git@pappcorn-plugins
Claude Code에 commit skill 설치
~/.claude/skills/commit/SKILL.md
$ npx degit pappcorn/universe/packages/best-practices-git/skills/commit ~/.claude/skills/commitClaude Code (project)에 commit skill 설치
.claude/skills/commit/SKILL.md
$ npx degit pappcorn/universe/packages/best-practices-git/skills/commit .claude/skills/commitCodex에 commit skill 설치
~/.agents/skills/commit/SKILL.md
$ npx degit pappcorn/universe/packages/best-practices-git/skills/commit ~/.agents/skills/commitGemini CLI에 commit skill 설치
~/.gemini/skills/commit/SKILL.md
$ npx degit pappcorn/universe/packages/best-practices-git/skills/commit ~/.gemini/skills/commitClaude.ai에 commit skill 설치
npx degit pappcorn/universe/packages/best-practices-git/skills/commit commit && zip -r commit.zip commit # claude.ai → Customize → Skills → + → Create skill → Upload a skill → commit.zip
SKILL.md
GitHub에서 보기/commit — record a change the way this repo records changes
Optional argument: $ARGUMENTS — treat it as a scope hint or a partial subject
the user wants in the message.
Why this skill exists
A commit is not a save button. It is the only durable explanation of a change
that travels with the code — the thing someone reads at 2am, six months from
now, when git blame lands on a line nobody understands and the ticket system
that held the context has since been replaced.
Two failures cause most of the pain, and both are avoidable in the thirty
seconds before you type git commit:
- The message narrates the diff. "update user service" tells you nothing the diff does not already say better. The diff is a perfect record of what changed and a useless record of why. Only the message can carry the why, and only the author knows it — for about a day.
- The commit mixes unrelated changes. A commit that fixes a bug and renames a variable and bumps a dependency cannot be reverted, cherry-picked, or bisected. The moment you need any of those, you need them urgently.
Everything below serves those two points.
Live state
Current branch:
!git branch --show-current
Working tree:
git status --short
Unstaged:
git diff --stat
Already staged:
git diff --cached --stat
This repo's actual convention — the style oracle. Match it, do not override it:
git log --oneline -20
Full recent messages (do bodies exist? do trailers exist? what do they look like?):
git log -4 --format='%s%n%n%b%n---'
Top-level layout (candidate scopes, if this repo uses scopes):
ls -1
Step 1 — Branch guard
If the current branch is protected — main, master, develop, release,
production, prod, or anything listed under protectedBranches in
.claude/best-practices-git.json — stop. Do not commit.
Protected branches are shared history. A commit landed straight on one skips review and skips CI, and if it turns out to be wrong, the fix is a public revert rather than a closed pull request nobody had to see.
Offer to create a branch instead and carry the work over — git switch -c <type>/<slug> is non-destructive and brings uncommitted changes with it. Suggest
a name from the repo's existing branch convention (git branch -a shows it); if
there is none, <type>/<short-slug> matching the commit type you are about to
use. Wait for the user before continuing.
Step 2 — Learn the repo's conventions before writing anything
Read the two git log blocks above and answer these, in your head, for this
repo:
- Format. Conventional Commits (
feat:,fix(scope):)? Bare imperative subjects? A ticket prefix (PROJ-123: …)? Sentence case or lower case? - Scopes. If the repo uses them, what is the vocabulary? Derive it from the history and the top-level layout, not from your assumptions about how monorepos are usually organized. If existing subjects have no scopes, do not introduce them.
- Granularity. One tight commit per change, or several small logical ones?
Stage to match (
git add -pwhen the repo favors small commits). - Bodies. Do messages carry a body? How long? Do they reference issues?
- Trailers. Does every commit end with something (
Co-Authored-By:,Signed-off-by:, a ticket link)? Reproduce exactly what is already there.
A repo's conventions beat this skill's preferences, always. Consistency is worth
more than any individual style rule — the history is only searchable if it is
uniform. If .claude/best-practices-git.json sets commit.convention,
commit.scopes, commit.trailers, or language, those settings win over your
inference; they exist for the case where the team is deliberately changing style.
Step 3 — Partition: one commit, one logical change
Group every changed path (staged and unstaged) by what it is for, not by where it lives. Then check:
- Does this changeset contain more than one reason to change? A bug fix plus an unrelated refactor is two commits. A feature plus a formatting sweep is two commits — and the formatting sweep is the one that will bury the feature in review.
- Does it cross a boundary the repo treats as separate (independent packages in a monorepo, unrelated services, vendored code)? If the history shows one scope per commit, keep it that way.
If the working tree holds more than one logical change, show the user the partition and propose an order. Do not silently commit them together, and do not split without telling them — a split changes what lands on the branch.
Step 4 — Safety screen
Look at the file list before staging. Refuse to stage, unless the user explicitly insists after you have named the file:
.env,.env.*,*.envcredentials*,service-account*,*-key.json,*.pem,*.key,id_rsa*,*.p12,*.gpg- Anything whose name or content looks like a token, an API key, or a connection string with a password in it
- Data dumps the user did not mention by name — CSV exports, scrapes,
*.sqlite,*.db,dump.*,backup.* - Binaries over ~1 MB that were not part of the conversation
- Build output and dependency directories (
dist/,build/,node_modules/) — if these show up ingit status, the.gitignoreis wrong; say so.
Say plainly why. "A pushed credential is a leaked credential — rotating it is the only fix, and it stays in the history of every fork and every clone forever" is the whole argument, and it is worth making once rather than arguing about the file.
Step 5 — Stage by name
git add path/one path/two
Never git add -A, git add ., or git add -u. Those stage whatever happens to
be in the tree — including the file another agent wrote thirty seconds ago in a
parallel session, the debug print you meant to delete, and the local config you
never intended to share. Naming the files is the last checkpoint where a human
decision is still possible.
Confirm with git status --short after staging, then read the staged diff itself:
git diff --cached
You are looking for what you did not mean to include: leftover console.log,
commented-out code, a stray whitespace reflow. Fix those now — after the commit
they cost a second commit.
Step 6 — Write the message
<subject — imperative, one line, fits in ~70 characters>
<body — only when the subject cannot carry the meaning>
<trailers the repo already uses>
Subject. Imperative mood: "add", not "added" or "adds" — a commit describes what applying it does. No trailing period. Concrete over categorical: "reject uploads over 10 MB" beats "improve upload validation". Use the format Step 2 inferred.
Body — this is the part that matters. Write one only when there is a why worth keeping, and then write the why, not the what:
- the constraint that forced this shape ("the vendor API rate-limits at 5 rps, so the pool is fixed at 4")
- the incident behind it ("this silently dropped every message with an emoji in the subject")
- the option not taken, and why ("a cache would be faster but goes stale on rename, which is the case that actually breaks users")
- the consequence a future reader would otherwise trip over ("callers must now await this — the sync path was the only reason the tests passed")
Do not restate the diff in prose. If the body reads like a changelog of the files, delete it — you have written the one thing the reader can already see.
Wrap the body at ~72 characters. If $ARGUMENTS was given, work it into the
subject naturally rather than pasting it.
Step 7 — Commit
Use a heredoc so newlines and trailers survive intact:
git commit -m "$(cat <<'EOF'
<subject>
<body>
<trailers>
EOF
)"
Hard rules:
- Never
--no-verify. Hooks are the team's agreement with itself. A hook you skipped runs in CI anyway, ten minutes later, in front of everyone. - Never
--amendunless the user asked for an amend in this turn. Amending rewrites a commit that may already be pushed and may already be someone else's base. - Never
commit -a. It stages by side effect and defeats Step 5.
Step 8 — When a hook fails
The commit did not happen. This matters: --amend at this point would
rewrite the previous commit — someone else's work — and that is the single most
common way this goes badly wrong.
- Read the hook output and fix the underlying problem in the code.
- Re-stage the fixed files by name.
- Make a new commit with the same message.
If the hook keeps failing for a reason unrelated to the diff (a missing tool, a broken environment), surface that to the user. Do not disable the hook.
Step 9 — Report
Four lines at most: the commit hash and subject; the branch; anything you left out (out-of-scope files, refused files); one next step if it is obvious. Do not re-summarize the diff — the user just watched you stage it.
Hard rules, in one place
- Never commit on a protected branch.
- Never
git add -A/./-u. Stage by name. - Never
--no-verify, never--amendunasked, nevercommit -a. - Never commit a credential, an
.env, or a data dump. Naming it and asking is not optional politeness — it is the last line of defense. - Never invent a convention the repo does not have.
이 스킬의 파일
1commit skill 질문
Claude Code에 commit skill을 어떻게 설치하나요?
npx degit pappcorn/universe/packages/best-practices-git/skills/commit ~/.claude/skills/commit를 실행합니다. Claude Code는 ~/.claude/skills(모든 프로젝트) 또는 .claude/skills(한 프로젝트)에서 skills를 로드하며, 설명이 작업과 일치할 때 skill을 사용합니다.
commit skill을 사용할 수 있는 클라이언트는 무엇인가요?
Agent Skills 형식을 읽는 모든 클라이언트(Claude Code, Codex, Gemini CLI, claude.ai(ZIP으로 업로드))가 사용할 수 있습니다. skill 내 스크립트는 클라이언트가 코드 실행을 허용하는 경우에만 실행됩니다.
커밋 메시지 형식을 어떻게 결정하나요?
저장소의 git history를 읽어 Conventional Commits, scope, trailer와 같은 기존 컨벤션을 추론합니다.