0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

チュートリアル : 一人で複数ユーザーを演じてチーム開発を体験する

0
Last updated at Posted at 2025-11-16

Git実践チュートリアル - 一人で複数ユーザーを演じてチーム開発を体験する

(トップページはこちら) - (Gitで始める効率的な開発ワークフロー)

目次

  1. はじめに
  2. 前提条件
  3. 環境構築
  4. シナリオ概要
  5. Phase 1: プロジェクトの初期化(徳川家康)
  6. Phase 2: 並行開発の開始
  7. Phase 3: 最初のmerge(織田信長)
  8. Phase 4: conflictの発生と解決
  9. Phase 5: conflictの解決
  10. Phase 6: よくあるトラブルと対処
  11. Phase 7: 高度なシナリオ
  12. Phase 8: チーム全体での統合
  13. Phase 9: レビューと振り返り
  14. Phase 10: さらなる学習
  15. よくあるエラーメッセージと対処法
  16. まとめ
  17. 付録: 緊急時のコマンド
  18. チュートリアル後のクリーンアップ

1. はじめに

Gitの真の便利さは、チーム開発で初めて実感できます。しかし、実際にチームを組んで練習するのは難しいものです。

このチュートリアルでは、一人で複数のユーザーを演じることで、以下を体験できます:

  • 並行開発とブランチ戦略
  • conflict(競合)の発生と解決
  • コードレビューとMerge Request
  • よくあるトラブルとその対処法

所要時間: 約2-3時間

2. 前提条件

  • Gitがインストールされていること
  • GitLab.comのアカウント(無料)
  • ターミナル(コマンドライン)の基本操作ができること

3. 環境構築

3.1. ターミナル管理の概要

このチュートリアルでは、3つのターミナルウィンドウを使い分けます。

ポイント: 各ターミナルは独立した開発者を表します。切り替えながら作業することで、チーム開発を体験できます。

3.2. 練習用ディレクトリの準備

# 練習用のルートディレクトリを作成
mkdir ~/git-practice
cd ~/git-practice

# 3人の開発者用ディレクトリを作成
mkdir tokugawa oda hideyoshi

3.3. ディレクトリ構成

~/git-practice/
├── tokugawa/    # 徳川家康(プロジェクトリーダー)
├── oda/         # 織田信長(バックエンド担当)
└── hideyoshi/   # 豊臣秀吉(フロントエンド担当)

補足: それぞれのディレクトリが、異なる開発者のローカル環境を表します。

3.4. GitLabでリモートリポジトリの準備

GitLab.comにログインして、新しいプロジェクトを作成します。

プロジェクト設定:

  • プロジェクト名: team-task-manager
  • 説明: チーム開発練習用のタスク管理アプリ
  • 可視性レベル: Public

重要: GitLab.comでは、Publicプロジェクトの場合、ユーザー数が無制限です。このチュートリアルのように複数のユーザーで開発を体験する場合に便利です。

プロジェクト作成後、リポジトリURLをメモしておきます。

例: https://gitlab.com/your-username/team-task-manager.git

注意: your-usernameの部分は、あなたのGitLabユーザー名に置き換えてください。以降のコマンドでも同様です。

4. シナリオ概要

3人のチームでタスク管理アプリを開発します。

4.1. 登場人物

  • 徳川家康 - プロジェクトリーダー。リポジトリを初期化し、全体の方針を決定します
  • 織田信長 - バックエンド開発者。API機能を実装します
  • 豊臣秀吉 - フロントエンド開発者。UI機能を実装します

5. Phase 1: プロジェクトの初期化(徳川家康)

⏱️ 所要時間:約15分


👤 操作者:徳川家康(プロジェクトリーダー)
📁 ディレクトリ:~/git-practice/tokugawa
🖥️ ターミナル:1番目

5.1. 徳川家康として作業開始

cd ~/git-practice/tokugawa

# Gitの設定
# --globalを使うと、システム全体でこの設定が有効になります
git config --global user.name "徳川家康"
git config --global user.email "tokugawa@example.com"

# リモートリポジトリをclone
# your-usernameを自分のGitLabユーザー名に置き換えてください
git clone https://gitlab.com/your-username/team-task-manager.git
cd team-task-manager

# このディレクトリだけで設定を上書きしたい場合(オプション)
# --globalなしで実行すると、このリポジトリ専用の設定になります
git config user.name "徳川家康"
git config user.email "tokugawa@example.com"

# 設定を確認
git config user.name
git config user.email

補足:

  • git config --global はシステム全体の設定
  • git config(--globalなし)はリポジトリ専用の設定
  • リポジトリ専用の設定は、グローバル設定を上書きします

5.2. プロジェクトの基本構造を作成

# READMEファイルを作成
cat > README.md << 'EOF'
# Team Task Manager

チーム向けタスク管理アプリケーション

## 機能

- タスクの作成・編集・削除
- タスクの割り当て
- 進捗の可視化

## 開発メンバー

- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)
- 豊臣秀吉(フロントエンド)
EOF

# 基本的なディレクトリ構造を作成
mkdir -p src/{backend,frontend}
mkdir -p docs

# .gitignoreファイルを作成
cat > .gitignore << 'EOF'
# OS
.DS_Store
Thumbs.db

# Editor
.vscode/
.idea/
*.swp

# Dependencies
node_modules/
venv/
__pycache__/

# Build
dist/
build/
*.pyc
EOF

# 初回commit
git add .
git commit -m "chore: プロジェクト初期構造を作成

- README.mdを追加
- src/ディレクトリ構造を作成
- .gitignoreを設定"

# リモートにpush
git push -u origin main

ワークフロー図:

5.3. 開発ガイドラインを作成

# 開発ガイドライン
cat > docs/DEVELOPMENT.md << 'EOF'
# 開発ガイドライン

## ブランチ戦略

- `main` - 本番環境のコード(常に動作する状態)
- `develop` - 開発の主軸
- `feature/*` - 機能開発用
- `bugfix/*` - バグ修正用
- `hotfix/*` - 緊急修正用

## commitメッセージ規約

