【Git・GitHub操作ガイド】第7章 Git・GitHubチーム開発入門!IssuesとPull Requestの基本を徹底解説!

本記事の目的

「よし、コードが書けた!でも、これをどうやってチームのプロジェクトに反映すればいいんだろう…?」「先輩にレビューをお願いしたいけど、どのファイルを見てもらえばいいか伝えるのが大変…」
一人での開発から、初めてチーム開発に参加したとき、多くの人がこんな壁にぶつかります。

この記事では、GitHubでの共同作業に不可欠なPull Requestワークフローについて、具体的なコマンドを使いながらステップバイステップで解説します。
この記事を読み終える頃には、あなたはGitHubを使ったチーム開発の基本的な流れをマスターし、自信を持って最初の「Pull Request」を送れるようになっています!


対象読者

この記事は、次のような方にオススメです。

  • Gitの基本操作(add, commit, push)は一通りできるが、チーム開発は未経験で、Pull Requestを使った開発フローを学びたい
  • Git/GitHubを学び始めたばかりで、チーム開発の全体像を掴みたい方(ghコマンドは応用として、まずは流れを理解しましょう!)
  • ghコマンドを使って、日々のGitHub操作を効率化したいと考えている方

目次


GitHubチーム開発の全体像(図解)

GitHub上での開発は、以下のようなコミュニケーションの流れで進みます。まずは、大まかな流れをイメージできればOKです。後ほど、詳しくステップバイステップで解説します。

  1. Issues:タスクの掲示板
    「こんなバグがあります」「こんな機能が欲しい」といった、開発のタスクや課題をチケットとして登録する場所です。すべての作業は、ここから始まります。
  2. Branches:作業の個室
    Issueで提起された課題を解決するために、Gitのブランチ機能を使って、mainブランチから分岐した個別の作業環境を作成します。
  3. Pull Requests (PR):変更の提案とレビュー
    ブランチでの作業が完了したら、「この変更をmainブランチに取り込んでください」というリクエストをGitHub上で作成します。他の開発者はこのPR上でコードレビューを行い、品質を高めます。
  4. Tags & Releases:成果の公式発表
    PRがマージされ、mainブランチが更新されたら、特定のバージョンとしてタグを付け、公式な「リリース」として成果物を公開します。
GitHubチーム開発の全体

次の章では、これらの活動を支えるGitとGitHubの機能やコマンドを解説していきます。


gitgh:ローカルとクラウドの相棒

