# マルチデバイス開発ガイド

> **作成日**: 2025年10月25日
> **バージョン**: 1.0
> **対象**: Dropbox 環境での複数デバイス開発
> **ステータス**: ✅ **実装完了・運用開始**

---

## 📋 概要

このガイドは、Dropbox フォルダ内で Git リポジトリを運用しながら、複数デバイス（デバイスA、デバイスB など）で安全に並行開発を行うための仕組みを定めます。

**主な特徴:**
- ✅ GitHub を真実の情報源（SSOT）として利用
- ✅ Dropbox 同期による Git リポジトリ破損リスク対策
- ✅ デバイス間の操作競合を警告で検知
- ✅ VS Code との統合で自動同期を実現
- ✅ 手動操作なしで main ブランチを自動同期

---

## 🏗️ システムアーキテクチャ

### **階層構造**

```
┌──────────────────────────────────────┐
│  GitHub（真実の情報源・SSOT）         │
│  - main ブランチ（本番・安定版）      │
│  - dev ブランチ（統合・QA）          │
│  - feature/* ブランチ（開発）        │
└──────────────────────────────────────┘
           ↑           ↓
      fetch/pull    commit/push
           ↑           ↓
┌──────────────────────────────────────┐
│  ローカル Git リポジトリ               │
│  - .git/（GitHub から独立管理）      │
│  - 作業ファイル（Dropbox 同期）      │
└──────────────────────────────────────┘
           ↕
┌──────────────────────────────────────┐
│  Dropbox 同期フォルダ                 │
│  - 作業ファイル（常時同期）           │
│  - デバイスロックファイル            │
│  - Git メタデータ（参考用）          │
└──────────────────────────────────────┘
           ↕
     デバイスA     デバイスB
    (Windows)    (Windows/Mac)
```

### **重要な原則**

1. **GitHub は唯一の真実の情報源**
   - ローカル `.git/` は GitHub の状態を常に反映
   - Dropbox の `.git/` には同期を依存しない

2. **Dropbox は作業ファイルのみ同期**
   - コード、ドキュメント、設定ファイルを同期
   - Git の状態（コミット、ブランチ履歴）は GitHub に依存

3. **デバイス間の競合は警告で防止**
   - デバイスロックファイルで作業デバイスを追跡
   - 別デバイス作業中の警告を表示

---

## 🔒 デバイスロック機構

### **ロックファイル位置**

```
.dropbox/
├── .gitkeep                # ディレクトリ管理用
├── DEVICE_LOCK             # 実行時生成：現在の作業デバイス名
└── LAST_GIT_SYNC           # 実行時生成：最後の同期タイムスタンプ
```

### **ロックの動作**

#### **VS Code 起動時（自動実行）**

```bash
scripts/check_device_lock.sh
│
├─ .dropbox/DEVICE_LOCK が存在？
│  ├─ YES: ロック先デバイスを読み込み
│  │  ├─ 現在のデバイス = ロック先？
│  │  │  ├─ YES: ロック有効 → 開発続行
│  │  │  └─ NO: 警告表示 → ユーザー判断
│  │  │      ├─ YES（上書き）: 新デバイスロック設定
│  │  │      └─ NO: 開発中止（安全性優先）
│  │
│  └─ NO: 新規ロック作成 → 開発開始
```

**表示例:**

```
==================================================
🔒 Device Lock Check
==================================================
Device:    DESKTOP-59K19LV
Timestamp: 2025年 10月 25日 土曜日 21:14:25

⚠️  WARNING: Another device has an active lock!

   Locked by: DESKTOP-XXXXX
   Current:   DESKTOP-59K19LV

This typically means:
  • DESKTOP-XXXXX is currently developing
  • Work may be uncommitted on that device
  • Git conflicts could occur if you proceed

Override and take the lock? (y/N):
```

### **ロックの解放**

VS Code 終了前に手動実行：

```bash
# Method 1: VS Code Task
Ctrl+Shift+P → Run Task → "Git: Release Device Lock"

# Method 2: コマンド実行
bash scripts/check_device_lock.sh --release
# または
rm -f .dropbox/DEVICE_LOCK
```

---

## 🔄 自動同期メカニズム

### **同期ポイント**

