Git実践チュートリアル - 一人で複数ユーザーを演じてチーム開発を体験する
(トップページはこちら) - (Gitで始める効率的な開発ワークフロー)
目次
- はじめに
- 前提条件
- 環境構築
- シナリオ概要
- Phase 1: プロジェクトの初期化(徳川家康)
- Phase 2: 並行開発の開始
- Phase 3: 最初のmerge(織田信長)
- Phase 4: conflictの発生と解決
- Phase 5: conflictの解決
- Phase 6: よくあるトラブルと対処
- Phase 7: 高度なシナリオ
- Phase 8: チーム全体での統合
- Phase 9: レビューと振り返り
- Phase 10: さらなる学習
- よくあるエラーメッセージと対処法
- まとめ
- 付録: 緊急時のコマンド
- チュートリアル後のクリーンアップ
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つのターミナルが開いている状態です:
- 徳川家康のターミナル(
~/git-practice/tokugawa/team-task-manager) - 織田信長のターミナル(
~/git-practice/oda/team-task-manager) - 豊臣秀吉のターミナル(これから設定)
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のみを作成
小規模な変更やシンプルな機能追加に適しています。
手順:
- GitLabにログインして、
team-task-managerプロジェクトを開きます - 左サイドバーの「Merge requests」をクリック
- 右上の「New merge request」ボタンをクリック
- Source branchを選択:
feature/api - Target branchを選択:
main - 「Compare branches and continue」ボタンをクリック
- 以下の情報を入力します:
Title:
feat: タスク管理APIの実装
Description:
## 概要
タスク管理のバックエンドAPIを実装しました。
## 変更内容
- TaskManagerクラスの実装
- タスクの作成・取得・更新機能
- ユニットテストの追加
## テスト
- ユニットテストが通ること
- タスクの作成が正常に動作すること
- タスクの取得が正常に動作すること
## レビュー依頼
@徳川家康
- 「Assignees」で徳川家康(自分)を選択(オプション)
- 「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を作成
- GitLabにログインして、
team-task-managerプロジェクトを開きます - 左サイドバーの「Issues」をクリック
- 右上の「New issue」ボタンをクリック
- 以下の情報を入力します:
Title:
タスク管理APIの実装
Description:
## 目的
チームでタスクを管理するためのバックエンドAPIを実装します。
## 要件
- [ ] TaskManagerクラスの作成
- [ ] タスク作成機能(create_task)
- [ ] タスク取得機能(get_tasks)
- [ ] タスク更新機能(update_task_status)
- [ ] ユニットテストの実装
## 技術仕様
- 言語: Python
- データ構造: インメモリのリスト
- テスト: unittest
## 期待される成果
タスクの基本的なCRUD操作が可能になること
## 担当者
@織田信長
## 見積もり
2日
- 「Labels」でラベルを選択(例:
feature,backend) - 「Assignees」で織田信長(自分)を選択
- 「Milestone」で該当するマイルストーンを選択(オプション)
- 「Create issue」ボタンをクリック
ステップ2: Issueに紐づくMerge Requestを作成
- 作成したIssueのページを開きます
- 右サイドバーの「Create merge request」ボタンをクリック
または、手動で紐付ける場合:
- 左サイドバーの「Merge requests」をクリック
- 右上の「New merge request」ボタンをクリック
- Source branchを選択:
feature/api - Target branchを選択:
main - 「Compare branches and continue」ボタンをクリック
- 以下の情報を入力します:
Title:
feat: タスク管理APIの実装
Description:
Closes #1
## 概要
タスク管理のバックエンドAPIを実装しました。
## 変更内容
- TaskManagerクラスの実装
- タスクの作成・取得・更新機能
- ユニットテストの追加
## テスト
- ユニットテストが通ること
- タスクの作成が正常に動作すること
- タスクの取得が正常に動作すること
## レビュー依頼
@徳川家康
重要: Closes #1 という記述により、Merge RequestがmergeされるとIssue #1が自動的にクローズされます。
- 「Assignees」で徳川家康(自分)を選択(オプション)
- 「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 #123Fixes #123Resolves #123
Issueに関連付け(クローズしない):
Related to #123Part 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でコメントを追加:
手順:
- Merge RequestのページのChangesタブをクリック
- コードの該当行にマウスを置くと、吹き出しアイコンが表示されます
- クリックしてコメントを入力:
コードの実装、よくできています。いくつか改善提案があります:
1. `create_task`でIDの採番ロジックが重複する可能性があります
2. エラーハンドリングを追加したほうが良いです
3. Docstringが充実していて素晴らしいです
軽微な修正なので、これで承認します。
- 「Start a review」または「Add comment now」をクリック
- Overviewタブに戻り、「Approve」ボタンをクリック
- 「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を解決してください。
選択肢:
- Resolve conflicts: GitLabのWeb UIで直接解決
- 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. 重要なポイント
- 小さく頻繁にcommit - 変更を細かく記録します
- branchを活用 - 機能ごとに独立した開発を行います
- conflictを恐れない - 適切に解決できます
- push前に確認 - git statusとgit logで確認します
- チームと協力 - コードレビューとコミュニケーションを大切にします
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インターフェースで削除できます。
手順:
- GitLabにログインして、
team-task-managerプロジェクトを開きます - 左サイドバーの「Settings」→「General」をクリック
- 「Advanced」セクションを展開
- 「Delete project」ボタンをクリック
- プロジェクト名を入力して確認
- 「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!