<type>: <subject>

<body>

<footer>

### Type
- `feat`: 新機能
- `fix`: バグ修正
- `docs`: ドキュメント
- `style`: フォーマット
- `refactor`: リファクタリング
- `test`: テスト追加
- `chore`: ビルド・設定変更

## ワークフロー

1. mainから最新を取得
2. feature/*ブランチを作成
3. 実装とcommit
4. リモートにpush
5. Merge Requestを作成
6. レビュー・修正
7. mainにmerge
EOF

git add docs/DEVELOPMENT.md
git commit -m "docs: 開発ガイドラインを追加"
git push

6. Phase 2: 並行開発の開始

⏱️ 所要時間:約30分

6.1. 織田信長の環境準備


👤 操作者:織田信長(バックエンド担当)
📁 ディレクトリ:~/git-practice/oda
🖥️ ターミナル:2番目(新規)

新しいターミナルウィンドウまたはタブを開きます。

重要: 徳川家康のターミナルはそのまま残しておいてください。別のターミナルで織田信長として作業します。

cd ~/git-practice/oda

# 織田信長として設定
git config --global user.name "織田信長"
git config --global user.email "oda@example.com"

# リポジトリをclone
# your-usernameを自分のGitLabユーザー名に置き換えてください
git clone https://gitlab.com/your-username/team-task-manager.git
cd team-task-manager

# このリポジトリ専用の設定(オプション)
git config user.name "織田信長"
git config user.email "oda@example.com"

# ブランチ確認
git branch -a

6.2. 織田信長: バックエンドAPI機能を実装

# feature/apiブランチを作成
git checkout -b feature/api

# APIファイルを作成
cat > src/backend/api.py << 'EOF'
"""
タスク管理API
"""

class TaskManager:
    def __init__(self):
        self.tasks = []
    
    def create_task(self, title, description, assignee):
        """新しいタスクを作成します"""
        task = {
            'id': len(self.tasks) + 1,
            'title': title,
            'description': description,
            'assignee': assignee,
            'status': 'open'
        }
        self.tasks.append(task)
        return task
    
    def get_tasks(self):
        """すべてのタスクを取得します"""
        return self.tasks
    
    def update_task_status(self, task_id, status):
        """タスクのステータスを更新します"""
        for task in self.tasks:
            if task['id'] == task_id:
                task['status'] = status
                return task
        return None
EOF

# commit
git add src/backend/api.py
git commit -m "feat: タスク管理APIの基本機能を実装

- TaskManagerクラスを作成
- create_task()メソッドを実装
- get_tasks()メソッドを実装
- update_task_status()メソッドを実装"

# リモートにpush
git push -u origin feature/api

6.3. 豊臣秀吉の環境準備


👤 操作者:豊臣秀吉(フロントエンド担当)
📁 ディレクトリ:~/git-practice/hideyoshi
🖥️ ターミナル:3番目(新規)

さらに別のターミナルウィンドウまたはタブを開きます。

これで3つのターミナルが開いている状態です:

  1. 徳川家康のターミナル(~/git-practice/tokugawa/team-task-manager)
  2. 織田信長のターミナル(~/git-practice/oda/team-task-manager)
  3. 豊臣秀吉のターミナル(これから設定)
cd ~/git-practice/hideyoshi

# 豊臣秀吉として設定
git config --global user.name "豊臣秀吉"
git config --global user.email "hideyoshi@example.com"

# リポジトリをclone
# your-usernameを自分のGitLabユーザー名に置き換えてください
git clone https://gitlab.com/your-username/team-task-manager.git
cd team-task-manager

# このリポジトリ専用の設定(オプション)
git config user.name "豊臣秀吉"
git config user.email "hideyoshi@example.com"

6.4. 豊臣秀吉: フロントエンドUI機能を実装

# feature/uiブランチを作成
git checkout -b feature/ui

# UIファイルを作成
cat > src/frontend/app.js << 'EOF'
/**
 * タスク管理アプリ - フロントエンド
 */

class TaskUI {
    constructor() {
        this.tasks = [];
    }
    
    renderTaskList() {
        const taskList = document.getElementById('task-list');
        taskList.innerHTML = '';
        
        this.tasks.forEach(task => {
            const taskElement = this.createTaskElement(task);
            taskList.appendChild(taskElement);
        });
    }
    
    createTaskElement(task) {
        const div = document.createElement('div');
        div.className = 'task-item';
        div.innerHTML = `
            <h3>${task.title}</h3>
            <p>${task.description}</p>
            <span class="assignee">担当: ${task.assignee}</span>
            <span class="status">${task.status}</span>
        `;
        return div;
    }
    
    addTask(title, description, assignee) {
        const task = {
            id: this.tasks.length + 1,
            title,
            description,
            assignee,
            status: 'open'
        };
        this.tasks.push(task);
        this.renderTaskList();
    }
}
EOF

cat > src/frontend/index.html << 'EOF'
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Team Task Manager</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>Team Task Manager</h1>
        <div id="task-list"></div>
    </div>
    <script src="app.js"></script>
</body>
</html>
EOF

# commit
git add src/frontend/
git commit -m "feat: タスク表示UIを実装

- TaskUIクラスを作成
- renderTaskList()メソッドを実装
- createTaskElement()メソッドを実装
- 基本的なHTMLテンプレートを追加"

# リモートにpush
git push -u origin feature/ui

6.5. 現在のブランチ状態

説明:

  • mainブランチから2つのfeatureブランチが分岐
  • 織田信長と豊臣秀吉が並行して作業中

7. Phase 3: 最初のmerge(織田信長)

⏱️ 所要時間:約15分


👤 操作者:織田信長(バックエンド担当)
🖥️ ターミナル:2番目に切り替え

織田信長のターミナルに切り替えます。

7.1. 織田信長: テストコードを追加

cd ~/git-practice/oda/team-task-manager

# 現在feature/apiブランチにいることを確認
git branch

# テストファイルを追加
cat > src/backend/test_api.py << 'EOF'
"""
APIのテストコード
"""
import unittest
from api import TaskManager

