Claude CodeのHook + Skillで、コミット後の変更を自動的にコミットする方法
Claude CodeのStop Hookで未コミットの変更を検知し、カスタムCommit Skillで自動的にグループコミットを行うことで、手動コミットを不要にする方法を紹介。
キーポイント
Claude CodeのHook機能を活用し、タスク完了時に未コミットの変更を自動検知・ブロックする仕組みを構築
Commit Skillで変更内容を分析し、意味のあるコミットメッセージを自動生成してグループ化コミットを実現
Git管理のワークフロー自動化により、AI支援執筆プロセスでのコミット忘れ問題を解決
影響分析・編集コメントを表示
影響分析
この記事は、AI支援ツール(Claude Code)とバージョン管理システム(Git)を連携させる実用的な自動化手法を示しており、AIを日常業務に統合する際の具体的な応用例として参考になる。ただし、特定ツールに依存したカスタマイズ事例であり、業界全体への広範な影響は限定的である。
編集コメント
AIツールのカスタマイズ能力を活かした実用的な自動化事例。技術的な詳細が具体的に記述されており、同様の課題を持つ開発者にとって参考になる内容。
私はGitを使ってすべての執筆コンテンツを管理しています。記事、素材、アウトライン、草稿など、すべてがリポジトリ内にあります。問題は、私がよくコミットを忘れてしまうことです。記事を書き終え、推敲し、公開した後、他のことに取り掛かってしまいます。数日後にgit statusを見ると、未コミットの変更が山積みになっています。
現在、私はClaude Codeを使って執筆プロセスを実行しており、素材分析から完成稿の公開まで、基本的にすべてを任せています。毎回のタスクでファイルを変更しているのだから、変更後に自動的にコミットさせられないでしょうか?
Claude CodeはHookメカニズムをサポートしており、特定のイベント(セッション開始、ツール呼び出し前後、タスク終了など)が発生したときに自動的にスクリプトを実行します。考え方はGit Hookと似ていますが、Claude Codeのライフサイクルにフックされています。
私はプロジェクトの.claude/settings.local.jsonに以下を追加しました:
"hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-commit.sh" }] }] }
スクリプトが行うことはシンプルです:ワークスペースに未コミットの変更(新規ファイル、変更、削除)があるかどうかをチェックし、もしあれば、Claude Codeが停止するのを阻止し、「まだやるべきことが残っています、コミットしてください」と伝えます。
if git diff --quiet && git diff --cached --quiet && \ [ -z "$(git ls-files --others --exclude-standard)" ]; then exit 0 # 変更なし、正常終了 fi # 変更あり、ブロックする echo '{"decision": "block", "reason": "检测到未提交的变更,请调用 /commit 技能提交更新。"}'
もう一つの詳細:コミット自体も「タスク終了」をトリガーするため、処理しないと無限ループになります。スクリプトはstop_hook_activeを使用してこれを回避します。
Commit Skill:コミットを意味のあるものにする
Hookはブロックするだけです。具体的なコミット方法はCommit Skillに依存します。
SkillはClaude Codeのスキルモジュールで、.claude/skills/に配置されます。
まず、変更されたファイルのパスを分析し、記事、スキル設定、コードのどれが変更されたかを判断します。
テーマごとにグループ化してコミットし、すべてを1つのコミットに詰め込まないようにします。例えば、2つの記事を変更した場合は、2回に分けてコミットします。
自動的に中国語のコミットメッセージを生成し、フォーマットは固定です:記事には「添加/润色/更新 + 主题」、コードには「优化/修复 + 功能」を使用します。
明確にコミットするファイルを指定し、git add . を避けます。
42257b3 添加 Amodei NYT 访谈整理文章 c4eee96 添加 Peter Steinberger OpenClaw 访谈整理文章 e2a01da 润色 Suleyman FT 专访文章
それぞれが何を変更したかを明確に説明しており、「update files」や「misc changes」のような意味のない情報ではありません。
2つのメカニズムの連携:Hookは門番として機能し、変更が漏れないように保証します。Skillは実行者として機能し、毎回のコミットが意味を持つように保証します。私はもうコミットのことを気にかける必要がなくなりました。
ファイルパス:.claude/hooks/auto-commit.sh
#!/bin/bash # Stop hook: タスク完了後に未コミットの変更を自動検出し、commit skillをトリガー INPUT=$(cat) STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false') # 無限ループ防止:コミット後に再度トリガーされた場合はそのまま通過 if [ "$STOP_HOOK_ACTIVE" = "true" ]; then exit 0 fi # 未コミットの変更があるかチェック cd "$CLAUDE_PROJECT_DIR" 2>/dev/null || exit 0 # ワークスペースに変更があるかチェック(変更済み、新規ファイルなど) if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null && [ -z "$(git ls-files --others --exclude-standard 2>/dev/null)" ]; then # 変更なし、正常終了 exit 0 fi # 未コミットの変更あり、Claudeの停止を阻止し、commitの実行を継続させる cat <<'EOF' {"decision": "block", "reason": "检测到未提交的变更,请调用 /commit 技能提交更新。"} EOF
ファイルパス:.claude/skills/commit/SKILL.md
--- name: commit description: 現在コミットされていない変更をコミットします。変更内容を自動分析し、規範的なコミットメッセージを生成し、ディレクトリごとのグループコミットまたはすべての変更の一括コミットをサポートします。 --- # Git Commit スキル 現在コミットされていない変更をgitリポジトリにコミットします。 ## ワークフロー ### ステップ1:未コミットの変更を確認 git status --short 変更タイプの分析: - M - 変更済み - ?? - 新規ファイル(未追跡) - D - 削除済み - R - リネーム済み ### ステップ2:変更内容の分析 変更されたファイルのパスに基づいて変更タイプを判断: | パスパターン | 変更タイプ | |----------|----------| | posts/YYYY-MM-DD/[slug]/ | 記事関連 | | .claude/skills/ | スキル設定 | | src/ | スクリプトコード | | .r2-upload-map/ | リソースマッピング(通常は単独でコミットしない) | | その他 | プロジェクト設定 | ### ステップ3:コミット戦略の決定 単一テーマの変更:すべてのファイルを一度にコミット 複数テーマの変更:ディレクトリ/テーマごとにグループ化してコミット グループ化の優先順位: 1. 記事ディレクトリ(記事ごとに1コミット) 2. スキルディレクトリ(スキルごとに1コミット) 3. コード変更(1つのコミットにまとめる) 4. 設定ファイル(1つのコミットにまとめる) ### ステップ4:コミットメッセージの生成 フォーマット規範: - 中国語を使用 - 変更内容を簡潔に記述 - 50字以内 よく使われるテンプレート: - 記事:添加 [記事テーマの概要]、润色 [記事タイトル]、更新 [記事タイトル] - スキル:添加 [スキル名] 技能、更新 [スキル名] 技能 - コード:优化 [機能の説明]、修复 [問題の説明] - 設定:更新项目配置 ### ステップ5:コミットの実行 git add <file1> <file2> ... git commit -m "commit message" 注意: - git add . や git add -A の使用を避ける - コミットするファイルを明確に指定 - 一時ファイル(.bak-*、.html.bak-*)を除外 ### ステップ6:結果の確認 git log --oneline -3 最近のコミット履歴を出力して成功を確認。 ## 除外ルール 以下のファイルはデフォルトでコミットしません: - *.bak-* - バックアップファイル - .DS_Store - macOSシステムファイル - node_modules/ - 依存関係ディレクトリ - .r2-upload-map/*.json - 通常は記事と一緒にコミットします。単独でのコミットが要求されない限り
ファイルパス:.claude/settings.local.json
{ "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-commit.sh" }] }] } }

