コンテンツにスキップ

3-2. 演習問題


1-1. チーム開発で main に直接 commit せず、feature branch を使う主な理由として最も適切なのはどれか。

  • A. まだ完成していない変更を共有の安定ラインから分離するため
  • B. GitHub のロゴを表示するため
  • C. ファイルを自動で暗号化するため

1-2. git fetch origin の役割として最も適切なのはどれか。

  • A. リモートの最新情報を取得するが、現在の branch にはまだ反映しない
  • B. リモートの履歴を削除する
  • C. いまの変更をすぐ merge する

1-3. Pull Request / Merge Request の主な目的として最も適切なのはどれか。

  • A. merge 前に変更内容と意図を確認し、レビューすること
  • B. ローカルのファイルサイズを減らすこと
  • C. DNS の名前解決を行うこと

1-4. main を更新するとき、意図しない merge commit を作りにくいコマンドとして最も適切なのはどれか。

  • A. git pull --ff-only
  • B. git add .
  • C. git branch -D main

1-5. 共有済みの main に誤った変更が入ったとき、まず優先して考える方法として最も適切なのはどれか。

  • A. git revert
  • B. git push --force
  • C. フォルダを手で削除する

1-6. PR / MR の説明として最も適切なのはどれか。

  • A. 変更の目的、差分、確認方法を共有する場
  • B. commit メッセージを自動で翻訳する機能
  • C. Git をインストールするためのツール

次の文章の空欄を埋めてください。

  1. GitHub で merge 前のレビュー依頼を行う仕組みを (   ) Request という。
  2. GitLab で同様の仕組みを (   ) Request という。
  3. リモートリポジトリの代表的な名前は (   ) である。
  4. リモートの履歴を取得するが、現在の branch にはまだ反映しないコマンドは git **(   )** origin である。
  5. ローカルの commit をリモートへ送るコマンドは git **(   )** である。
  6. 共有履歴を壊さずに変更を打ち消すコマンドは git **(   )** である。
解答欄

3-1. なぜチーム開発では main に直接 commit せず、branch を切って PR / MR を作ることが多いのか説明してください。

解答欄

3-2. git fetchgit pull --ff-only の違いを説明してください。

解答欄

3-3. PR / MR にはどのような情報を書くとレビューしやすくなるか説明してください。

解答欄

3-4. 共有済みの branch で、なぜまず git revert を優先して考えたほうがよいのか説明してください。

解答欄

実際の GitHub / GitLab アカウントがなくても流れを理解できるよう、ローカルに擬似的なリモートリポジトリ を作って練習してみましょう。

この演習では ~/practice/chapter03-team-demo の中に練習環境を作ります。
同名フォルダがすでにある場合は、chapter03-team-demo-2 のように別名を使ってください。

① 擬似リモートと作業用 clone を作る

Terminal window
mkdir -p ~/practice/chapter03-team-demo
cd ~/practice/chapter03-team-demo
git init --bare remote.git
git clone remote.git work
cd work
git config user.name "Trainee"
git config user.email "trainee@example.com"

次のような表示が出れば成功:

Initialized empty Git repository in .../remote.git/
Cloning into 'work'...
warning: You appear to have cloned an empty repository.
done.
  • warning: You appear to have cloned an empty repository. は正常。まだ commit がないだけ
  • remote.git が GitHub/GitLab 役、work が自分の PC 役と考える

② main を作って最初の commit を push する

Terminal window
git switch -c main
echo "# Team Demo" > README.md
git add README.md
git commit -m "Create team demo readme"
git push -u origin main
git --no-pager log --oneline --graph --all

git push の出力に次のような表示があれば成功:

To .../remote.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.

git --no-pager log --oneline --graph --all で、ローカルとリモートが同じ位置にいることを確認:

* a1b2c3d (HEAD -> main, origin/main) Create team demo readme
  • HEAD -> main が「今自分がいる場所」
  • origin/main が「リモートの main」
  • 両方が同じ commit を指しているので、push が成功している

③ feature branch で作業して push する

Terminal window
git switch -c feature/update-readme
echo "" >> README.md
echo "- Add workflow note" >> README.md
git add README.md
git commit -m "Add workflow note"
git push -u origin feature/update-readme
git --no-pager log --oneline --graph --all

git --no-pager log で、feature branch が main より 1 つ先に進んでいることを確認:

* b2c3d4e (HEAD -> feature/update-readme, origin/feature/update-readme) Add workflow note
* a1b2c3d (origin/main, main) Create team demo readme
  • HEADfeature/update-readme を指している(今いる場所)
  • main は 1 つ前の commit のまま(まだ更新していない)
  • これが PR / MR を出す前の状態

④ レビュー前の差分を確認し、追加修正する

Terminal window
git --no-pager diff main...feature/update-readme
echo "- Mention revert for safe rollback" >> README.md
git add README.md
git commit -m "Mention safe rollback"
git push