class TestTaskManager(unittest.TestCase):
    def setUp(self):
        self.manager = TaskManager()
    
    def test_create_task(self):
        task = self.manager.create_task(
            "テストタスク",
            "これはテストです",
            "織田信長"
        )
        self.assertEqual(task['title'], "テストタスク")
        self.assertEqual(task['status'], "open")
    
    def test_get_tasks(self):
        self.manager.create_task("タスク1", "説明1", "徳川家康")
        self.manager.create_task("タスク2", "説明2", "織田信長")
        tasks = self.manager.get_tasks()
        self.assertEqual(len(tasks), 2)

if __name__ == '__main__':
    unittest.main()
EOF

git add src/backend/test_api.py
git commit -m "test: TaskManagerのユニットテストを追加"
git push

7.2. GitLabでMerge Requestを作成

GitLabのWebインターフェースで操作します。

GitLabでは、Merge Requestを作成する方法が2つあります:

方法1: Merge Requestのみを作成(シンプル)
方法2: Issueを作成してからMerge Requestを作成(推奨)

7.2.1. 方法1: Merge Requestのみを作成

小規模な変更やシンプルな機能追加に適しています。

手順:

  1. GitLabにログインして、team-task-managerプロジェクトを開きます
  2. 左サイドバーの「Merge requests」をクリック
  3. 右上の「New merge request」ボタンをクリック
  4. Source branchを選択:feature/api
  5. Target branchを選択:main
  6. 「Compare branches and continue」ボタンをクリック
  7. 以下の情報を入力します:

Title:

feat: タスク管理APIの実装

Description:

## 概要
タスク管理のバックエンドAPIを実装しました。

## 変更内容
- TaskManagerクラスの実装
- タスクの作成・取得・更新機能
- ユニットテストの追加

## テスト
- ユニットテストが通ること
- タスクの作成が正常に動作すること
- タスクの取得が正常に動作すること

## レビュー依頼
@徳川家康
  1. 「Assignees」で徳川家康(自分)を選択(オプション)
  2. 「Create merge request」ボタンをクリック