原文を表示
See all postsPublished on 2026-02-18用 Claude Code 的 Hook + Skill,实现每次提交后自从 commit 提交变更
我用 Git 管理所有写作内容,文章、素材、提纲、草稿,全在仓库里。问题是我经常忘记提交。写完一篇文章,润色完,发布了,然后就去忙别的了。过几天一看 git status
现在我用 Claude Code 跑写作流程,从素材分析到成稿发布基本都交给它。既然每次任务它都在改文件,能不能让它改完就自己提交?
Claude Code 支持 Hook 机制,在特定事件(会话开始、工具调用前后、任务结束等)发生时自动执行脚本。思路和 Git Hook 类似,但挂在 Claude Code 的生命周期上。
我在项目的 .claude/settings.local.json
"hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-commit.sh" }] }] }
脚本做的事很简单:检查工作区有没有未提交的变更(新文件、修改、删除),如果有,就阻止 Claude Code 停下来,告诉它“你还有活没干完,去提交”。
if git diff --quiet && git diff --cached --quiet && \ [ -z "$(git ls-files --others --exclude-standard)" ]; then exit 0 # 没变更,正常结束 fi # 有变更,拦住它 echo '{"decision": "block", "reason": "检测到未提交的变更,请调用 /commit 技能提交更新。"}'
还有个细节:提交本身也会触发“任务结束”,不处理就无限循环。脚本用 stop_hook_active
Commit Skill:让提交有意义
Hook 只管拦截,具体怎么提交靠 Commit Skill。
Skill 是 Claude Code 的技能模块,放在 .claude/skills/
先分析变更文件的路径,判断改的是文章、技能配置还是代码
按主题分组提交,不把所有东西塞进一个 commit。比如改了两篇文章,就分两次提交
自动生成中文 commit message,格式固定:文章用“添加/润色/更新 + 主题”,代码用“优化/修复 + 功能”
明确指定提交文件,避免 git add .
42257b3 添加 Amodei NYT 访谈整理文章 c4eee96 添加 Peter Steinberger OpenClaw 访谈整理文章 e2a01da 润色 Suleyman FT 专访文章
每条都说得清楚这次改了什么,不是那种“update files”或者“misc changes”的垃圾信息。
两个机制的配合:Hook 当守门员,保证没有变更被遗漏;Skill 当执行者,保证每次提交都有意义。 我再也不用惦记提交这件事了。
文件路径:.claude/hooks/auto-commit.sh
#!/bin/bash # Stop hook: 任务完成后自动检测未提交变更并触发 commit skill INPUT=$(cat) STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false') # 防止无限循环:commit 后再次触发时直接放行 if [ "$STOP_HOOK_ACTIVE" = "true" ]; then exit 0 fi # 检查是否有未提交的变更 cd "$CLAUDE_PROJECT_DIR" 2>/dev/null || exit 0 # 检查工作区是否有变更(已修改、新文件等) if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null && [ -z "$(git ls-files --others --exclude-standard 2>/dev/null)" ]; then # 没有变更,正常结束 exit 0 fi # 有未提交变更,阻止 Claude 停止,让它继续执行 commit cat <<'EOF' {"decision": "block", "reason": "检测到未提交的变更,请调用 /commit 技能提交更新。"} EOF
文件路径:.claude/skills/commit/SKILL.md
--- name: commit description: 提交当前未 commit 的修改。自动分析变更内容,生成规范的 commit message,支持按目录分组提交或一次性提交所有修改。 --- # Git Commit 技能 提交当前未 commit 的修改到 git 仓库。 ## 工作流程 ### 步骤一:查看未提交修改 git status --short 分析变更类型: - M - 已修改 - ?? - 新文件(未跟踪) - D - 已删除 - R - 重命名 ### 步骤二:分析变更内容 根据修改文件路径判断变更类型: | 路径模式 | 变更类型 | |----------|----------| | posts/YYYY-MM-DD/[slug]/ | 文章相关 | | .claude/skills/ | 技能配置 | | src/ | 脚本代码 | | .r2-upload-map/ | 资源映射(通常不单独提交) | | 其他 | 项目配置 | ### 步骤三:决定提交策略 单一主题修改:一次性提交所有文件 多主题修改:按目录/主题分组提交 分组优先级: 1. 文章目录(每篇文章一个 commit) 2. 技能目录(每个技能一个 commit) 3. 代码变更(合并为一个 commit) 4. 配置文件(合并为一个 commit) ### 步骤四:生成 Commit Message 格式规范: - 用中文 - 简洁描述变更内容 - 不超过 50 字 常用模板: - 文章:添加 [文章主题简述]、润色 [文章标题]、更新 [文章标题] - 技能:添加 [技能名] 技能、更新 [技能名] 技能 - 代码:优化 [功能描述]、修复 [问题描述] - 配置:更新项目配置 ### 步骤五:执行提交 git add <file1> <file2> ... git commit -m "commit message" 注意: - 避免使用 git add . 或 git add -A - 明确指定要提交的文件 - 排除临时文件(.bak-*、.html.bak-*) ### 步骤六:确认结果 git log --oneline -3 输出最近提交记录确认成功。 ## 排除规则 以下文件默认不提交: - *.bak-* - 备份文件 - .DS_Store - macOS 系统文件 - node_modules/ - 依赖目录 - .r2-upload-map/*.json - 通常随文章一起提交,除非单独要求
文件路径:.claude/settings.local.json
{ "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-commit.sh" }] }] } }

関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み