Skip to main content

git-commit

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

Datos de origen

Repositorio
kasiopeiya/claude-dev-template
Última actividad en el origen
27 de septiembre de 2026 a las 12:35
Idioma detectado de SKILL.md
japonés
Estrellas
0
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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 の「対応方針」の書き先に決定記録と書かれていれば、それに従う。このトレーラーの付いたコミットは、`npm run gen:adr-index` が `docs/adr/adr-commit-list.md` の一覧に載せる。トレーラーの段落以外に `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) 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 ``` 2以上なら並行セッションがある。0 は cwd を引けず(`lsof` が無いなど)判定できなかったことを示すので、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 がそのファイルの 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のみ対象 ```
Ver en GitHub