補足: Merge Requestが作成されると、URLが発行されます(例:https://gitlab.com/your-username/team-task-manager/-/merge_requests/1)。このURLを開いてレビューします。

7.2.2. 方法2: Issueを作成してからMerge Requestを作成(推奨)

大規模な機能追加やチーム開発に適しています。Issueで要件を明確にし、進捗を追跡できます。

手順:

ステップ1: Issueを作成

  1. GitLabにログインして、team-task-managerプロジェクトを開きます
  2. 左サイドバーの「Issues」をクリック
  3. 右上の「New issue」ボタンをクリック
  4. 以下の情報を入力します:

Title:

タスク管理APIの実装

Description:

## 目的
チームでタスクを管理するためのバックエンドAPIを実装します。

## 要件
- [ ] TaskManagerクラスの作成
- [ ] タスク作成機能(create_task)
- [ ] タスク取得機能(get_tasks)
- [ ] タスク更新機能(update_task_status)
- [ ] ユニットテストの実装

## 技術仕様
- 言語: Python
- データ構造: インメモリのリスト
- テスト: unittest

## 期待される成果
タスクの基本的なCRUD操作が可能になること

## 担当者
@織田信長

## 見積もり
2日
  1. 「Labels」でラベルを選択(例:feature, backend)
  2. 「Assignees」で織田信長(自分)を選択
  3. 「Milestone」で該当するマイルストーンを選択(オプション)
  4. 「Create issue」ボタンをクリック

ステップ2: Issueに紐づくMerge Requestを作成

  1. 作成したIssueのページを開きます
  2. 右サイドバーの「Create merge request」ボタンをクリック

または、手動で紐付ける場合:

  1. 左サイドバーの「Merge requests」をクリック
  2. 右上の「New merge request」ボタンをクリック
  3. Source branchを選択:feature/api
  4. Target branchを選択:main
  5. 「Compare branches and continue」ボタンをクリック
  6. 以下の情報を入力します:

Title:

feat: タスク管理APIの実装

Description:

Closes #1

## 概要
タスク管理のバックエンドAPIを実装しました。

## 変更内容
- TaskManagerクラスの実装
- タスクの作成・取得・更新機能
- ユニットテストの追加

## テスト
- ユニットテストが通ること
- タスクの作成が正常に動作すること
- タスクの取得が正常に動作すること

## レビュー依頼
@徳川家康

重要: Closes #1 という記述により、Merge RequestがmergeされるとIssue #1が自動的にクローズされます。

  1. 「Assignees」で徳川家康(自分)を選択(オプション)
  2. 「Create merge request」ボタンをクリック

7.2.3. 2つの方法の比較

観点 方法1: MRのみ 方法2: Issue + MR
適した場面 小規模な変更、緊急修正 大規模な機能開発、計画的な開発
メリット 素早く作成できる 要件が明確、進捗追跡が容易
デメリット 要件や背景が不明確になりやすい 手順が多い
追跡性 MRのみ IssueとMRで2段階の追跡
議論の場 MRのコメント欄 Issue(要件)とMR(実装)で分離
推奨ケース バグ修正、typo修正、ドキュメント更新 新機能、リファクタリング、複雑な変更

7.2.4. IssueとMerge Requestを紐づけるキーワード

Merge RequestのDescriptionに以下のキーワードを使うと、自動的にIssueを操作できます:

Issueをクローズ:

  • Closes #123
  • Fixes #123
  • Resolves #123

Issueに関連付け(クローズしない):

  • Related to #123
  • Part of #123

複数のIssueを一度にクローズ:

  • Closes #123, #456, #789

例:

Closes #42
Related to #38

## 概要
ユーザー認証機能を実装しました。

このチュートリアルでは、シンプルさを優先して方法1を使用しますが、実際のプロジェクトでは方法2を推奨します。


👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

7.3. 徳川家康: Merge Requestをレビュー

徳川家康のターミナルに切り替えます。

cd ~/git-practice/tokugawa/team-task-manager

# リモートの最新情報を取得
git fetch origin

# 織田信長のブランチを確認
git checkout feature/api
git pull origin feature/api

# コードレビュー(実際にファイルを確認)
cat src/backend/api.py
cat src/backend/test_api.py

# テストを実行
cd src/backend
python test_api.py
cd ../..

GitLabでコメントを追加:

手順:

  1. Merge RequestのページのChangesタブをクリック
  2. コードの該当行にマウスを置くと、吹き出しアイコンが表示されます
  3. クリックしてコメントを入力:
コードの実装、よくできています。いくつか改善提案があります:

1. `create_task`でIDの採番ロジックが重複する可能性があります
2. エラーハンドリングを追加したほうが良いです
3. Docstringが充実していて素晴らしいです

軽微な修正なので、これで承認します。
  1. 「Start a review」または「Add comment now」をクリック
  2. Overviewタブに戻り、「Approve」ボタンをクリック
  3. 「Merge」ボタンをクリックして統合を完了します

補足: Merge後、GitLabは自動的にfeature/apiブランチを削除するか確認します。「Delete source branch」にチェックを入れると、リモートのブランチが削除されます。


👤 操作者:織田信長(バックエンド担当)
🖥️ ターミナル:2番目に切り替え

7.4. 織田信長: ローカルを更新

織田信長のターミナルに戻ります。

cd ~/git-practice/oda/team-task-manager

# mainブランチに戻る
git checkout main

# リモートから最新を取得
git pull origin main

# feature/apiブランチは不要なので削除
git branch -d feature/api

# 確認
git log --oneline --graph

Merge Requestのフロー:

8. Phase 4: conflictの発生と解決

⏱️ 所要時間:約20分


👤 操作者:豊臣秀吉(フロントエンド担当)
🖥️ ターミナル:3番目に切り替え

豊臣秀吉のターミナルに切り替えます。

8.1. 豊臣秀吉: UIを完成させる

cd ~/git-practice/hideyoshi/team-task-manager

# feature/uiブランチにいることを確認
git branch

# スタイルシートを追加
cat > src/frontend/style.css << 'EOF'
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f5f5f5;
    padding: 20px;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    background-color: white;
    padding: 30px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

h1 {
    color: #333;
    margin-bottom: 30px;
    text-align: center;
}

.task-item {
    border: 1px solid #ddd;
    padding: 15px;
    margin-bottom: 10px;
    border-radius: 4px;
    transition: box-shadow 0.3s;
}

.task-item:hover {
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}

.task-item h3 {
    color: #2c3e50;
    margin-bottom: 8px;
}

.task-item p {
    color: #666;
    margin-bottom: 10px;
}

.assignee {
    display: inline-block;
    background-color: #3498db;
    color: white;
    padding: 4px 8px;
    border-radius: 3px;
    font-size: 12px;
    margin-right: 8px;
}

.status {
    display: inline-block;
    background-color: #2ecc71;
    color: white;
    padding: 4px 8px;
    border-radius: 3px;
    font-size: 12px;
}
EOF

git add src/frontend/style.css
git commit -m "style: タスク表示のスタイルシートを追加"
git push

8.2. 豊臣秀吉: mainブランチの更新を取り込もうとする

# mainの最新を取得
git fetch origin

# mainを確認すると、織田信長の変更がmergeされている
git log origin/main --oneline

# feature/uiにmainの変更を取り込む(rebase)
git rebase origin/main

👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

8.3. 徳川家康: 同時にREADMEを更新(conflictの種を撒く)

徳川家康のターミナルに切り替えます。

cd ~/git-practice/tokugawa/team-task-manager

# mainブランチで作業
git checkout main
git pull origin main

# READMEを更新
cat > README.md << 'EOF'
# Team Task Manager

チーム向けタスク管理アプリケーション

## 機能

- タスクの作成・編集・削除
- タスクの割り当て
- 進捗の可視化
- バックエンドAPI実装済み

## 技術スタック

- Backend: Python
- Frontend: JavaScript (Vanilla)
- Version Control: Git / GitLab

## 開発メンバー

- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)- API実装完了
- 豊臣秀吉(フロントエンド)- 開発中

## セットアップ

```bash
# リポジトリをclone
git clone https://gitlab.com/your-username/team-task-manager.git

# バックエンドのテスト実行
cd src/backend
python test_api.py

EOF

git add README.md
git commit -m "docs: READMEを更新

  • 完了した機能にチェックマークを追加
  • 技術スタックセクションを追加
  • セットアップ手順を追加"

git push origin main


---
**👤 操作者:豊臣秀吉(フロントエンド担当)**  
**🖥️ ターミナル:3番目に切り替え**
---

### 8.4. 豊臣秀吉: Merge Requestを作成しようとする

**豊臣秀吉のターミナルに戻ります。**

```bash
cd ~/git-practice/hideyoshi/team-task-manager

# feature/uiブランチから作業
git checkout feature/ui

# READMEも更新してしまう(conflictの原因)
cat >> README.md << 'EOF'

## UI機能

- レスポンシブデザイン
- モダンなスタイリング
- インタラクティブなタスク表示
EOF

git add README.md
git commit -m "docs: UI機能の説明をREADMEに追加"
git push

GitLabでMerge Requestを作成すると...

画面の表示:

⚠️ このMerge Requestにはconflictがあります

以下のファイルにconflictがあります:
- README.md

conflictを解決してください。

選択肢:

  1. Resolve conflicts: GitLabのWeb UIで直接解決
  2. Resolve locally: ローカルで解決(推奨)

このチュートリアルでは、ローカルで解決する方法を学びます。

8.5. conflictの図解

説明: 両方のブランチでREADME.mdを変更したため、conflictが発生しています。

9. Phase 5: conflictの解決

⏱️ 所要時間:約15分


👤 操作者:豊臣秀吉(フロントエンド担当)
🖥️ ターミナル:3番目(継続)

豊臣秀吉のターミナルで作業を続けます。

9.1. 豊臣秀吉: conflictを解決する

cd ~/git-practice/hideyoshi/team-task-manager

# 最新のmainを取得
git fetch origin
git checkout feature/ui

