git-workflow-and-versioning について
チームやコーディングエージェント向けの Git ワークフローとバージョン管理のスキルです。開発からリリースまで変更を小さく保つ方法として、コミット、ブランチ、worktree、セマンティックバージョニング、タグ、変更履歴を解説します。
主な機能
- 01原子的なコミットと明確なメッセージ
- 02短命なフィーチャーブランチ
- 03Git worktree による並行作業
- 04コミット前チェックと変更概要
- 05セマンティックバージョニング、タグ、変更履歴
活用シーン
- 01段階的なコード変更の整理
- 02独立したブランチでのエージェント並行作業
- 03範囲を絞った変更のレビューと取り消し
- 04再現可能で記録のあるリリースの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ addyosmani/ agent-skills --skill git-workflow-and-versioningインストール後、Claude Code で/git-workflow-and-versioningを入力して読み込まれたか確認します。
詳細
Git のワークフローとバージョン管理
概要
Git はセーフティネットです。コミットを保存ポイント、ブランチをサンドボックス、履歴をドキュメントとして扱いましょう。AI エージェントが高速でコードを生成するなか、規律あるバージョン管理が変更を管理しやすく、レビューしやすく、元に戻せる状態に保ちます。
使用するタイミング
常に使用します。コードの変更はすべて Git を通します。
基本原則
トランクベース開発(推奨)
main は常にデプロイ可能な状態に保ちます。短期間だけ使用する機能ブランチで作業し、1〜3 日以内にマージします。長期間使用する開発ブランチは隠れたコストです。ブランチが分岐し、マージの競合を生み、統合を遅らせます。DORA の調査では一貫して、トランクベース開発は高いパフォーマンスを発揮するエンジニアリングチームと相関しています。
main ──●──●──●──●──●──●──●──●──●── (always deployable)
╲ ╱ ╲ ╱
●──●─╱ ●──╱ ← short-lived feature branches (1-3 days)
これを推奨されるデフォルトとします。gitflow や長期間使用するブランチを採用しているチームは、原則(アトミックコミット、小さな変更、説明的なメッセージ)を各自のブランチモデルに適用できます。重要なのは、特定のブランチ戦略よりもコミットの規律です。
- 開発ブランチはコストです。 ブランチを使う期間が 1 日延びるごとに、マージのリスクが積み重なります。
- リリースブランチは許容されます。
mainの開発を進めながら、リリースを安定させる必要がある場合に使用します。 - 長期ブランチより機能フラグを優先します。 未完成の作業を数週間ブランチに置いておくのではなく、機能フラグで非公開にしてデプロイすることを優先します。
1. 早めに、頻繁にコミットする
成功した増分ごとに、個別のコミットを作成します。大量の変更をコミットしないまま溜め込まないでください。
Work pattern:
Implement slice → Test → Verify → Commit → Next slice
Not this:
Implement everything → Hope it works → Giant commit
コミットは保存ポイントです。次の変更で何かが壊れた場合、最後に正常だった状態へすぐに戻せます。
2. アトミックコミット
各コミットでは、論理的にひとつのことだけを行います。
# Good: Each commit is self-contained
git log --oneline
a1b2c3d Add task creation endpoint with validation
d4e5f6g Add task creation form component
h7i8j9k Connect form to API and add loading state
m1n2o3p Add task creation tests (unit + integration)
# Bad: Everything mixed together
git log --oneline
x1y2z3a Add task feature, fix sidebar, update deps, refactor utils
3. 説明的なメッセージ
コミットメッセージでは、単に「何を」ではなく「なぜ」を説明します。
# Good: Explains intent
feat: add email validation to registration endpoint
Prevents invalid email formats from reaching the database.
Uses Zod schema validation at the route handler level,
consistent with existing validation patterns in auth.ts.
# Bad: Describes what's obvious from the diff
update auth.ts
形式:
<type>: <short description>
<optional body explaining why, not what>
種類:
feat— 新機能fix— バグ修正refactor— バグ修正や機能追加を目的としないコード変更test— テストの追加または更新docs— ドキュメントのみの変更chore— ツール、依存関係、設定
4. 関心事を分ける
フォーマット変更と動作変更を組み合わせないでください。リファクタリングと機能追加を組み合わせないでください。変更の種類ごとに別のコミットに分け、できれば別々の PR にします。
# Good: Separate concerns
git commit -m "refactor: extract validation logic to shared utility"
git commit -m "feat: add phone number validation to registration"
# Bad: Mixed concerns
git commit -m "refactor validation and add phone number field"
リファクタリングと機能開発は分けます。 リファクタリングと機能変更は別々の変更です。それぞれを分けて提出しましょう。変更ごとにレビューや取り消しがしやすくなり、履歴から内容を把握しやすくなります。変数名の変更など、小規模な整理はレビュー担当者の判断で機能追加のコミットに含めてもかまいません。
5. 変更の規模を調整する
コミット/PR あたり約 100 行を目安にします。約 1000 行を超える変更は分割してください。大規模な変更を分割する方法については、code-review-and-quality の分割戦略を参照してください。
~100 lines → Easy to review, easy to revert
~300 lines → Acceptable for a single logical change
~1000 lines → Split into smaller changes
ブランチ戦略
機能ブランチ
main (always deployable)
│
├── feature/task-creation ← One feature per branch
├── feature/user-settings ← Parallel work
└── fix/duplicate-tasks ← Bug fixes
main(またはチームのデフォルトブランチ)からブランチを作成します- ブランチは短期間だけ使用します(1〜3 日以内にマージします)。長期間使用するブランチは隠れたコストです
- マージ後にブランチを削除します
- 未完成の機能には、長期間使用するブランチより機能フラグを優先します
ブランチの命名
feature/<short-description> → feature/task-creation
fix/<short-description> → fix/duplicate-tasks
chore/<short-description> → chore/update-deps
refactor/<short-description> → refactor/auth-module
ワークツリーの利用
AI エージェントを並行して作業させる場合は、Git のワークツリーを使って複数のブランチを同時に実行します。
# Create a worktree for a feature branch
git worktree add ../project-feature-a feature/task-creation
git worktree add ../project-feature-b feature/user-settings
# Each worktree is a separate directory with its own branch
# Agents can work in parallel without interfering
ls ../
project/ ← main branch
project-feature-a/ ← task-creation branch
project-feature-b/ ← user-settings branch
# When done, merge and clean up
git worktree remove ../project-feature-a
利点:
- 複数のエージェントが異なる機能に同時に取り組めます
- 各ディレクトリに独自のブランチがあるため、ブランチを切り替える必要がありません
- 実験がうまくいかなかった場合は、ワークツリーを削除すればよく、何も失われません
- 明示的にマージするまで変更が分離されます
保存ポイントのパターン
Agent starts work
│
├── Makes a change
│ ├── Test passes? → Commit → Continue
│ └── Test fails? → Revert to last commit → Investigate
│
├── Makes another change
│ ├── Test passes? → Commit → Continue
│ └── Test fails? → Revert to last commit → Investigate
│
└── Feature complete → All commits form a clean history
このパターンでは、失う作業は最大でもひとつの増分にとどまります。エージェントが道を外れた場合は、git reset --hard HEAD で最後に成功した状態へ戻せます。
変更の概要
変更を加えた後は、必ず構造化された概要を提示してください。これにより、レビューが容易になり、変更範囲を適切に保てているかを記録し、意図しない変更を明らかにできます。
CHANGES MADE:
- src/routes/tasks.ts: Added validation middleware to POST endpoint
- src/lib/validation.ts: Added TaskCreateSchema using Zod
THINGS I DIDN'T TOUCH (intentionally):
- src/routes/auth.ts: Has similar validation gap but out of scope
- src/middleware/error.ts: Error format could be improved (separate task)
POTENTIAL CONCERNS:
- The Zod schema is strict — rejects extra fields. Confirm this is desired.
- Added zod as a dependency (72KB gzipped) — already in package.json
このパターンにより、誤った思い込みを早期に発見でき、レビュー担当者に変更内容を明確に示せます。特に「DIDN'T TOUCH」セクションは重要です。変更範囲を守り、頼まれていない改修に手を広げていないことを示せます。
コミット前の準備
コミットする前に、毎回次のことを行ってください。
# 1. Check what you're about to commit
git diff --staged
# 2. Ensure no secrets
git diff --staged | grep -i "password\|secret\|api_key\|token"
# 3. Run tests
npm test
# 4. Run linting
npm run lint
# 5. Run type checking
npx tsc --noEmit
Git フックを使って自動化します。
// package.json (using lint-staged + husky)
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md}": ["prettier --write"]
}
}
生成ファイルの扱い
- 生成ファイルをコミットするのは、プロジェクトで必要とされている場合に限ります(例:
package-lock.json、Prisma のマイグレーション) - ビルド出力(
dist/、.next/)、環境ファイル(.env)、IDE 設定(共有する場合を除き、.vscode/settings.json)はコミットしないでください - 次の項目を含む
.gitignoreを用意してください:node_modules/、dist/、.env、.env.local、*.pem
デバッグに Git を使う
# Find which commit introduced a bug
git bisect start
git bisect bad HEAD
git bisect good <known-good-commit>
# Git checkouts midpoints; run your test at each to narrow down
# View what changed recently
git log --oneline -20
git diff HEAD~5..HEAD -- src/
# Find who last changed a specific line
git blame src/services/task.ts
# Search commit messages for a keyword
git log --grep="validation" --oneline
リリースとバージョン管理
コミットはあなたが変更を追跡するためのもので、バージョンは利用者が変更を追跡するためのものです。別のチーム、公開済みパッケージ、デプロイ済みクライアントなど、ほかの何かがあなたのコードに依存した時点で、「main の最新」というだけでは「今、何を実行していて、安全にアップグレードできるのか」という問いに答えられなくなります。バージョン番号と変更履歴が、その問いへの答えとなる契約です。
セマンティックバージョニング
利用者がいるものはすべて、バージョンを MAJOR.MINOR.PATCH とし、番号に意味を持たせます。
MAJOR breaking change — consumers must change their code to upgrade
MINOR new functionality, backward-compatible — safe to upgrade
PATCH bug fix, backward-compatible — safe to upgrade
バージョン番号は約束です。そのため、コードもそれに合わせてください。利用者が頼りにしていた挙動を変える「パッチ」は、変装したメジャー変更です(Hyrum's Law — api-and-interface-design スキルを参照)。変更が互換性を破るかどうか迷ったら、破るものと考えてください。予期しないメジャー変更のほうが、利用者の環境を壊すよりはるかに低コストです。
リリースにタグを付け、そのタグを信頼できる情報源にする
リリースとは、移動するブランチではなく、変更できない履歴上の時点です。いつでも再現できるように、タグを付けてください。
git tag -a v1.4.0 -m "Release 1.4.0"
git push origin v1.4.0
複数のファイルを手作業で編集するのではなく、タグからバージョンを導出してください。そうすれば、成果物、タグ、変更履歴が食い違うことはありません。
人が読みやすい変更履歴を保つ
変更履歴は git log ではありません。「何が変わり、それは自分に関係があるのか」という問いに対する、利用者向けに整理された回答です。新しいものから順に Added / Changed / Fixed / Deprecated / Removed / Security に分類し、各項目は内部の仕組みではなく、利用者への影響を中心に記述します。
## [1.4.0] - 2025-06-12
### Added
- Bulk task import via CSV
### Fixed
- Timezone drift in recurring task due dates
### Deprecated
- `GET /v1/tasks/all` — use the paginated `GET /v1/tasks` (removal in 2.0)
変更の影響がまだ新しいうちに、その変更を加えるコミットで変更履歴の項目も作成してください。リリース時にコミット履歴をたどって再構成するのは避けます。互換性を破る変更には、移行に関する注記と非推奨期間を設けてください(deprecation-and-migration スキルに従ってください)。実際のリリース作業は shipping-and-launch スキルの担当です。このセクションでは、そこにつながるバージョン管理の契約を定めます。
よくある合理化
| 合理化 | 実際 |
|---|---|
| 「機能が完成したらコミットする」 | 巨大なコミットはレビューもデバッグも取り消しも困難です。変更を小分けにしてコミットしてください。 |
| 「メッセージは重要ではない」 | メッセージはドキュメントです。将来のあなた(そして将来のエージェント)が、何がなぜ変わったのかを理解する必要があります。 |
| 「後ですべてをスカッシュする」 | スカッシュすると開発の経緯が失われます。最初から、整理された小刻みなコミットを心がけてください。 |
| 「ブランチは手間が増える」 | 短命なブランチはコストがかからず、競合する作業の衝突を防ぎます。問題なのは長命なブランチです。1~3日以内にマージしてください。 |
| 「後でこの変更を分割する」 | 大きな変更はレビューが難しく、デプロイのリスクが高まり、取り消しも困難になります。提出後ではなく、提出前に分割してください。 |
「.gitignore は必要ない」 | 本番用のシークレットを含む .env をコミットするまではそう思うかもしれません。すぐに設定してください。 |
| 「小さな修正だから、パッチバージョンを上げる」 | 利用者から見える変更を確認してください。利用者が依存していた動作の変更は、差分の大きさにかかわらずメジャー変更です。 |
| 「変更履歴はコミットログにすぎない」 | コミットは開発者向け、変更履歴は利用者向けで、影響度に基づいて整理するものです。生のコミットから生成すると、重要な情報が埋もれてしまいます。 |
| 「リリース時に変更履歴を書く」 | その時点では、影響を記憶から再構成することになり、その半分は抜け落ちています。変更と同時に項目を書いてください。 |
注意すべき兆候
- コミットされていない変更が大量に蓄積している
- 「fix」「update」「misc」のようなコミットメッセージ
- 書式変更と動作変更が混在している
- プロジェクトに
.gitignoreがない node_modules/、.env、ビルド成果物をコミットしているmainから大きく乖離した長命なブランチ- 共有ブランチへの強制プッシュ
- 破壊的変更がマイナーまたはパッチバージョンの更新としてリリースされている
- タグなしのリリース、またはタグと同期しないバージョン番号の手動編集
- 利用者向けリリースに変更履歴の項目がない、または変更履歴がコミットメッセージをそのまま並べただけになっている
確認事項
コミットごとに:
- コミットが1つの論理的な変更を行っている
- メッセージが理由を説明し、種類の規約に従っている
- コミット前にテストが通っている
- 差分にシークレットが含まれていない
- 書式だけの変更と動作変更が混在していない
-
.gitignoreに標準的な除外対象が含まれている
リリースごとに(利用者がいるものすべて):
- バージョン更新が変更内容に合っている:破壊的変更 → メジャー、追加 → マイナー、修正 → パッチ
- リリースにタグが付けられ、バージョンが手動編集でタグと食い違うのではなく、タグから決定されている
- 変更履歴に、このバージョンの影響度別に整理された、精選された読みやすい項目がある