| タイミング | トリガー | 動作 | 実装 |
|----------|--------|------|------|
| **VS Code 起動** | 自動 | デバイスロック確認 | `check_device_lock.sh` |
| **VS Code 起動** | 自動 | GitHub から main 取得 | `git.autofetch` |
| **dev 切り替え** | 手動 | main を自動 sync | `hooks/post-checkout` |
| **3分ごと** | 自動 | 最新を取得 | `git.autofetchPeriod: 180` |
| **手動トリガー** | ユーザー | 即座に同期実行 | `sync-git-safe.sh` |
| **main マージ** | GitHub | 通知・ログ出力 | `.github/workflows/sync-main.yml` |

### **同期フロー例**

#### **シナリオ1: デバイスA で PR を main にマージ**

```
Timeline:
─────────────────────────────────────────────────

09:00 | デバイスA: dev で開発・コミット
      | $ git push origin dev

09:15 | デバイスA: GitHub で PR 作成
      | PR: dev → main

09:30 | デバイスA: PR をマージ
      | ✅ GitHub main が更新

09:31 | GitHub Actions: sync-main.yml 実行
      | ✅ ログ出力：「main updated」

09:35 | デバイスB: VS Code を起動
      | ✅ git.autofetch で自動 fetch
      | ✅ origin/main が更新されたことを検知

09:38 | デバイスB: 手動でタスク実行
      | > Run Task → "Git: Sync main from GitHub"
      | ✅ Dropbox 同期完了を確認（最大5秒待機）
      | ✅ GitHub から main を pull
      | ✅ ローカル main が最新に更新
```

#### **シナリオ2: dev ブランチに切り替え時**

```
$ git checkout dev

──→ hooks/post-checkout が自動実行
    │
    ├─ 現在のブランチ = dev？
    │  ├─ YES: git fetch origin main:main
    │  │        ✅ main を GitHub から同期
    │  │        （ローカル dev はチェックアウトしたまま）
    │  │
    │  └─ NO: スキップ

✅ 完了：main は常に最新、dev で開発可能
```

---

## 📝 VS Code 統合

### **自動設定**

**`.vscode/settings.json` に追加される設定:**

```json
{
  "git.autofetch": true,
  "git.autofetchPeriod": 180,
  "[git-commit]": {
    "editor.rulers": [50, 72]
  }
}
```

**動作:**
- `git.autofetch: true` → バックグラウンドで自動 fetch
- `git.autofetchPeriod: 180` → 3分ごとに実行

### **VS Code Tasks**

**`.vscode/tasks.json` で定義:**

| Task 名 | トリガー | 実行内容 |
|---------|--------|--------|
| `Git: Check Device Lock` | 起動時（自動） | デバイスロック確認 |
| `Git: Sync main from GitHub` | 手動実行 | 安全な GitHub 同期 |
| `Git: Release Device Lock` | 終了前（手動） | ロック解放 |
| `Git: Install Hooks` | 初回セットアップ | Git Hooks インストール |

**実行方法:**

```
Ctrl+Shift+P → "Run Task" → タスク名を選択
```

---

## 🛡️ Git Hooks

### **post-checkout Hook**

**ファイル**: `hooks/post-checkout`

**動作**: ブランチを dev に切り替えた時、main を自動同期

```bash
# 実行条件
if [ "$(git symbolic-ref --short HEAD)" = "dev" ]; then
  git fetch origin main:main --quiet
fi
```

**利点:**
- 手動操作なしで main を最新に保つ
- Dropbox の同期に依存しない（GitHub から直接取得）

### **pre-commit Hook**

**ファイル**: `hooks/pre-commit`

**動作**:
1. **main ブランチへの直コミット禁止**（保護）
2. **別デバイスのロックを検知・警告**（マルチデバイス安全性）

#### **チェック1：main ブランチ保護**

```bash
current_branch=$(git symbolic-ref --short HEAD)
if [ "$current_branch" = "main" ]; then
  # main への直コミットを拒否
  echo "❌ COMMIT REJECTED: Direct commits to main are forbidden!"
  exit 1
fi
```

**動作:**
- main ブランチでの commit を禁止
- 正しいワークフロー（feature/dev → PR）へ誘導
- 緊急時のみ `git commit --no-verify` でバイパス可能

#### **チェック2：デバイス競合検知**

```bash
# ロックファイルを確認
if [ -f .dropbox/DEVICE_LOCK ]; then
  locked_device=$(cat .dropbox/DEVICE_LOCK)
  if [ "$locked_device" != "$(hostname)" ]; then
    # 別デバイスでロック中
    echo "⚠️  WARNING: Device lock detected!"
    # ユーザー確認を取る
    read -p "Continue with commit? (y/N): "
  fi
fi
```

