Skip to main content

git-commit

git差分を分析し、フォーマットに従ったコミットを自動作成する。

Quellinformationen

Repository
kasiopeiya/claude-dev-template
Letzte Quellaktivität
13. Oktober 2026 um 06:24
Erkannte Sprache von SKILL.md
Japanisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
git-commit
description
git差分を分析し、フォーマットに従ったコミットを自動作成する。
# Git Commit Helper git の変更内容を分析し、適切なコミットメッセージを生成し、自律的にコミットを実行するスキルです。サブエージェントを使わず、このスキル内で完結して処理します。 - 対象範囲はデフォルトでワーキングツリー・staged 双方の全差分。引数 `work`(ワーキングツリーのみ)/`stage`(stagedのみ)で範囲を限定できる - そのセッションで編集したかどうかは問わず、リポジトリの現在の git 状態にある差分ファイルすべてが対象。ただし並行する別セッションを検出したときは、このセッションで編集したファイルだけに絞る(Phase 1) - ブランチは確認しない。main ブランチでも確認なしでコミットしてよい - コミット実行前のユーザー承認は求めない。コミット分割は Phase 2.5 の機械的な規則(type×ディレクトリ)だけで決め、その規則で1通りに定まらないときだけ `AskUserQuestion` で確認する - `git rebase` は使用しない(マージには **3-way merge** または **fast-forward** を使う)。履歴の書き換えがバグ特定を困難にするためである ## コミットのルール commit・branch 操作をする前に従うルール。 ### コミットの書き方 コミットメッセージには変更の**理由・背景**を書く。 「何を変えたか」はコードを読めばわかる。「なぜ変えたか」はコードからは読み取れない。その情報をメッセージに残す。 ``` # Bad: 何をしたかしか書かれていない パスワードバリデーションを追加 # Good: なぜ必要だったかが書かれている パスワードバリデーションを追加 短いパスワードによる不正アクセスのリスクを下げるため、 8文字以上を必須とするバリデーションを実装した。 ``` ### issue対応時のコミットメッセージ コミットは、**件名の末尾に `(#issue番号)` を付与する**。 形式は `type: 説明 (#issue番号)` とする。 ``` # Bad: どのissue対応か追跡できない fix: ログイン失敗時のエラーメッセージを修正 # Good: 件名にissue番号があり、対応関係を追跡できる fix: ログイン失敗時のエラーメッセージを修正 (#42) ``` issue番号を記録するのは、コミットとissue(背景・議論・受け入れ条件)を双方向に辿れるようにするためである。 なお、`Closes #42` のようなクローズ用キーワードは、**コミットメッセージ**の件名・本文に書かない。本プロジェクトの開発フローではissueのタスク一覧(チェックリスト)を1つずつ進める運用であり、コミット単位でissueを自動クローズすると作業途中で閉じてしまうためである。 **この禁止が掛かるのはコミットメッセージだけである。PR本文には `Closes #42` を書いてよい。** PRのマージは作業が完了した時点なので、途中で閉じてしまう問題が起きない。 ### 「なぜ」をどこに書くか(本文とissueの使い分け) 「なぜ変えたか」を残す場所は、**コミット本文** と **issue** の2つがある。件名(`type: 説明`)はどの場合も必須である。 | issueの書かれ方 | 「なぜ」の置き場所 | コミット本文 | | ----------------------------------------------------------------- | ------------------ | -------------------------- | | issueの「この変更が必要な理由」節に、この変更の理由が書かれている | issue | 省略可(`(#番号)` で辿る) | | issueに無い判断をした | issue+コミット | その判断の理由を書く | ``` # Good: issueに背景があり、本文は省略 fix: ログイン失敗時のエラーメッセージを修正 (#42) # Good: issueに無い「実装上の判断」を本文に残す fix: ログイン失敗時のエラーメッセージを修正 (#42) ライブラリXのバリデーションは多言語対応が不十分なため、 issueの方針とは別に自前のメッセージ生成へ差し替えた。 ``` この使い分けが成立する前提は、**上記の表の1行目の条件を満たすこと**である。満たさない場合は、本方式は理由がどこにも残らない状態になるため、本文に書く。 ### 決定記録を残すコミット コミットに含まれる決定が、`docs/policy/adr-policy.md` の判定で「コミットの決定記録」になるときは、本文に決定・理由・却下した案を書き、最後のトレーラーの段落に `Decision-Record: yes` を足す。Issue の「対応方針」の書き先に決定記録と書かれていれば、それに従う。このトレーラーの付いたコミットは、`/past-decision-search` が `git log` から引く。トレーラーの段落以外に `Decision-Record: yes` の行を書かない。 ``` feat: 一覧 API のページングをカーソル方式にする (#123) 決定: 一覧 API のページングは、オフセットではなくカーソル(最後に返した行のキー)で行う。 理由: 一覧の途中で行が追加・削除されると、オフセット方式では行の重複や抜けが起きる。 却下した案: - オフセット方式:件数が増えるほど遅くなり、途中の追加・削除で重複や抜けが起きる Decision-Record: yes ``` ### コミットの粒度 粒度は基本的に任意とする。ただし、コミットメッセージと無関係なファイルを含めてはならない。気づいた割れ窓は直すか起票するが、無関係な変更を1つのコミットに詰めるのは別問題である(「割れ窓を放置しない」[refined-engineer-judgment-principles](../../../docs/policy/refined-engineer-judgment-principles.md))。 ``` # Bad: ログイン修正とは無関係なCSSの変更が混入している fix: ログイン失敗時のエラーメッセージを修正 - src/auth/login.ts - src/styles/global.css ← 関係ない # Good: メッセージに関係するファイルだけが含まれている fix: ログイン失敗時のエラーメッセージを修正 - src/auth/login.ts ``` ### ブランチ命名規則 ブランチ名は `<prefix>/<説明>` の形式とする。 - `feat/`:新機能・機能変更 - `fix/`:バグ修正 - `refactor/`:振る舞いを変えない構造の変更 - `chore/`:設定変更・依存関係の更新など - `ci/`:CI/CD・GitHub Actionsの変更 - `test/`:テストの追加・修正 - `docs/`:ドキュメントの変更 ## 処理フロー ### Phase 1:対象範囲の決定と変更内容の取得 引数に応じて対象範囲を決定する: - **なし(デフォルト)**:ワーキングツリー・staged 双方の差分 - `work`:ワーキングツリー(未ステージ)の差分のみ - `stage`:staged の差分のみ #### 並行セッションを検出する 同じ作業ツリーを別の Claude セッションが編集していると、既定スコープは無関係な変更まで巻き込む。巻き込まれた側は自分の作業が別 Issue のコミットに紛れたことに気づけない。そこで、範囲を決めたらまず同じ作業ツリーで動いている claude セッションの数を数える。 ```bash top=$(git rev-parse --show-toplevel) if command -v lsof >/dev/null 2>&1; then ps -eo pid=,comm= | awk '$2 == "claude" {print $1}' | while read -r pid; do cwd=$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p') [ -n "$cwd" ] && [ "$(git -C "$cwd" rev-parse --show-toplevel 2>/dev/null)" = "$top" ] && echo "$pid" done | wc -l else npm run -s --prefix "$top" count-registered-sessions fi ``` 2以上なら並行セッションがある。0 は判定できなかったことを示すので、2以上と同じく扱う。**このとき既定スコープを「このセッションで自分が Edit/Write したファイルのみ」に切り替える**(引数 `work` / `stage` の指定も、この絞り込みの中で適用する)。切り替えたことと、除外したファイルのパスを Phase 5 の出力に列挙する。 1なら単独セッションなので、既定スコープをそのまま使う。 範囲を決めたら現在の状態を把握する。**スコープに不要なコマンドは実行しない**(`work` なら staged 側、`stage` なら worktree 側は取得不要)。依存関係のないコマンドは1回の Bash 呼び出しにまとめる: ```bash git status --short # 常に取得 git diff --stat # スコープが「なし」または work のときのみ git diff --cached --stat # スコープが「なし」または stage のときのみ ``` `git diff`(内容)と `git log --oneline` は無条件に取得しない。**Phase 2 の type 判定・Phase 3 の本文執筆で実際に必要になった時点で、必要な対象だけに絞って**取得する(type がファイル名だけで判定できるならどちらも不要)。 ステータス出力の先頭2文字でステージ状態・変更タイプを判定する: ``` M file.ts # Modified(ステージ済み) M file.ts # Modified(未ステージ) A file.md # Added(ステージ済み) ?? file.txt # Untracked ``` ### Phase 2:Commit Type の判定 type の語彙は上記「ブランチ命名規則」の prefix 一覧に従う(末尾の `/` を除いたものが type)。**まずファイル名・パス・ステータス(A/M)だけで判定を試み、それで確定しない場合のみ diff 内容を取得する**: - **テストファイル(`*.test.*`, `*.spec.*`)のみ**:`test` - **`docs/` または `*.md` のみ**:`docs` - **設定ファイル(`package.json`, `tsconfig.json`, `*.config.*` など)のみ**:`chore` - **CI・GitHub Actions の変更**:`ci` - **ソースの新規追加(A)による機能拡張**:`feat` - **ソースの修正(M)によるバグ修正**:`fix` - **振る舞いを変えない構造変更**:`refactor` A=feat・M=fix はあくまで目安。修正が機能追加のこともあるため、ファイル名だけでは判断がつかない場合に限り diff 内容(該当ファイルのみ)を読む。それでも**diff 内容が type 一覧(feat/fix/refactor/docs/chore/ci/test)のどれとも一致しない、または複数の type に同時に当てはまるときは AskUserQuestion でユーザーに確認する**。 ### Phase 2.5:コミット分割の判定 上記「コミットの粒度」(無関係なファイルを混ぜない)を実践する。ファイルを `type` × トップレベルディレクトリでグループ化し、**2グループ以上に分かれる場合は分割して進める**: - 異なる type の混在(例:`docs` と `feat`)→ type ごとに分割 - 異なるトップレベルディレクトリの混在 → ディレクトリごとに分割 - 同一 type・同一ディレクトリ → 原則1コミット 同じファイルが複数の type に同時に当てはまり、上記の規則で1グループに定まらないときだけ `AskUserQuestion` で確認してよい。 ### Phase 3:メッセージの生成 上記「コミットのルール」に従って組み立てる: 1. **件名**:`type: 説明`。説明は変更内容が伝わるよう簡潔に(目安30文字以内)。 2. **issue番号**:件名末尾に `(#番号)` を付与する。番号はブランチ名等から推定し、**不明な場合はユーザーに確認する**。 3. **本文(なぜ)**:本文を書くかどうかは上記「『なぜ』をどこに書くか」の表で判断する。書く場合はコードから読み取れない背景・判断理由を記す。決定記録にあたる決定を含むなら、上記「決定記録を残すコミット」の書式で書く。 ### Phase 4:ステージング対象の決定 - Phase 1 で決定した範囲(デフォルト=work+stage全体、または `work`/`stage` 指定範囲)に含まれるソース・ドキュメント・設定・テストの各変更ファイルを対象に含める。単独セッションなら、セッション内で編集したかどうかは問わない。 - **除外して警告表示**:`.env*`, `node_modules/`, `dist/`・`build/`, `.DS_Store`/`Thumbs.db`, `*.log`。並行セッションを検出したときは、**このセッションで Edit/Write していないファイル**も除外して警告表示する。 - デフォルト範囲かつ既にステージ済みのファイルは対象に含め、確認表示では `✓` を付ける。 ### Phase 5:コミット実行 ユーザー承認は求めず、自律的に実行する。グループごとに、次の手順を順に行う。 **1. ステージする**:Phase 4 で決めた対象ファイルのパスを明示して `git add <パス>...` する(`-A` や `.` を使わない)。 **2. index を突き合わせる**:ステージ済みの一覧を取り、Phase 4 の対象リストと一致するか確認する。 ```bash git diff --cached --name-only ``` - **対象外のパスが混じっている**:別セッションが staged にしたもの。`git reset` で外さない(相手の index を壊す)。手順3のパス指定でコミット対象から外れるので、除外したパスとして出力に列挙する - **対象のパスが出てこない**:別セッションが先にコミットした可能性がある。`git log --oneline -3` と `git show --stat <hash>` で取り込み済みか確かめ、済んでいればグループから外す **3. コミットする**:対象パスを `--` の後ろに並べ、index 全体ではなくそのパスだけをコミットする。 ```bash git commit -m "<件名>" -- <対象パス>... ``` パス指定を省くと、index に載った他セッションの変更ごとコミットされる。Phase 1 でスコープを正しく絞っても実行段階で巻き込むので、ここは AI の判断に委ねず常にパスで縛る。 このコマンドは index を経由せず作業ツリーの内容をコミットする。手順1のステージ後にファイルを直していると、index には古い内容が残り、次のコミットがそれを拾う。コミット後に `git status --short` を見て、対象ファイルが残っていたら `git add <パス>` で index を揃える。pre-commit hook が再生成して再ステージする `docs/adr/` 配下のファイルは別で、コミット後に `MM` で残る。hook の `git add` が効くのは一時 index だけだからである。作業ツリーは hook が再生成した最新で HEAD と同じだから、`git restore --staged <パス>` で index だけを HEAD に戻す。 ファイルの一部だけをステージしているときは、pre-commit hook がそのファイルの prettier 整形と再ステージを見送る(`git add <パス>` が未ステージの変更ごとコミットに混ぜてしまうため)。整形の取りこぼしは、push 前の pre-push hook(`npm run format:check`)が止める。 ``` === Git Commit Summary === Commit Type: feat Message: feat: アカウント同期処理の実装 (#42) Committed Files: ✓ src/sync.ts Excluded (warnings): ⚠ .env is ignored (environment file) ⚠ docs/guide/foo.html — 並行セッションを検出したため除外(このセッションで編集していない) ``` 分割する場合は各コミットの Type・Message・対象ファイルを順に列挙する。 - 複数コミットの途中で失敗(pre-commit hook 等)した場合、成功済みコミットはロールバックしない。失敗したグループはステージされたまま残し、原因と再実行を促す。 - 完了後 `git log --oneline -n <件数>` で結果を表示する。 ## 使用方法 ``` /git-commit # デフォルト:ワーキングツリー+staged全差分が対象 /git-commit work # ワーキングツリー(未ステージ)のみ対象 /git-commit stage # stagedのみ対象 ```
Auf GitHub ansehen