# mainブランチをmergeしてconflictを表面化させる
git merge origin/main

# conflict発生
# Auto-merging README.md
# CONFLICT (content): Merge conflict in README.md
# Automatic merge failed; fix conflicts and then commit the result.

# conflictしているファイルを確認
git status
# On branch feature/ui
# You have unmerged paths.
#   (fix conflicts and run "git commit")
# 
# Unmerged paths:
#   (use "git add <file>..." to mark resolution)
#         both modified:   README.md

# ファイルを開いて確認
cat README.md

README.mdには以下のようなconflictマーカーが表示されます:

# Team Task Manager

チーム向けタスク管理アプリケーション

## 機能

<<<<<<< HEAD
- タスクの作成・編集・削除
- タスクの割り当て
- 進捗の可視化

## 開発メンバー

- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)
- 豊臣秀吉(フロントエンド)

## UI機能

- レスポンシブデザイン
- モダンなスタイリング
- インタラクティブなタスク表示
=======
- タスクの作成・編集・削除
- タスクの割り当て
- 進捗の可視化
- バックエンドAPI実装済み

## 技術スタック

- Backend: Python
- Frontend: JavaScript (Vanilla)
- Version Control: Git / GitLab

## 開発メンバー

- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)- API実装完了
- 豊臣秀吉(フロントエンド)- 開発中

## セットアップ

```bash
# リポジトリをclone
git clone https://gitlab.com/your-username/team-task-manager.git

# バックエンドのテスト実行
cd src/backend
python test_api.py

origin/main


### 9.2. conflictマーカーの説明

<<<<<<< HEAD
あなたの変更(現在のブランチ)

相手の変更(mergeしようとしているブランチ)

origin/main


**重要:** これらのマーカーはGitが自動的に挿入するものです。正しく統合した後、マーカーを必ず削除してください。

### 9.3. 正しく統合する

エディタで`README.md`を編集し、両方の良いところを取ります:

```markdown
# Team Task Manager

チーム向けタスク管理アプリケーション

## 機能

- タスクの作成・編集・削除
- タスクの割り当て
- 進捗の可視化
- バックエンドAPI実装済み
- フロントエンドUI(開発中)

## 技術スタック

- Backend: Python
- Frontend: JavaScript (Vanilla)
- Version Control: Git / GitLab

## 開発メンバー

- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)- API実装完了
- 豊臣秀吉(フロントエンド)- UI実装中

## セットアップ

```bash
# リポジトリをclone
git clone https://gitlab.com/your-username/team-task-manager.git

# バックエンドのテスト実行
cd src/backend
python test_api.py

UI機能

  • レスポンシブデザイン
  • モダンなスタイリング
  • インタラクティブなタスク表示

conflictマーカー(`<<<<<<<`, `=======`, `>>>>>>>`)をすべて削除します。

### 9.4. conflict解決のcommit

```bash
# 解決したファイルをstaging
git add README.md

# statusを確認
git status
# On branch feature/ui
# All conflicts fixed but you are still merging.
#   (use "git commit" to conclude merge)

# mergeのcommitを完了
git commit -m "merge: origin/mainをfeature/uiにmergeしてconflictを解決

README.mdのconflictを解決:
- 徳川家康の技術スタックとセットアップ情報を保持
- 豊臣秀吉のUI機能説明を追加
- 開発状況を最新に更新"

# リモートにpush
git push origin feature/ui

9.5. conflict解決フロー


👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

9.6. 徳川家康: 豊臣秀吉のMerge Requestを確認

徳川家康のターミナルに切り替えます。

cd ~/git-practice/tokugawa/team-task-manager

# 最新情報を取得
git fetch origin

# 豊臣秀吉のブランチを確認
git checkout feature/ui
git pull origin feature/ui

# logを確認
git log --oneline --graph

# mergeのcommitがあることを確認
# READMEの内容を確認
cat README.md

GitLabでMerge Requestを承認してmergeします。

10. Phase 6: よくあるトラブルと対処

⏱️ 所要時間:約30分


👤 操作者:織田信長(バックエンド担当)
🖥️ ターミナル:2番目に切り替え

10.1. トラブル1: 間違えたブランチにcommitした(織田信長)

織田信長のターミナルに切り替えます。

織田信長がmainブランチで直接作業してしまったケースです。

cd ~/git-practice/oda/team-task-manager

# mainブランチで作業してしまう(間違い)
git checkout main
git pull origin main

# 誤ってmainで新機能を実装
cat > src/backend/database.py << 'EOF'
"""
データベース接続モジュール
"""

class Database:
    def __init__(self, db_path):
        self.db_path = db_path
    
    def connect(self):
        """データベースに接続します"""
        print(f"Connecting to {self.db_path}")
        # 実際の接続処理はここに
EOF

git add src/backend/database.py
git commit -m "feat: データベースモジュールを追加"

# あっ、mainブランチでcommitしてしまった
git status
# On branch main
# Your branch is ahead of 'origin/main' by 1 commit.

10.1.1. 対処法: commitを別ブランチに移動

# 正しいブランチを作成(commitは残る)
git branch feature/database

# mainブランチを1つ前に戻す
git reset --hard HEAD~1

# 確認
git log --oneline
# mainブランチには戻っている

# feature/databaseブランチに切り替え
git checkout feature/database
git log --oneline
# commitが存在する

# リモートにpush
git push -u origin feature/database

フロー図:


👤 操作者:豊臣秀吉(フロントエンド担当)
🖥️ ターミナル:3番目に切り替え

10.2. トラブル2: push済みのcommitを取り消したい(豊臣秀吉)

豊臣秀吉のターミナルに切り替えます。

豊臣秀吉がバグのあるコードをpushしてしまったケースです。

cd ~/git-practice/hideyoshi/team-task-manager

git checkout main
git pull origin main

# バグのあるコードをcommit
cat > src/frontend/buggy.js << 'EOF'
// このコードにはバグがあります
function calculateTotal(items) {
    let total = 0;
    for (let i = 0; i <= items.length; i++) {  // <=がバグ
        total += items[i].price;
    }
    return total;
}
EOF

