Git コミット完全チートシート

## 目次
1. [コミットの基本原則](#1-コミットの基本原則)
2. [良いコミットメッセージの書き方](#2-良いコミットメッセージの書き方)
3. [コミット単位の決め方](#3-コミット単位の決め方)
4. [コミットの標準フォーマット](#4-コミットの標準フォーマット)
5. [基本的なコミットコマンド](#5-基本的なコミットコマンド)
6. [コミットの修正と管理](#6-コミットの修正と管理)
7. [ブランチ戦略とコミット](#7-ブランチ戦略とコミット)
8. [コミットフック](#8-コミットフック)
9. [CI/CDとの連携](#9-CICDとの連携)
10. [トラブルシューティング](#10-トラブルシューティング)

## 1. コミットの基本原則

### 1.1 原子的コミット
- **1つの論理的変更 = 1つのコミット**：1つの機能追加や1つのバグ修正を1つのコミットにまとめる
- **複数の変更を混ぜない**：異なる目的の変更は別々のコミットに分ける
- **なぜ重要か**：レビュー、バグ追跡、リバート（変更取り消し）が容易になる

### 1.2 コミットのタイミング
- **頻繁にコミットする**：作業を小さな単位に分けて頻繁にコミットする
- **動作する状態でコミットする**：コードが正常に動作する状態でコミットすべき
- **一日の終わりにはコミットする**：未コミットの変更を残して帰らない

### 1.3 理想的なコミットサイズ
- **小さすぎない**：「変数名の変更」だけなど、微小すぎる変更は避ける
- **大きすぎない**：300〜500行程度の変更を目安とする
- **例外**：リファクタリングや依存関係の更新など、大規模な変更が必要な場合もある

## 2. 良いコミットメッセージの書き方

### 2.1 基本構造
```
[タイプ] 簡潔な要約（50文字以内）

詳細な説明（72文字で改行）。何を変更したかではなく、
なぜ変更したのかに焦点を当てる。

関連する課題番号やリンク:
Fixes #123
Related to #456
```

### 2.2 要約行のポイント
- **命令形で書く**：「追加した」ではなく「追加する」
- **大文字で始める**
- **末尾にピリオドを付けない**
- **50文字以内に収める**
- **何を」ではなく「なぜ」と「どのように」を説明する

### 2.3 詳細説明のポイント
- **空行で要約と区切る**
- **72文字で折り返す**
- **変更の背景や理由を説明する**
- **関連するバグチケットやドキュメントへの参照を含める**

### 2.4 良いコミットメッセージの例
```
[feat] ユーザー認証にGoogle OAuthを追加

セキュリティ強化のため、既存のパスワード認証に加えて
Google OAuthによるログインオプションを追加。

- ユーザーはGoogleアカウントでログイン可能
- 初回ログイン時に自動的にユーザーアカウントを作成
- 既存ユーザーは設定画面でGoogleアカウントと紐付け可能

Refs #142
```

### 2.5 レビュー指摘対応のコミットメッセージ例
```
[review] ユーザー登録フォームのバリデーション強化

PR #67のレビュー指摘対応:
- メールアドレスの正規表現バリデーションを修正
- パスワード強度チェックを追加
- エラーメッセージの表示方法を改善

Addresses review comments in PR #67
```

## 3. コミット単位の決め方

### 3.1 機能単位でコミットする
- **1つの機能 = 1つ以上の論理的なコミット**
- **機能完成前の中間コミット**：WIP (Work In Progress) プレフィックスを付ける
- **例**：ログイン機能の追加なら「ログインフォームのUI作成」「認証ロジックの実装」「エラーハンドリングの追加」など

### 3.2 ファイル種別ごとに分ける場合
- **フロントエンドとバックエンドの変更を分ける**
- **データベースマイグレーションは別コミット**
- **設定ファイルの変更は分離する**

### 3.3 リファクタリングのコミット
- **機能変更とリファクタリングを混ぜない**
- **リファクタリングは必ず別コミットにする**
- **テスト追加も別コミットが望ましい**

### 3.4 指摘対応のコミット
- **レビュー指摘は対応ごとに分ける**：1つの指摘に対して1つのコミット
- **指摘内容をコミットメッセージに含める**：どの指摘に対応したのかを明確にする
- **プレフィックスを付ける**：`[fix]`や`[review]`などでレビュー指摘対応と分かるようにする
- **関連チケット番号を参照する**：`Fixes #123`や`Addresses review comment in PR #45`
- **複数の小さな指摘はまとめる場合も**：関連性の高い軽微な修正は1つのコミットにまとめる
- **大きな修正は分割する**：設計変更を伴う指摘は複数コミットに分ける

## 4. コミットの標準フォーマット

### 4.1 Conventional Commits
```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

#### 4.1.1 よく使われるタイプ
- **feat**: 新機能
- **fix**: バグ修正
- **docs**: ドキュメントのみの変更
- **style**: コードの動作に影響しない変更（フォーマット等）
- **refactor**: バグ修正や機能追加ではないコード変更
- **perf**: パフォーマンス改善
- **test**: テストの追加・修正
- **chore**: ビルドプロセスやツールの変更、ライブラリの更新など
- **ci**: CI設定ファイルやスクリプトの変更

#### 4.1.2 スコープの例
- **auth**: 認証関連
- **api**: API関連
- **ui**: ユーザーインターフェース
- **db**: データベース
- **config**: 設定

### 4.2 Gitmojiの活用
コミットメッセージの先頭に絵文字を付けて視覚的に分かりやすくする手法：

- **✨ (feat)**: 新機能
- **🐛 (fix)**: バグ修正
- **📚 (docs)**: ドキュメント
- **🎨 (style)**: スタイル・フォーマット
- **♻️ (refactor)**: リファクタリング
- **⚡️ (perf)**: パフォーマンス改善
- **✅ (test)**: テスト
- **🔧 (chore)**: 設定変更

### 4.3 日本語環境でのコミットメッセージ
- **英語と日本語の混在を避ける**：どちらかに統一
- **日本語の場合**：文字化けに注意（UTF-8を使用）
- **チーム内で統一する**：フォーマットをチーム内で統一して一貫性を保つ

## 5. 基本的なコミットコマンド

### 5.1 新規コミット作成
```
# 変更をステージングエリアに追加
git add <ファイル名>

# 全ての変更をステージングエリアに追加
git add .

# 変更をコミット
git commit -m "コミットメッセージ"

# 変更を追加してコミット（新規ファイルは追加されない）
git commit -am "コミットメッセージ"
```

### 5.2 変更の確認
```
# 変更状態の確認
git status

# 変更内容の詳細表示
git diff

# ステージングされた変更の詳細表示
git diff --staged

# コミット履歴の表示
git log

# コミット履歴をグラフ表示
git log --graph --oneline --decorate
```

### 5.3 部分的なコミット
```
# ファイルの一部だけをステージング
git add -p <ファイル名>

# 対話的にステージングする変更を選択
git add -i
```

## 6. コミットの修正と管理

### 6.1 直前のコミットの修正
```
# 直前のコミットメッセージを変更
git commit --amend -m "新しいメッセージ"

# 変更を追加して直前のコミットを修正（メッセージ変更なし）
git add <ファイル名>
git commit --amend --no-edit

# 変更を追加して直前のコミットを修正（メッセージも変更）
git add <ファイル名>
git commit --amend
```

### 6.2 コミットの打ち消し
```
# コミットを打ち消す新しいコミットを作成
git revert <コミットハッシュ>

# 直前のコミットを打ち消す
git revert HEAD
```

### 6.3 複数コミットの統合（squash）
```
# 直近のn個のコミットを対話的に操作
git rebase -i HEAD~n

# masterからの全コミットを対話的に操作
git rebase -i master
```

リベース中の操作：
- **pick**: コミットをそのまま使用
- **reword**: コミットを使用するがメッセージを変更
- **edit**: コミットを使用するが修正のために停止
- **squash**: 直前のコミットと統合し、コミットメッセージも統合
- **fixup**: 直前のコミットと統合するがメッセージは破棄
- **drop**: コミットを削除

### 6.4 コミットの分割
```
# 対象のコミットまでリベース
git rebase -i <分割したいコミットの1つ前のハッシュ>

# 対象コミットを「edit」に変更して保存
# コミットを取り消す（変更はステージングに残る）
git reset HEAD^

# 変更を部分的にステージングして複数のコミットに分ける
git add <ファイル1>
git commit -m "1つ目のコミット"
git add <ファイル2>
git commit -m "2つ目のコミット"

# リベースを続行
git rebase --continue
```

### 6.5 コミットの移動（cherry-pick）
```
# 特定のコミットを現在のブランチに適用
git cherry-pick <コミットハッシュ>

# 複数のコミットを順番に適用
git cherry-pick <コミットハッシュ1> <コミットハッシュ2>

# コミットをマージせずに変更だけをステージングエリアに追加
git cherry-pick -n <コミットハッシュ>
```

### 6.6 レビュー指摘後の修正戦略
```
# 1. 既存コミットを修正する方法
git add <修正ファイル>
git commit --amend --no-edit  # 直前のコミットに修正を追加

# 2. 新しいコミットを作成する方法
git add <修正ファイル>
git commit -m "[review] レビュー指摘対応: フォームバリデーション修正"

# 3. fixupコミットを作成する方法（後でsquashする前提）
git add <修正ファイル>
git commit --fixup=<修正対象のコミットハッシュ>

# 4. PRマージ前にfixupコミットを自動的に統合
git rebase -i --autosquash <ブランチのベースコミット>
```

## 7. ブランチ戦略とコミット

### 7.1 Feature Branch Workflow
- **特徴**：機能ごとに専用ブランチを作成
- **コミット方針**：機能ブランチでは小さな作業単位で頻繁にコミット
- **マージ前**：関連コミットをsquashして整理してからマージするケースが多い
- **PRサイズ**：レビューしやすいサイズ（通常500行以下）に保つ

### 7.2 Git Flow
- **特徴**：develop, feature, release, hotfix, masterの5種類のブランチを使用
- **コミット方針**：
  - **feature**：自由にコミット
  - **develop**：機能完成時にマージ
  - **release**：バグ修正のみコミット
  - **hotfix**：緊急バグ修正
  - **master**：製品リリース時のみ

### 7.3 Trunk Based Development
- **特徴**：主にmainブランチに直接コミット、短命なフィーチャーブランチを使用
- **コミット方針**：
  - 小さな変更を頻繁にmainに統合
  - フィーチャートグル（機能フラグ）を活用して未完成機能を本番環境に含める
  - CI/CDパイプラインとの統合が重要

### 7.4 レビュープロセスとコミット戦略
- **プルリクエスト前のコミット整理**：レビュー前にsquashや分割で整理
- **レビュー中のコミット**：
  - **追加コミット方式**：指摘対応を新しいコミットとして追加（履歴が追える）
  - **修正コミット方式**：元のコミットを修正（歴史を綺麗に保つ）
  - **Fixupコミット方式**：`--fixup`フラグでマーク付けして後で統合
- **レビュー後のコミット整理**：マージ前に`git rebase -i`で整理する
- **コミット署名**：`git commit -s`でSigned-off-byを追加（一部のプロジェクトで必須）

## 8. コミットフック

### 8.1 pre-commitフック
```bash
#!/bin/bash
# .git/hooks/pre-commit
# 実行権限を付与: chmod +x .git/hooks/pre-commit

# コードスタイルチェック
npm run lint

# テスト実行
npm test

# 0以外の終了コードならコミットを中止
if [ $? -ne 0 ]; then
  echo "テストに失敗しました。コミットを中止します。"
  exit 1
fi
```

### 8.2 commit-msgフック
```bash
#!/bin/bash
# .git/hooks/commit-msg
# 実行権限を付与: chmod +x .git/hooks/commit-msg

# コミットメッセージが規約に沿っているか確認
commit_msg=$(cat $1)
pattern="^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?: .{1,50}$"

if ! [[ $commit_msg =~ $pattern ]]; then
  echo "コミットメッセージが規約に沿っていません。例: feat: 新機能の追加"
  exit 1
fi
```

### 8.3 Husky（Node.jsプロジェクト用）
package.jsonの設定例：
```json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  },
  "lint-staged": {
    "*.js": ["eslint --fix", "prettier --write", "git add"],
    "*.{json,md}": ["prettier --write", "git add"]
  },
  "commitlint": {
    "extends": ["@commitlint/config-conventional"]
  }
}
```

## 9. CI/CDとの連携

### 9.1 コミットトリガーのCI/CD
- **Pull Requestごとにテスト実行**
- **特定ブランチへのコミットで自動デプロイ**
- **コミットメッセージに基づく処理分岐**

### 9.2 GitHub Actionsの例
```yaml
name: CI

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '16'
    - name: Install dependencies
      run: npm ci
    - name: Run linter
      run: npm run lint
    - name: Run tests
      run: npm test
```

### 9.3 SemVerとの連携
- **feat: コミットで minor バージョンアップ**
- **fix: コミットで patch バージョンアップ**
- **BREAKING CHANGE: を含むコミットで major バージョンアップ**

## 10. トラブルシューティング

### 10.1 間違ったコミットをした場合
```
# 直前のコミットを取り消し（変更は保持）
git reset --soft HEAD^

# 直前のコミットを完全に取り消し（変更も破棄）
git reset --hard HEAD^

# 特定のコミットまで戻る（変更は保持）
git reset --soft <コミットハッシュ>

# 特定のコミットまで完全に戻る（変更も破棄）
git reset --hard <コミットハッシュ>
```

### 10.2 プッシュ済みのコミットを修正する場合
```
# 履歴を書き換えた後に強制プッシュ（注意：チーム開発では要相談）
git push --force-with-lease
```

### 10.3 コミット履歴が複雑になった場合
```
# 履歴を単純化して表示
git log --oneline --graph --decorate

# コミットをグループ化して表示
git shortlog -sn

# 特定ファイルのコミット履歴を表示
git log --follow -- <ファイル名>
```

### 10.4 コンフリクトの解決
```
# コンフリクトの確認
git status

# マージツールを使用してコンフリクトを解決
git mergetool

# コンフリクト解決後のコミット
git commit
```

### 10.5 一時的に変更を退避
```
# 作業中の変更を一時保存
git stash

# 保存した変更を確認
git stash list

# 保存した変更を復元（スタックから削除）
git stash pop

# 保存した変更を復元（スタックに保持）
git stash apply
```

---

## 11. 補足：GitとCIツールの統合事例

### 11.1 GitHub
- Semantic Release: コミットメッセージからバージョンを自動決定
- Danger: PRの自動レビュー
- CodeClimate: コード品質の自動チェック

### 11.2 GitLab
- GitLab CI: パイプラインの自動実行
- GitLab Pages: ドキュメントの自動生成
- Auto DevOps: コミットからデプロイまでの自動化

### 11.3 Bitbucket
- Bitbucket Pipelines: コミットごとのCI/CD
- Code Insights: コード品質レポート
- Jira連携: コミットメッセージからJiraチケット更新

---

このチートシートが実務のGit運用の参考になれば幸いです。チームでの開発では、コミットルールを明文化し共有することで、より効率的な開発とコードレビューが可能になります。