git --no-pager diff main...feature/update-readme で、main から見た差分が表示される:

# Team Demo
+- Add workflow note

追加修正を commit して push した後、feature branch に commit が 2 件積まれている状態になる:

* c3d4e5f (HEAD -> feature/update-readme, origin/feature/update-readme) Mention safe rollback
* b2c3d4e Add workflow note
* a1b2c3d (origin/main, main) Create team demo readme
  • レビュー指摘への対応は、同じ branch に commit を足して push するだけでよい

⑤ main に戻して安全に取り込む

Terminal window
git switch main
git pull --ff-only origin main
git merge --ff-only feature/update-readme
git push origin main
git --no-pager log --oneline --graph --all

git merge --ff-only の出力:

Updating a1b2c3d..c3d4e5f
Fast-forward
README.md | 3 +++
1 file changed, 3 insertions(+)

merge 後の git log で、main が feature branch に追いついていることを確認:

* c3d4e5f (HEAD -> main, origin/main, origin/feature/update-readme, feature/update-readme) Mention safe rollback
* b2c3d4e Add workflow note
* a1b2c3d Create team demo readme
  • mainfeature/update-readme が同じ commit を指している
  • Fast-forward は「main を素直に前に進めただけ」という意味
  • もし --ff-only が失敗しても、まだ壊していないので git status で状況を確認する

⑥ 共有済みの変更を安全に打ち消す

Terminal window
git revert HEAD --no-edit
git push origin main
git --no-pager log --oneline --graph --all

git revert 後の git log で、打ち消し commit が追加されていることを確認:

* d4e5f6a (HEAD -> main, origin/main) Revert "Mention safe rollback"
* c3d4e5f (origin/feature/update-readme, feature/update-readme) Mention safe rollback
* b2c3d4e Add workflow note
* a1b2c3d Create team demo readme
  • 元の commit(c3d4e5f)は消えておらず、逆向きの commit が上に追加 されている
  • push 後、リモートの origin/main も同じ位置にいるので、共有先にも反映されている

⑦ 困ったら確認する

途中で分からなくなったら、次を実行して状況を整理する。

Terminal window
git status
git branch
git --no-pager log --oneline --graph --all

問題1の解答(クリックで開く)

1-1. 正解:A. まだ完成していない変更を共有の安定ラインから分離するため

解説

  • A が正しい。feature branch を使う最大の目的は、未完成の変更を main に直接混ぜず、安全に分離することである。
  • B は誤り。ロゴ表示とは無関係である。
  • C は誤り。暗号化は別の仕組みの役割である。

1-2. 正解:A. リモートの最新情報を取得するが、現在の branch にはまだ反映しない

解説

  • A が正しい。git fetch は「まず最新状況を持ってくる」ための安全な取得操作である。
  • B は誤り。履歴削除は行わない。
  • C は誤り。merge まで自動で行うのは pull 側の性質に近い。

1-3. 正解:A. merge 前に変更内容と意図を確認し、レビューすること

解説

  • A が正しい。PR / MR は差分、目的、確認方法を共有しながら merge 前に検討するための場である。
  • B は誤り。ファイルサイズ削減機能ではない。
  • C は誤り。DNS とは関係がない。

1-4. 正解:A. git pull --ff-only

解説

  • A が正しい。--ff-only を付けると、履歴がまっすぐ進むときだけ取り込むため、意図しない merge commit を避けやすい。
  • B は誤り。git add . はステージ操作であり、リモート更新とは別の話である。
  • C は誤り。main を削除するのは論外である。

1-5. 正解:A. git revert

解説

  • A が正しい。共有済み履歴の取消しでは、まず git revert を考えるのが安全である。
  • B の push --force は履歴を書き換えるため、共有 branch では影響が大きい。
  • C は誤り。フォルダを手で消しても、共有履歴の整合性は保てない。

1-6. 正解:A. 変更の目的、差分、確認方法を共有する場

解説

  • A が正しい。レビューしやすい PR / MR は、「何を」「なぜ」「どう確認したか」が見える。
  • B は誤り。翻訳機能ではない。
  • C は誤り。Git インストールとは別の話である。
問題2の解答(クリックで開く)
  1. Pull

GitHub では Pull Request と呼ぶ。merge 前に差分と意図を共有するための仕組みである。

  1. Merge

GitLab では Merge Request と呼ぶ。名前は違うが、役割はほぼ同じである。

  1. origin

リモートリポジトリの代表的な名前である。clone 時に自動で付くことが多い。

  1. fetch

リモートの情報だけを取り込む安全寄りの操作である。まず状況を把握したいときに有効。

  1. push

ローカルの commit を共有先へ送る操作である。送る前に git statusgit log で確認することが大切。

  1. revert