git add src/frontend/buggy.js
git commit -m "feat: 合計金額計算機能を追加"
git push origin main

# push後、バグに気づいた

10.2.1. 対処法: git revertで打ち消しcommitを作成

# 直前のcommitを打ち消す新しいcommitを作成
git revert HEAD

# エディタが開くので、commitメッセージを確認・編集
# デフォルト: Revert "feat: 合計金額計算機能を追加"

# 保存して閉じると、revertのcommitが作成される
git log --oneline
# a1b2c3d (HEAD -> main) Revert "feat: 合計金額計算機能を追加"
# d4e5f6g feat: 合計金額計算機能を追加

# push
git push origin main

# 正しいコードを実装
cat > src/frontend/buggy.js << 'EOF'
// バグを修正
function calculateTotal(items) {
    let total = 0;
    for (let i = 0; i < items.length; i++) {  // <に修正
        total += items[i].price;
    }
    return total;
}
EOF

git add src/frontend/buggy.js
git commit -m "fix: 合計金額計算のバグを修正

配列の範囲外アクセスを修正(<=を<に変更)"
git push origin main

10.2.2. resetとrevertの違い

git reset(履歴を削除)

git revert(打ち消しcommitを追加)

比較表:

コマンド 用途 安全性 push後の使用
git reset 履歴を削除 危険 使用不可
git revert 打ち消しcommit作成 安全 使用可能

👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

10.3. トラブル3: 大きなファイルをcommitしてしまった(徳川家康)

徳川家康のターミナルに切り替えます。

cd ~/git-practice/tokugawa/team-task-manager

# 大きなファイルを誤ってcommit
dd if=/dev/zero of=large-file.bin bs=1M count=100  # 100MBのファイル

git add large-file.bin
git commit -m "feat: データファイルを追加"

# pushしようとするとエラー
git push origin main
# remote: error: File large-file.bin is 104.86 MB; this exceeds GitLab's file size limit of 100 MB

10.3.1. 対処法: commitからファイルを削除

# 直前のcommitを取り消す(ファイルは残る)
git reset --soft HEAD~1

# ファイルをstagingから外す
git reset HEAD large-file.bin

# .gitignoreに追加
echo "large-file.bin" >> .gitignore

# 正しくcommit
git add .gitignore
git commit -m "chore: .gitignoreに大きなファイルを追加"
git push origin main

# 大きなファイルは別の方法で管理
# Git LFSを使用するか、外部ストレージにアップロード

👤 操作者:織田信長(バックエンド担当)
🖥️ ターミナル:2番目に切り替え

10.4. トラブル4: conflictの解決を間違えた(織田信長)

織田信長のターミナルに切り替えます。

cd ~/git-practice/oda/team-task-manager

# conflict解決中に間違えて重要なコードを削除
git merge feature/another-feature

# conflictマーカーを削除する際、誤って機能も削除
# git addしてしまった後に気づく
git status
# On branch main
# All conflicts fixed but you are still merging.

10.4.1. 対処法: mergeを中止してやり直す

# まだcommitしていない場合
git merge --abort

# もう一度merge
git merge feature/another-feature

# 今度は慎重にconflictを解決
# エディタで正しく編集
git add .
git commit

もしcommitしてしまった場合:

# mergeのcommitを取り消す
git reset --hard HEAD~1

# もう一度merge
git merge feature/another-feature
# 正しく解決

👤 操作者:豊臣秀吉(フロントエンド担当)
🖥️ ターミナル:3番目に切り替え

10.5. トラブル5: 作業中に緊急対応が必要(豊臣秀吉)

豊臣秀吉のターミナルに切り替えます。

cd ~/git-practice/hideyoshi/team-task-manager

# feature/new-featureで作業中
git checkout -b feature/new-feature
# ファイルを編集中...

# 突然、本番環境でバグ発見。mainで緊急修正が必要
# でも現在の作業はcommitできる状態ではない

git status
# On branch feature/new-feature
# Changes not staged for commit:
#   modified:   src/frontend/app.js
#   modified:   src/frontend/style.css

10.5.1. 対処法: git stashで作業を一時退避

# 作業を退避
git stash save "新機能実装中(途中)"
# Saved working directory and index state On feature/new-feature: 新機能実装中(途中)

# mainブランチに切り替え
git checkout main
git pull origin main

# 緊急修正用ブランチを作成
git checkout -b hotfix/critical-bug

# バグを修正
# (修正作業)

git add .
git commit -m "fix: 本番環境の致命的なバグを修正"
git push origin hotfix/critical-bug

# Merge Requestを作成してmerge

# 元の作業に戻る
git checkout feature/new-feature

# 退避した作業を復元
git stash pop
# On branch feature/new-feature
# Changes not staged for commit:
#   modified:   src/frontend/app.js
#   modified:   src/frontend/style.css

# 作業を継続

10.5.2. stashの便利なコマンド

# 退避リストを表示
git stash list
# stash@{0}: On feature/new-feature: 新機能実装中(途中)
# stash@{1}: WIP on main: 前回の作業

# 特定の退避内容を確認
git stash show stash@{0}
git stash show -p stash@{0}  # 詳細な差分

# 特定の退避を復元(削除しない)
git stash apply stash@{0}

# 特定の退避を削除
git stash drop stash@{0}

# すべての退避を削除
git stash clear

stashのフロー:

11. Phase 7: 高度なシナリオ

⏱️ 所要時間:約25分


👤 操作者:織田信長(バックエンド担当)
🖥️ ターミナル:2番目に切り替え

11.1. シナリオ1: 複数のcommitを1つにまとめる(rebase)

織田信長のターミナルに切り替えます。

織田信長が細かいcommitを繰り返してしまった場合です。

cd ~/git-practice/oda/team-task-manager

git checkout -b feature/refactor

# 細かいcommitを繰り返す
echo "# 関数1" >> src/backend/utils.py
git add src/backend/utils.py
git commit -m "utils: 関数1を追加"

echo "# 関数2" >> src/backend/utils.py
git add src/backend/utils.py
git commit -m "utils: 関数2を追加"