ワークフローではgitghという2つのコマンドが登場します。混乱しないように、役割を整理しておきましょう。

  • git: あなたのPC(ローカル)でコードの変更履歴を記録・管理するツールです。(例: git add, git commit, git switch
  • gh: GitHub(クラウド)上での共同作業をコマンドラインから操作するツールです。(例: gh issue create, gh pr create

イメージとしては、「gitで下書きを書いて保存し、ghでチームに提出・相談する」と考えると分かりやすいでしょう。

それでは、具体的なGitHubチーム開発ワークフローの解説に進みます。


Git/Githubの導入、主要なコマンドについては、以下の記事で詳細に解説していますので、まだ導入やコマンドになれていない方は、ぜひご覧ください。


実践!GitHubチーム開発ワークフロー

それでは、チームで安全かつ効率的に開発を進めるための、最も標準的な手順である「Pull Request (PR) ワークフロー」を解説します。

ワークフローの全体像

これから、あなたが実施するワークフローの全体図になります。

  1. 【任務の受注】: Issueを元に、新しい作業を開始します。
  2. 【自分の作業部屋へ】: mainブランチから、自分専用の作業ブランチを作成します。
  3. 【開発に集中】: 誰にも邪魔されない環境で、コードの変更とコミットを繰り返します。
  4. 【成果の提出】: 作業が終わったら、ローカルの変更をGitHubにプッシュします。
  5. 【提案と相談】: 「この変更、どうでしょうか?」とPull Requestを作成し、チームにレビューを依頼します。
  6. 【フィードバックと修正】: レビューコメントを元に、コードをさらに良くしていきます。
  7. 【承認と統合】: レビューでOKが出たら、変更をmainブランチにマージします。
  8. 【後片付け】: 役目を終えた作業部屋(ブランチ)を掃除します。

この一連のサイクルが、あなたの書いたコードが製品に反映されるまでの道のりです。

あなたが実施するワークフローの全体図

STEP1: Issueを作成して「やること」を明確にする

概要

Issueは、バグ報告、機能要望、質問など、プロジェクトに関するあらゆるタスクを管理するためのチケットシステムです。各Issueには、担当者、ラベル(bug, enhancementなど)、マイルストーン(v1.0リリースなど)を割り当てることができ、タスクを見える化することができます。

利用シーン

  • ユーザーから「ログインできない」というバグ報告を受け、Issueを作成する。
  • 次のバージョンで実装したい新機能について、仕様を検討するためのIssueを立てる。

ghコマンドでの操作例

Issueの作成
# タイトル(-t)と本文(-b)を指定してIssueを作成
gh issue create -t "ログインボタンが反応しない" -b "ユーザー名とパスワードを入力後、ログインボタンをクリックしても画面が遷移しません。"
コマンドの実行:gh issue create

コード実行例:

hogehoge@mac hello-world % gh issue create -t "ログインボタンが反応しない" -b "ユーザー名とパスワードを入力後、ログインボタンをクリックしても画面が遷移しません。"
Creating issue in hogehoge/hello-world
https://github.com/hogehoge/hello-world/issues/1

 ※ 最後の行に発行されたissueのURLが表示されます。このURLの末尾の数字がissue固有の番号になります。削除や参照の際に必要になります。

issueを発行した画面
Issueのクローズ

Pull Requestの説明に Closes #1 のように書けばマージ時に自動でクローズされますが、PRと直接関連しないIssueなどを手動で閉じる際に以下のコマンドを使います。

# Issue番号1にコメントを残してクローズする
gh issue close 1 --comment "対応不要になったためクローズします。"
コマンドの実行:gh issue close

コード実行例:

hogehoge@mac hello-world % gh issue close 1 --comment "対応不要になったためクローズします。"
 Closed issue hogehoge/hello-world#1 (ログインボタンが反応しない)
hogehoge@mac hello-world %
issueをクローズした画面

ここでは、Issue #2 の「ユーザープロフィール機能の追加」というタスクを担当するシナリオで進めます。

シナリオ用 issueの登録

コード実行例:

hogehoge@mac hello-world % gh issue create -t "ユーザープロフィール機能の追加" -b "ユーザープロフィールの機能を追加して、ユーザーの属性情報を追加・編集できるようにします。"

Creating issue in hogehoge/hello-world

https://github.com/hogehoge/hello-world/issues/2
hogehoge@mac hello-world %

STEP2: 作業の開始(ブランチ作成)

まず、最新のコードから作業を始めるため、ローカルのmainブランチを最新の状態に更新します。

# 1. mainブランチに移動
git switch main

# 2. リモートの最新情報を取得してマージ
git pull origin main

次に、今回の作業専用のブランチを作成して、そこへ移動します。ブランチ名は、Issue番号や機能名を含めると分かりやすいです。

# 3. 'feature/2-user-profile' という名前でブランチを作成・移動
git switch -c feature/2-user-profile
シナリオ用 ブランチの作成

コード実行例:

# mainブランチへ切り替え
hogehoge@mac hello-world % git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
hogehoge@mac hello-world 

# mainブランチを最新状態へ
hogehoge@mac hello-world % git pull origin main
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
From github.com:hogehoge/hello-world
 * branch            main       -> FETCH_HEAD
Already up to date.

# 作業用ブランチを作成
hogehoge@mac hello-world % git switch -c feature/2-user-profile
Switched to a new branch 'feature/2-user-profile'
hogehoge@mac hello-world %

STEP3: 開発と記録(変更 & コミット)

ここから、テキストエディタやIDEで、必要なファイルの作成や修正を行います。作業がある程度キリの良いところまで進んだら、コミットして変更を記録します。

# (ファイルを修正...)

# 1. 変更したファイルをステージング
git add .

# 2. 変更内容が分かるメッセージを付けてコミット
git commit -m "feat: ユーザープロフィールの基本レイアウトを作成"

この「変更 → addcommit」のサイクルを、機能が完成するまで繰り返します。

シナリオ用 ユーザープロファイルの追加

コード実行例:

hogehoge@mac hello-world % git status
On branch feature/2-user-profile
nothing to commit, working tree clean
hogehoge@mac hello-world % ls
README.md index.html
hogehoge@mac hello-world % vi index.html 
hogehoge@mac hello-world % git status
On branch feature/2-user-profile
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
hogehoge@mac hello-world % git add index.html 
hogehoge@mac hello-world % git commit -m "feat: ユーザープロフィールの基本レイアウトを作成"
[feature/2-user-profile 816a8f7] feat: ユーザープロフィールの基本レイアウトを作成
 1 file changed, 1 insertion(+), 1 deletion(-)
hogehoge@mac hello-world % git status
On branch feature/2-user-profile
nothing to commit, working tree clean
hogehoge@mac hello-world %

Gitのコミット履歴のいろいろな操作(消去、まとめ、復元など)については、以下の記事で詳細に解説していますので、是非ご覧ください。


STEP4: 共有の準備(リモートへプッシュ)

ローカルでの作業が完了したら、その成果をGitHubのリモートリポジトリに送信(プッシュ)します。これにより、他の人からあなたの作業が見えるようになり、Pull Requestを作成する準備が整います。

# '--set-upstream' または '-u' は、ローカルブランチとリモートブランチを紐付けるオプション(初回のみでOK)
git push --set-upstream origin feature/2-user-profile

git push -u origin feature/2-user-profile

2回目以降のプッシュは git push だけで大丈夫です。
コード実行例:

# いきなりgit pushはできない。(エラーになる)
hogehoge@mac hello-world % git push
fatal: The current branch feature/2-user-profile has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/2-user-profile

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

# ローカルブランチとリモートブランチを紐付ける  
hogehoge@mac hello-world % git push -u origin feature/2-user-profile
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 452 bytes | 452.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote: 
remote: Create a pull request for 'feature/2-user-profile' on GitHub by visiting:
remote:      https://github.com/hogehoge/hello-world/pull/new/feature/2-user-profile
remote: 
To github.com:hogehoge/hello-world.git
 * [new branch]      feature/2-user-profile -> feature/2-user-profile
branch 'feature/2-user-profile' set up to track 'origin/feature/2-user-profile'.
hogehoge@mac hello-world %

STEP5: 提案とレビュー依頼(Pull Request作成)

いよいよ、あなたの変更をチームに提案します。GitHub CLI (gh) を使うのが最も簡単です。

gh pr create

このコマンドを実行すると、対話形式でPRのタイトルや説明文を入力できます。

コード実行例:

# pull requestの作成
hogehoge@mac hello-world % gh pr create

Creating pull request for feature/2-user-profile into main in hogehoge/hello-world

# タイトルを入力、必須、デフォルトでタイトルを提案してくれる
**?** **Title (required)** feat: ユーザープロフィールの基本レイアウトを作成

# nanoエディターで編集
**?** **Body** <Received>

**?** **What's next?**  [Use arrows to move, type to filter]
**> Submit**
  Submit as draft
  Continue in browser
  Add metadata
  Cancel

# Submitを選択
**?** **What's next?** Submit

https://github.com/hogehoge/hello-world/pull/3
hogehoge@mac hello-world %

良いPull Requestの書き方例

レビュアーが変更の意図を素早く理解し、質の高いレビューをするためには、分かりやすい説明が不可欠です。

良いPRを作成するためのポイントは:

  • タイトル: 何をしたかが一目で分かるように。(例: feat: ユーザープロフィール機能を追加
  • 説明文: 「何を」「なぜ」変更したのかを詳しく書きます。関連するIssueをCloses #2のように記述すると、このPRがマージされた時に自動でIssueもクローズされ、非常に便利です。

以下に、このシナリオに沿った例を示します。


タイトル: feat: ユーザープロフィール機能を追加

本文:

Closes #2

## 概要 (What)

ユーザープロフィール画面の基本的なUIコンポーネントを実装しました。
- プロフィール画像表示エリア
- ユーザー名表示エリア
- 自己紹介文表示エリア

## 目的 (Why)

Issue #2 で定義された、ユーザープロフィール機能の第一歩として、まずは画面の骨格を作成する必要がるため。

## 実装内容 (How)

- `src/components/UserProfile.js` を新規作成。
- `src/pages/ProfilePage.js` から上記コンポーネントを呼び出すように変更。
- スタイリングには `styled-components` を使用。

## スクリーンショット

UIの変更を含む場合は、スクリーンショットを貼るとレビューが格段にしやすくなります。

| Before | After |
| :---: | :---: |
| (変更前の画面なし) | ![image](https://example.com/after_screenshot.png) |

## 補足・レビュー依頼

- 今回はUIの骨格のみで、バックエンドとの連携は未実装です。
- コンポーネントの命名規則 (`UserProfile.js`) がプロジェクトの規約に合っているか、特に確認を願いします。

@reviewer-username

STEP6: 品質の向上(レビューと修正)

PRが作成されると、GitHub上でレビュアーがあなたのコードを確認し、コメントを付けてくれます。

「ここの変数名はもっと分かりやすくしよう」「この処理は、もっと効率的な書き方があるよ」といったフィードバックが届きます。

ghコマンドでレビューコメントを確認する

GitHubのWebページを開かなくても、ghコマンドでレビュー状況を素早く確認できます。gh pr viewコマンドを使いましょう。

# PR番号が '3' の場合。--commentsフラグでコメントに焦点を当てる
gh pr view 3 --comments

このコマンドを実行すると、以下のようにPR全体へのコメントや、特定のコード行に対するコメント(インラインコメント)が一覧で表示されます。

コード実行例:

View comments in #3

reviewer-username commented 2 hours ago
--------------------------------
全体的な方針は素晴らしいと思います!
1点、`UserProfile.js` の変数名についてコメントしましたので、修正をお願いします。

--
View comments on diff
src/components/UserProfile.js:12
reviewer-username commented 2 hours ago
--------------------------------
変数名は lowerCamelCase ではなく UpperCamelCase に統一しましょう。

このように、ターミナル上で直接レビュー内容を確認できるため、すぐに修正作業に取り掛かれます。


フィードバックを受けたら、指摘に従ってローカルでコードを修正し、再びコミットしてプッシュします。

# (指摘箇所を修正...)
git add .
git commit -m "fix: レビュー指摘を反映し、変数名を修正"
git push

プッシュすると、その変更は自動的に既存のPRに反映されます。この「レビュー → 修正 → プッシュ」のサイクルを、レビュアーから承認(Approve)がもらえるまで繰り返します。


STEP7: 統合(マージ)

チームメンバーから承認されたら、いよいよあなたのコードをプロジェクトの本体(mainブランチ)に統合します。

# PR番号が '3' の場合
gh pr merge 3 --squash --delete-branch

このコマンドでは、マージ方法として --squash を、後処理として --delete-branch を指定しています。

  • --squash: 作業中の細かなコミット(”fix typo”など)を一つにまとめてからマージし、mainの歴史を綺麗に保ちます。多くのプロジェクトで推奨される方法です。
  • --delete-branch: マージ後、GitHub上のリモートブランチを自動で削除してくれます。

コード実行例:

hogehoge@mac hello-world % gh pr merge 3 --squash --delete-branch
 Squashed and merged pull request hogehoge/hello-world#3 (feat: ユーザープロフィールの基本レイアウトを作成)
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 2 (delta 1), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 1.09 KiB | 556.00 KiB/s, done.
From github.com:hogehoge/hello-world
 * branch            main       -> FETCH_HEAD
   df9f8ce..0c291e9  main       -> origin/main
Updating df9f8ce..0c291e9
Fast-forward
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 Deleted local branch feature/2-user-profile and switched to branch main
 Deleted remote branch feature/2-user-profile
hogehoge@mac hello-world %

他にも以下のマージ方法があり、プロジェクトのルールに応じて使い分けます。

  • --merge: マージコミット(ブランチを統合したことを示す新しいコミット)を作成します。元のブランチのコミット履歴がすべて残るため、最も安全で推奨されることが多い方法です。
  • --rebase: ブランチの各コミットを、mainブランチの最新コミットの後ろに一つずつ付け直してからマージします。履歴が一直線になり綺麗ですが、履歴を書き換えるため、複数人で共有しているブランチで使うと大きな問題を引き起こす可能性があります。 Gitに慣れるまでは、--merge--squashを使うことを強く推奨します。

この流れでつまずいたら、Pull Requestのレビューでよく発生する「コンフリクト(コードの衝突)」の解決方法について以下の記事で、詳細に解説しているので、是非ご覧ください。


STEP8: 後片付け(ブランチ削除)

最後に、あなたの手元に残っているローカルの作業ブランチを削除して、作業環境を綺麗に保ちます。

# 1. mainブランチに戻る
git switch main

# 2. 不要になったローカルブランチを削除
git branch -d feature/2-user-profile

これで、一つの機能開発サイクルが完了です。お疲れ様でした!


STEP9: Release機能で開発の「成果」を正式に公開する

概要

Gitのタグ機能と連携し、リポジトリの履歴における特定のポイントを「バージョン」として正式にマーキングする機能です。
リリースには、ソースコードのzipファイルが自動的に添付されるほか、コンパイル済みの実行ファイルなどを手動で添付することもできます。

Gitタグの作成とプッシュ

gh release createコマンドは、Gitのタグを元にリリースを作成します。そのため、先にローカルでタグを作成し、リモートリポジトリにプッシュしておく必要があります。
チーム開発では、誰が、いつ、どんな目的で付けたタグなのかが分かるように、注釈付きタグ (-a) を使うのが一般的です。

# 1. 注釈(-m)を付けて、v1.0.0という名前のタグを作成
git tag -a v1.0.0 -m "バージョン1.0.0のリリース"

# 2. 作成したタグをリモートリポジトリにプッシュ
git push origin v1.0.0

コード実行例:

# 既存のタグの確認
hogehoge@mac hello-world % git tag 
# タグの付与
hogehoge@mac hello-world % git tag -a v1.0.0 -m "バージョン1.0.0のリリース"
hogehoge@mac hello-world % git tag 
v1.0.0
# タグのプッシュ
hogehoge@mac hello-world % git push origin v1.0.0
Enter passphrase for key '/Users/hogehoge/.ssh/id_ed25519'
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 200 bytes | 200.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:hogehoge/hello-world.git
 * [new tag]         v1.0.0 -> v1.0.0
hogehoge@mac hello-world %
  • GitHubリリースの作成
# v1.0.0タグを元に、GitHubリリースを作成。--generate-notesで変更点を自動要約
gh release create v1.0.0 --generate-notes

コード実行例:

hogehoge@mac hello-world % gh release create v1.0.0 --generate-notes<br>https://github.com/hogehoge/hello-world/releases/tag/v1.0.0<br>hogehoge@mac hello-world %

tag と releaseについては、以下の記事で詳細に解説していますので、是非ご覧ください。


(応用)Branch Protection Ruleでミスを防ごう

概要

mainブランチのような重要なブランチが、誤って変更されたり、品質の低いコードが混入したりするのを防ぐためのガードレール機能です。これはコマンドではなく、GitHubのWeb UIから設定します。

利用シーン

  • mainブランチには、最低1人以上のレビュー承認がないとマージできないようにしたい。
  • 自動テストがすべて成功しない限り、マージボタンを押せなくしたい。
  • 誰にも強制プッシュ(push --force)を許可しないようにしたい。(強制プッシュ:リモートリポジトリの履歴をローカルの履歴で強制的に上書きする危険な操作)

設定手順

  1. リポジトリページの「Settings」タブを開く。
  2. 左メニューの「Branches」を選択する。
  3. 「Add classic branch protection rules」をクリックする。
  4. 保護したいブランチ名(例: main)を入力し、適用したいルール(レビュー必須、自動テストの合格が必須など)にチェックを入れて保存します。

参考資料


まとめ

【今日からできる!実践ステップ】

  1. 自分のGitHubアカウントに、練習用のリポジトリを作成しましょう。
  2. gh issue create -t "最初のタスク" -b "README.mdを更新する" でIssueを作成します。
  3. git switch -c update-readme でブランチを作成し、README.mdを少し編集してコミットします。
  4. git push -u origin update-readme で変更をGitHubにアップロードします。
  5. gh pr create --title "READMEを更新" --body "Closes #1" で最初のPull Requestを作成してみましょう!

ぜひ、あなたのプロジェクトでも次のissueが発生した際に、自分で修正し、pull requestを作成してみてください。

さあ、あなたのMacを快適な開発環境にしましょう!!

SNSでもご購読できます。

コメントを残す

*