共有履歴を壊さずに変更を打ち消す方法である。チーム開発では特に重要。

問題3の解答例(クリックで開く)

3-1. branch と PR / MR を使う理由

main に直接 commit すると、未完成の変更がそのまま共有され、レビュー前に混ざってしまう。 branch を分けて PR / MR を作ると、変更を安全に隔離しながら、意図や差分を確認してから取り込める。 その結果、品質確認、影響範囲の把握、問題発生時の切り分けがしやすくなる。


3-2. git fetchgit pull --ff-only の違い

git fetch はリモートの最新履歴を取得するだけで、いまの作業 branch にはまだ反映しない。 一方 git pull --ff-only は取得した履歴を現在の branch に反映する。 つまり fetch は確認寄り、pull --ff-only は安全寄りの更新操作である。


3-3. レビューしやすい PR / MR に必要な情報

何を変えたか、なぜ変えたか、どう確認したかを書くとレビューしやすい。 必要なら「まだ相談したい点」や「未対応の懸念」も書くと、レビュー側が意図をつかみやすい。 これにより、単なる差分の確認ではなく、変更の背景も含めて評価できる。


3-4. 共有 branch では git revert を優先する理由

共有済みの履歴を書き換えると、他の人のローカル履歴と食い違いが起きやすい。 git revert なら、元の commit を消さずに打ち消し commit を追加するため、誰が見ても経緯を追いやすい。 そのため、チーム開発ではまず revert を考えるほうが安全である。

問題4の解答例(クリックで開く)

① 擬似リモートと作業用 clone を作る

Terminal window
$ mkdir -p ~/practice/chapter03-team-demo
$ cd ~/practice/chapter03-team-demo
$ git init --bare remote.git
$ git clone remote.git work
$ cd work
$ git config user.name "Trainee"
$ git config user.email "trainee@example.com"

remote.git は GitHub / GitLab の代わりとなる共有リポジトリ役である。 work は自分のローカル作業場所で、ここで branch 作成や commit を試す。 --bare は「作業ファイルを持たない共有用リポジトリ」を作るための指定である。


② main を作って最初の commit を push する

Terminal window
$ git switch -c main
$ echo "# Team Demo" > README.md
$ git add README.md
$ git commit -m "Create team demo readme"
$ git push -u origin main
$ git --no-pager log --oneline --graph --all

ここでローカルの main が作られ、origin に push される。 -u によって、ローカル branch とリモート branch の対応が覚えられるため、次回以降の push / pull が楽になる。


③ feature branch で作業して push する

Terminal window
$ git switch -c feature/update-readme
$ echo "" >> README.md
$ echo "- Add workflow note" >> README.md
$ git add README.md
$ git commit -m "Add workflow note"
$ git push -u origin feature/update-readme
$ git --no-pager log --oneline --graph --all

main から分離した feature branch で変更を進めている。 これが、実務で PR / MR を出す前の基本形である。 git log --graph --all を見ると、main と feature branch の位置関係が分かる。


④ レビュー前の差分を確認し、追加修正する

Terminal window
$ git --no-pager diff main...feature/update-readme
$ echo "- Mention revert for safe rollback" >> README.md
$ git add README.md
$ git commit -m "Mention safe rollback"
$ git push

git --no-pager diff main...feature/update-readme により、feature branch が main に対してどんな差分を持つか確認できる。 その後、レビュー指摘に対応するつもりで追加 commit を積み、同じ branch に push している。 実際の PR / MR でも、このように追加修正を重ねていくことが多い。


⑤ main に戻して安全に取り込む

Terminal window
$ git switch main
$ git pull --ff-only origin main
$ git merge --ff-only feature/update-readme
$ git push origin main
$ git --no-pager log --oneline --graph --all

まず main を最新にし、そのうえで fast-forward できる場合だけ merge している。 --ff-only を付けることで、履歴が不自然に分岐している場合は止まってくれるため、安全確認のきっかけになる。 もし止まっても、まだ壊れてはいない。git statusgit --no-pager log --oneline --graph --all で branch の位置関係を確認してから次を考える。


⑥ 共有済みの変更を安全に打ち消す

Terminal window
$ git revert HEAD --no-edit
$ git push origin main
$ git --no-pager log --oneline --graph --all

共有済みの main に入った直近の commit を、git revert で打ち消している。 元の commit を消すのではなく、逆向きの commit を追加して push するため、履歴の説明責任を保ちやすい。 チーム開発で「まず安全に戻す」感覚を身につけるには、とてもよい練習である。


⑦ 困ったら確認する

Terminal window
$ git status
$ git branch
$ git --no-pager log --oneline --graph --all

git status で作業状態、git branch で現在 branch、git log --graph --all で履歴全体を確認できる。 チーム開発では、「いま自分がどこで何をしようとしているか」を見失わないことが重要である。