echo "# 関数3" >> src/backend/utils.py
git add src/backend/utils.py
git commit -m "utils: 関数3を追加"

echo "# テスト追加" >> src/backend/test_utils.py
git add src/backend/test_utils.py
git commit -m "test: utilsのテストを追加"

# 履歴を確認
git log --oneline
# a1b2c3d test: utilsのテストを追加
# d4e5f6g utils: 関数3を追加
# g7h8i9j utils: 関数2を追加
# j9k0l1m utils: 関数1を追加

11.1.1. 対話的rebaseで統合

# 直近4つのcommitを編集
git rebase -i HEAD~4

# エディタが開く
# pick j9k0l1m utils: 関数1を追加
# pick g7h8i9j utils: 関数2を追加
# pick d4e5f6g utils: 関数3を追加
# pick a1b2c3d test: utilsのテストを追加

# 以下のように編集(pickをsquashに変更)
# pick j9k0l1m utils: 関数1を追加
# squash g7h8i9j utils: 関数2を追加
# squash d4e5f6g utils: 関数3を追加
# squash a1b2c3d test: utilsのテストを追加

# 保存して閉じる

# 次のエディタでcommitメッセージを編集
# feat: ユーティリティ関数とテストを追加
# 
# - 関数1: データ変換
# - 関数2: バリデーション
# - 関数3: フォーマッタ
# - ユニットテストを追加

# 保存して閉じる

# 確認
git log --oneline
# m1n2o3p feat: ユーティリティ関数とテストを追加

11.1.2. 対話的rebaseのオプション

pick (p)   = commitをそのまま使用
reword (r) = commitを使用するがメッセージを編集
edit (e)   = commitを使用するが修正のために停止
squash (s) = commitを使用するが前のcommitに統合
fixup (f)  = squashと同じだがcommitメッセージは破棄
drop (d)   = commitを削除

👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

11.2. シナリオ2: 特定のcommitだけを別ブランチに適用(cherry-pick)

徳川家康のターミナルに切り替えます。

徳川家康がdevelopブランチの特定の修正だけをmainに適用したい場合です。

cd ~/git-practice/tokugawa/team-task-manager

# developブランチで作業
git checkout -b develop
git push -u origin develop

# 複数のcommit
echo "機能A" > feature-a.txt
git add feature-a.txt
git commit -m "feat: 機能Aを追加"

echo "バグ修正" > bugfix.txt
git add bugfix.txt
git commit -m "fix: 致命的なバグを修正"  # このcommitだけmainに適用したい

echo "機能B" > feature-b.txt
git add feature-b.txt
git commit -m "feat: 機能Bを追加"

# バグ修正のcommit IDを確認
git log --oneline
# a1b2c3d feat: 機能Bを追加
# d4e5f6g fix: 致命的なバグを修正  ← これをcherry-pick
# g7h8i9j feat: 機能Aを追加

# mainブランチに切り替え
git checkout main

# 特定のcommitだけを適用
git cherry-pick d4e5f6g

# 確認
git log --oneline
# x9y8z7w fix: 致命的なバグを修正  ← cherry-pickされた

git push origin main

cherry-pickの図解:


👤 操作者:豊臣秀吉(フロントエンド担当)
🖥️ ターミナル:3番目に切り替え

11.3. シナリオ3: 歴史の書き換え(filter-branch)

豊臣秀吉のターミナルに切り替えます。

注意: これは非常に危険な操作です。push前のみ実行してください。

機密情報を含むファイルをcommitしてしまった場合です。

cd ~/git-practice/hideyoshi/team-task-manager

# 機密情報を含むファイルをcommit(間違い)
cat > secrets.env << 'EOF'
DATABASE_PASSWORD=super_secret_password
API_KEY=1234567890abcdef
EOF

git add secrets.env
git commit -m "chore: 環境設定を追加"

# さらにいくつかcommit
echo "新機能" > new-feature.txt
git add new-feature.txt
git commit -m "feat: 新機能を追加"

# あっ、secrets.envに機密情報が
# しかも複数commit後に気づいた

11.3.1. 対処法: 履歴から完全に削除

# まだpushしていないことを確認
git log --oneline origin/main..HEAD

# ファイルを履歴から削除
git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch secrets.env" \
  --prune-empty --tag-name-filter cat -- --all

# .gitignoreに追加
echo "secrets.env" >> .gitignore
git add .gitignore
git commit -m "chore: secrets.envを.gitignoreに追加"

# 確認
git log --oneline
# secrets.envのcommitは存在するが、ファイルは削除されている

重要な注意事項:

  • この操作はpush前のみ実行
  • チームメンバーに影響を与える可能性があります
  • より安全な代替案:BFG Repo-Cleanerの使用

12. Phase 8: チーム全体での統合

⏱️ 所要時間:約10分


👤 操作者:徳川家康(プロジェクトリーダー)
🖥️ ターミナル:1番目に切り替え

徳川家康のターミナルに切り替えます。

12.1. 最終的なプロジェクト構成

すべての機能をmainブランチに統合した状態です。

cd ~/git-practice/tokugawa/team-task-manager
git checkout main
git pull origin main

# プロジェクト構造を確認
tree -L 3
team-task-manager/
├── .gitignore
├── README.md
├── docs/
│   └── DEVELOPMENT.md
└── src/
    ├── backend/
    │   ├── api.py
    │   ├── test_api.py
    │   ├── database.py
    │   └── utils.py
    └── frontend/
        ├── index.html
        ├── app.js
        └── style.css

12.2. 最終的なGitグラフ

12.3. tagの作成とリリース

# バージョンtagを作成
git tag -a v1.0.0 -m "初回リリース

機能:
- タスク管理API
- フロントエンドUI
- データベース接続

Contributors:
- 徳川家康(プロジェクトリーダー)
- 織田信長(バックエンド)
- 豊臣秀吉(フロントエンド)"

# tagをリモートにpush
git push origin v1.0.0

# すべてのtagをpush
git push --tags