**利点:**
- main への直接コミットを 100% 防止
- 同時開発による競合を事前に警告
- PR フロー強制による品質向上

---

## 🔧 初回セットアップ

### **ステップ1: Hooks をインストール**

```bash
# 方法A: VS Code Task
Ctrl+Shift+P → "Run Task" → "Git: Install Hooks"

# 方法B: 直接実行
bash scripts/install-hooks.sh
```

**確認:**

```bash
$ ls -la .git/hooks/post-checkout .git/hooks/pre-commit
-rwxr-xr-x post-checkout
-rwxr-xr-x pre-commit
```

### **ステップ2: .vscode/tasks.json を確認**

```bash
# VS Code を開き、.vscode/tasks.json が存在することを確認
ls -la .vscode/tasks.json
```

### **ステップ3: デバイスロックをテスト**

```bash
# 手動実行してテスト
bash scripts/check_device_lock.sh
```

**期待される出力:**

```
==================================================
🔒 Device Lock Check
==================================================
Device:    DESKTOP-59K19LV

🆕 No lock detected - creating new lock
✅ Lock file created: /path/to/.dropbox/DEVICE_LOCK

==================================================
Ready for development ✨
==================================================
```

---

## 📖 実運用フロー

### **デバイスA での開発ステップ**

```bash
# Step 1: VS Code を開く
# ──→ 自動で check_device_lock.sh が実行
# ──→ ロック設定＆GitHub から main を fetch

# Step 2: 開発作業
git checkout -b feature/my-feature dev
# ... コーディング ...
git add .
git commit -m "feat: add new feature"

# Step 3: push して PR を作成
git push origin feature/my-feature
# GitHub で PR 作成：feature/my-feature → dev

# Step 4: PR レビュー・マージ
# デバイスA の GitHub で PR をマージ
# ──→ dev が更新

# Step 5: 次のサイクル準備（dev に PR を出す）
git checkout dev
git pull origin dev
git checkout -b feature/next-feature dev
```

### **デバイスB での開発ステップ**

```bash
# Step 1: VS Code を開く
# ──→ 自動で check_device_lock.sh が実行
# ⚠️ "デバイスA が作業中です" → YES で上書き
# ──→ ロック設定＆GitHub から main を fetch

# Step 2: 開発作業（デバイスA とは異なる機能）
git checkout -b feature/other-feature dev
# ... コーディング ...
git add .
git commit -m "feat: add other feature"

# Step 3: push して PR を作成
git push origin feature/other-feature
# GitHub で PR 作成：feature/other-feature → dev

# Step 4: PR レビュー・マージ
# GitHub で PR をマージ
# ──→ dev が更新

# Step 5: VS Code 終了
# Ctrl+Shift+P → "Run Task" → "Git: Release Device Lock"
# ──→ ロック解放
```

### **main が更新された場合**

```bash
# デバイスB で開発中：

# 自動検知：
# ──→ git.autofetch で main の更新を検知（3分ごと）

# 手動同期：
Ctrl+Shift+P → "Run Task" → "Git: Sync main from GitHub"

# 実行内容：
# 1. Dropbox 同期完了を確認（最大5秒）
# 2. GitHub から main を fetch
# 3. ローカル main を pull
# 4. 開発ブランチに戻る（dev など）
# 5. .dropbox/LAST_GIT_SYNC を更新
```

---

## ⚠️ トラブルシューティング

### **問題1: 「デバイスロックが引っかかって開発できない」**

**原因**: 別デバイスのロックが残っている

**解決策:**

```bash
# Option 1: ロックを強制解放
rm -f .dropbox/DEVICE_LOCK

# Option 2: VS Code Task で解放
Ctrl+Shift+P → "Run Task" → "Git: Release Device Lock"

# Option 3: 別デバイスで明示的に解放
# (別デバイスの VS Code を開き、ロック解放)
```

### **問題2: 「main の同期に失敗した」**

**原因**: ネットワーク接続、Dropbox 同期遅延

**解決策:**

```bash
# 1. ネットワーク接続を確認
ping github.com

# 2. Dropbox フォルダの同期状況を確認
# Dropbox メニュー → 状態を確認

# 3. 手動で同期
git fetch origin
git checkout main
git pull origin main

# 4. それでもダメな場合：スクリプトで詳細を確認
bash scripts/sync-git-safe.sh
```

### **問題3: 「main ブランチへのコミットが拒否された」**