# tag一覧を確認
git tag
# v0.1
# v0.2
# v0.3
# v1.0.0

# 特定のtagをcheckout
git checkout v1.0.0

13. Phase 9: レビューと振り返り

⏱️ 所要時間:約10分

13.1. 学んだことをまとめます

このチュートリアルで体験したことをまとめます。

13.1.1. 基本的なワークフロー

  • branchの作成と切り替え
  • commitとpush
  • pullとmerge

13.1.2. conflictの解決

  • conflictマーカーの理解
  • 適切な統合方法
  • mergeのcommit作成

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

  • 間違えたブランチへのcommit
  • push済みcommitの取り消し
  • 大きなファイルの処理
  • 作業の一時退避

13.1.4. 高度な操作

  • 対話的rebase
  • cherry-pick
  • 履歴の書き換え

13.2. 実務でのベストプラクティス

13.3. よく使うコマンドまとめ

13.3.1. 日常作業

git status                     # 状態確認
git add .                      # staging
git commit -m "message"        # commit
git push                       # push
git pull                       # pull

13.3.2. branch操作

git branch                     # branch一覧
git checkout -b feature/xxx    # branch作成+切替
git merge feature/xxx          # merge

13.3.3. トラブル対応

git stash                      # 作業退避
git stash pop                  # 作業復元
git reset --soft HEAD~1        # commit取消
git revert HEAD                # 打ち消しcommit
git merge --abort              # merge中止

13.3.4. 情報確認

git log --oneline --graph      # 履歴グラフ
git diff                       # 差分確認
git show コミットID            # commit詳細

13.3.5. リモート操作

git fetch                      # リモート情報取得
git pull --rebase              # rebaseでpull
git push -u origin branch      # 初回push

14. Phase 10: さらなる学習

⏱️ 所要時間:随時

14.1. 次のステップ

14.1.1. 実際のプロジェクトで実践

  • 個人プロジェクトで毎日使います
  • オープンソースプロジェクトに貢献します
  • チーム開発に参加します

14.1.2. 高度な機能を学ぶ

  • Git Hooks(自動化)
  • Submodules(サブプロジェクト管理)
  • Git LFS(大きなファイル管理)
  • Bisect(バグの原因特定)

14.1.3. ツールを活用

  • GitKraken、SourceTree(GUIクライアント)
  • VS Code Git拡張機能
  • GitLabのCI/CD機能

14.2. 参考リソース

14.3. トラブル時のチェックリスト

15. よくあるエラーメッセージと対処法

チュートリアル中に遭遇する可能性のあるエラーと、対応するセクションへのリンクです。

15.1. エラーメッセージ索引

エラーメッセージ 原因 対処セクション
! [rejected] main -> main (fetch first) リモートに新しい変更がある 10.2. トラブル2
CONFLICT (content): Merge conflict in ... 同じファイルの同じ箇所を変更 9. Phase 5: conflictの解決
error: Your local changes to the following files would be overwritten 未保存の変更がある 10.5. トラブル5
fatal: not a git repository Gitリポジトリ外でコマンド実行 ディレクトリを確認
error: pathspec '...' did not match any file(s) 指定したファイルが存在しない ファイル名を確認
fatal: remote origin already exists リモートが既に設定されている git remote -vで確認
error: failed to push some refs pushに失敗 git pullしてから再度push
You have divergent branches ローカルとリモートが分岐 git pull --rebase
error: You have not concluded your merge merge中に別の操作を実行 git merge --abortまたは解決してgit commit

15.2. デバッグの基本手順

16. まとめ

このチュートリアルでは、一人で複数のユーザーを演じることで、Gitのチーム開発を体験しました。

16.1. 重要なポイント

  1. 小さく頻繁にcommit - 変更を細かく記録します
  2. branchを活用 - 機能ごとに独立した開発を行います
  3. conflictを恐れない - 適切に解決できます
  4. push前に確認 - git statusとgit logで確認します
  5. チームと協力 - コードレビューとコミュニケーションを大切にします

16.2. 最も重要なこと

Gitは失敗しても大丈夫です。ほとんどの操作は取り消せます。git reflogを使えば、ほぼすべての状態に戻れます。

実際に手を動かして、失敗を恐れずに試してみてください。それが最高の学習方法です。

17. 付録: 緊急時のコマンド

17.1. とにかく元に戻したい

git reflog                              # 操作履歴を確認
git reset --hard HEAD@{5}               # 5つ前の状態に戻る

17.2. mergeを中止

git merge --abort

17.3. rebaseを中止

git rebase --abort

17.4. 削除したbranchを復元

git reflog
git checkout -b ブランチ名 HEAD@{n}

17.5. 間違えてcommitしたファイルを削除

git rm --cached ファイル名
git commit --amend

17.6. すべてを破棄して最初から

cd ..
rm -rf team-task-manager
git clone https://gitlab.com/your-username/team-task-manager.git

18. チュートリアル後のクリーンアップ

練習用のディレクトリとリポジトリを削除する手順です。

18.1. ローカルディレクトリの削除

# 練習用ディレクトリ全体を削除
cd ~
rm -rf git-practice

# 確認
ls -la | grep git-practice
# 何も表示されなければ削除完了

18.2. GitLabリポジトリの削除(オプション)

GitLabのWebインターフェースで削除できます。

手順:

  1. GitLabにログインして、team-task-managerプロジェクトを開きます
  2. 左サイドバーの「Settings」→「General」をクリック
  3. 「Advanced」セクションを展開
  4. 「Delete project」ボタンをクリック
  5. プロジェクト名を入力して確認
  6. 「Yes, delete project」をクリック

注意: リポジトリを削除すると、全ての履歴とデータが失われます。必要に応じてバックアップを取ってください。

18.3. 環境の復元

# グローバルなGit設定を元に戻す(必要に応じて)
git config --global user.name "あなたの本名"
git config --global user.email "your-email@example.com"

# 設定を確認
git config --global --list

最後に

Gitは強力なツールですが、基本を押さえれば必ず使いこなせます。このチュートリアルで学んだことを実践で活かしてください。

Happy Coding!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?