**原因**: pre-commit hook が main への直コミットを防止（保護機能）

**エラーメッセージ:**

```
❌ COMMIT REJECTED: Direct commits to main are forbidden!

The 'main' branch is protected and can only be updated via PR merge.

✅ Correct workflow:
   1. Switch to dev or feature branch:
      $ git checkout dev
      $ git checkout -b feature/my-feature dev

   2. Make your changes and commit:
      $ git add . && git commit -m 'feat: your change'

   3. Push and create a PR:
      $ git push origin feature/my-feature
      $ gh pr create --base dev --head feature/my-feature

🚀 For direct main updates (hotfixes only):
   - Contact the project maintainer
   - Use: git commit --no-verify (⚠️  not recommended)
```

**解決策:**

```bash
# 1. 正しいワークフローに従う（推奨）
git checkout dev
# または
git checkout -b feature/my-feature dev

# 2. feature/dev で変更をコミット
git add . && git commit -m "feat: your change"

# 3. PR を作成
git push origin feature/my-feature
gh pr create --base dev --head feature/my-feature

# 4. 緊急時のみバイパス（非推奨）
git commit --no-verify  # 保護をスキップ（利用避け）
```

### **問題4: 「pre-commit hook の警告が邪魔」**

**原因**: pre-commit hook が他デバイスのロック検出

**動作**: `y` を入力して続行可能

**ロック解放される場合**: 他デバイスが実際に開発中の可能性 → 確認してから続行

---

## 🔐 安全性ガイドライン

### **✅ してはいけないこと**

| 禁止事項 | 理由 | 代替案 |
|---------|------|------|
| **main ブランチへの直コミット** | ❌ hook が禁止（PR 必須） | dev/feature で commit → PR |
| 同時に複数デバイスで直接 push | Git 競合の危険 | PR フロー を使用 |
| `.git/` を手動で編集 | リポジトリ破損 | `git` コマンドを使用 |
| Dropbox ロックを無視して操作 | 他デバイスの上書き | ロック解放を待つ |
| 未コミット状態で VS Code を終了 | 変更ロスの危険 | commit/stash してから終了 |
| `git commit --no-verify` で main に コミット | 保護機能の無効化 | 緊急時のみ（要相談） |

### **✅ すべきこと**

| 推奨事項 | 利点 |
|---------|------|
| 作業前に VS Code を開く | 自動でロック＆同期 |
| 定期的に main に PR を出す | GitHub が唯一の真実の情報源 |
| 終了時にロック解放 | 他デバイスが作業開始可能 |
| 3分ごとの fetch で最新を把握 | 競合を早期に検知 |

---

## 📊 マトリックス：デバイス・ブランチ・アクション

| デバイス | ブランチ | アクション | ロック | 同期 | 結果 |
|---------|---------|----------|-------|------|------|
| A | feature/x | 開発・commit | ✅ | GitHub → fetch | dev に PR |
| A | dev | merge PR | ✅ | dev → pull | main に PR 準備 |
| B | 新規 開始 | VS Code open | ⚠️→✅ | GitHub → fetch | 開発開始可 |
| B | feature/y | 開発・commit | ✅ | GitHub → fetch | dev に PR |
| B | 終了 | Ctrl+C | ❌ | ロック解放 | A が再開可 |
| AB | 同時 | 両方開く | ⚠️ | 警告表示 | 上書きするか判断 |

---

## 🔗 関連ドキュメント

- [ブランチ戦略とCI/CD運用ガイド](./branch_strategy.md) - 3段階開発フロー（feature → dev → main）
- [Git ワークフロー完全ガイド](./git_workflow.md) - コミット・プッシュ・PR の詳細
- [開発者ガイド](./developer_guide.md) - MCP・Claude Code・環境設定
- [AGENTS.md](../../AGENTS.md) - プロジェクト原則・ワークフロー
- [CLAUDE.md](../../CLAUDE.md) - Claude Code + MCP 環境での契約

---

## 📞 質問・問題報告

マルチデバイス開発で問題が発生した場合：

1. **このドキュメントの「トラブルシューティング」を確認**
2. **ロックファイルの状態を確認**: `cat .dropbox/DEVICE_LOCK`
3. **GitHub の状態を確認**: `git fetch origin && git status`
4. **スクリプトを直接実行してログを確認**: `bash scripts/sync-git-safe.sh`

---

**最終更新**: 2025年10月25日
**メンテナー**: Claude Code
**ステータス**: ✅ 本番運用中
