コンテンツにスキップ

3-1. 演習問題


1-1. Git で迷ったとき、最初に実行するコマンドとして最も適切なのはどれか。

  • A. git status
  • B. git merge
  • C. git push

1-2. git add memo.txt の主な役割として最も適切なのはどれか。

  • A. memo.txt の変更を次の commit に入れる準備をする
  • B. memo.txt を完全に削除する
  • C. memo.txt をリモートへ送る

1-3. すでに git add した変更を、作業内容は残したままステージから外したい。最も適切なのはどれか。

  • A. git restore memo.txt
  • B. git restore --staged memo.txt
  • C. git commit -m "undo"

1-4. branch を使う主な理由として最も適切なのはどれか。

  • A. まだ完成していない変更を main から分離して作業するため
  • B. ファイルサイズを自動で小さくするため
  • C. ステータスコードを確認するため

1-5. merge conflict が起きやすい状況として最も適切なのはどれか。

  • A. 別々の branch で、同じファイルの同じ部分を別々に変更した
  • B. git status を 2 回続けて実行した
  • C. まだ 1 回も commit していない

1-6. すでに commit 済みの変更を、履歴を壊さず安全に打ち消したい。最も適切なのはどれか。

  • A. git revert <commit>
  • B. git add <file>
  • C. git diff

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

  1. 今編集中のファイルがある場所を (   ) ツリーという。
  2. 次の commit に入れる変更を選ぶ場所を (   ) エリアという。
  3. 変更履歴を記録する単位を (   ) という。
  4. 新しい branch を作ってそのまま移動するコマンドは git switch -c **(   )** である。
  5. ステージ済みの差分を見るコマンドは git **(   )** --staged である。
  6. commit 済みの変更を安全に打ち消すコマンドは git **(   )** である。
解答欄

3-1. 作業ツリー・ステージングエリア・リポジトリの違いを説明してください。

解答欄

3-2. なぜ変更を小さく commit し、branch を分けて作業したほうがよいのか説明してください。

解答欄

3-3. git restoregit revert の違いを説明してください。

解答欄

3-4. Git の状態が分からなくなったとき、なぜ最初に git status を見るべきなのか説明してください。

解答欄

Git Bash を使って、失敗しても戻せる小さな練習用リポジトリ を作ってみましょう。

次の作業は ~/practice/git-basics という練習用フォルダで行います。
間違えてもこのフォルダの中だけなので、安心して試してください。

① 練習用リポジトリを作る

Terminal window
mkdir -p ~/practice/git-basics
cd ~/practice/git-basics
git init
git branch -m main
git config user.name "Trainee"
git config user.email "trainee@example.com"
git status

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

On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
  • On branch main が出ていれば、Git 管理が始まっている
  • No commits yet は、まだ何も記録していない状態を意味する

② 最初の commit を作る

Terminal window
echo "Git practice" > memo.txt
git status
git add memo.txt
git status
git commit -m "Add initial memo"
git --no-pager log --oneline

git status を 2 回実行しているのがポイント。表示の変化を追うこと:

# 1回目の git status(add 前)
Untracked files:
memo.txt ← まだ Git が追跡していない
# 2回目の git status(add 後)
Changes to be committed:
new file: memo.txt ← 次の commit に入る準備ができた

commit 後の git --no-pager log --oneline で、履歴が 1 件表示されれば成功:

a1b2c3d Add initial memo

a1b2c3d の部分は環境ごとに異なる)

③ 未ステージの変更を確認して戻す

Terminal window
echo "Second line" >> memo.txt
git --no-pager diff
git restore memo.txt
git status

git --no-pager diff で、追加した行が緑色の + 付きで表示される:

Git practice
Second line

git restore memo.txt の後、git status で次のように表示されれば成功:

On branch main
nothing to commit, working tree clean
  • working tree clean は「作業ツリーに未保存の変更がない」という意味
  • つまり restore で変更が取り消され、commit 済みの状態に戻っている

④ ステージしすぎた変更を戻す

Terminal window
echo "Second line" >> memo.txt
git add memo.txt
git status
git --no-pager diff --staged
git restore --staged memo.txt
git status
git --no-pager diff

git add 後の git status では、変更が「次の commit に入る予定」になっている:

Changes to be committed:
modified: memo.txt

git restore --staged 後の git status では、ステージから外れて「未ステージ」に戻る:

Changes not staged for commit:
modified: memo.txt

ここで重要なのは、ステージから外れただけで、編集内容自体は消えていない こと。 git --no-pager diff を実行すると、まだ差分が表示される:

Git practice
Second line

⑤ 変更を commit してから、安全に打ち消す

Terminal window
git add memo.txt
git commit -m "Add second line to memo"
git --no-pager log --oneline --graph
git revert HEAD --no-edit
git --no-pager log --oneline --graph

revert 前の git log では commit が 2 件:

* b2c3d4e Add second line to memo
* a1b2c3d Add initial memo

revert 後の git log では、打ち消し commit が 追加 されて 3 件になる:

* c3d4e5f Revert "Add second line to memo"
* b2c3d4e Add second line to memo
* a1b2c3d Add initial memo
  • 元の commit(b2c3d4e)は消えておらず、逆向きの commit が上に追加 されている
  • これが「履歴を消す」ではなく「打ち消す」ということ

⑥ branch を作って merge する

Terminal window
git switch -c feature/add-note
echo "Branch note" > note.txt
git add note.txt
git commit -m "Add branch note"
git switch main
git merge --no-ff feature/add-note -m "Merge feature/add-note"
git --no-pager log --oneline --graph --all

git switch -c feature/add-note で新しい branch に切り替わる:

Switched to a new branch 'feature/add-note'

merge 後の git --no-pager log --oneline --graph --all で、枝分かれと合流が見える:

* d4e5f6a Merge feature/add-note
|\
| * e5f6a7b Add branch note
|/
* c3d4e5f Revert "Add second line to memo"
* b2c3d4e Add second line to memo
* a1b2c3d Add initial memo
  • |\|/ の部分が、branch が分かれて合流したことを表している
  • --no-ff を付けたので、merge commit(d4e5f6a)が明示的に作られている

⑦ 迷ったら状態を見る

途中で分からなくなったら、必ず次の順で確認する。

Terminal window
git status
git --no-pager diff
git --no-pager diff --staged
git --no-pager log --oneline --graph --all

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

1-1. 正解:A. git status

解説

  • A が正しい。Git で迷ったときは、今どの branch にいて、何が未ステージで、何がステージ済みかを最初に把握する必要がある。
  • B は誤り。git merge は状態を確認する前に実行するコマンドではない。
  • C は誤り。git push は共有先へ変更を送る操作であり、状況確認なしに行うと危険である。

1-2. 正解:A. memo.txt の変更を次の commit に入れる準備をする

解説

  • A が正しい。git add は「次の commit にこの変更を入れる」と Git に伝える操作である。
  • B は誤り。ファイル削除の命令ではない。
  • C は誤り。リモートへ送るのは git push の役割である。

1-3. 正解:B. git restore --staged memo.txt

解説

  • B が正しい。git restore --staged は、ステージした変更を外すためのコマンドである。
  • A の git restore memo.txt は、作業ツリーの変更自体を戻す方向で使う。
  • C は誤り。新しい commit を作っても、「ステージから外す」ことにはならない。

「変更を消したい」のか、「次の commit から外したいだけ」なのかを区別することが重要である。


1-4. 正解:A. まだ完成していない変更を main から分離して作業するため

解説

  • A が正しい。branch の主目的は、安全に作業を分けることにある。
  • B は誤り。branch にファイル圧縮の役割はない。
  • C は誤り。ステータスコードは HTTP の話であり、Git の branch とは無関係である。

1-5. 正解:A. 別々の branch で、同じファイルの同じ部分を別々に変更した

解説

  • A が正しい。同じ場所に対して異なる変更があると、Git はどちらを採用すべきか自動では決められない。
  • B は誤り。git status を何回実行しても conflict は起きない。
  • C は誤り。commit の回数そのものではなく、変更内容の衝突が本質である。

1-6. 正解:A. git revert <commit>

解説

  • A が正しい。git revert は履歴を壊さず、既存 commit の内容を打ち消す新しい commit を作る。
  • B の git add はステージ操作であり、commit 済み変更の取消しではない。
  • C の git diff は差分確認用であり、履歴を打ち消す操作ではない。

特にチーム開発では、「消す」より「打ち消す」を優先すると安全である。

問題2の解答(クリックで開く)
  1. 作業

今編集中のファイルがある場所を作業ツリーという。Git のコマンドで状態を見るときの出発点である。

  1. ステージング

次の commit に入れる変更を選ぶ場所である。全部を一度に commit せず、意味のある単位に分けるために必要。

  1. commit

履歴を記録する基本単位である。あとで戻ったりレビューしたりするときの最小単位になる。

  1. feature/login

例として feature/login のような branch 名が入る。大切なのは「新しい branch 名を与え、その branch へ移動する」という意味である。

  1. diff

git diff --staged で、ステージ済みの変更内容を確認できる。commit 前の最終確認としてよく使う。

  1. revert

commit 済みの変更を安全に打ち消すコマンドである。履歴の整合性を保ちやすい。

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

3-1. 作業ツリー・ステージングエリア・リポジトリの違い

作業ツリーは今自分が編集している場所、ステージングエリアは次の commit に入れる変更を選ぶ場所、リポジトリは commit 履歴が保存される場所である。 Git はこの 3 つを分けて管理しているため、変更を見たり、選んだり、記録したりを段階的に行える。 この構造を理解すると、git addgit restore --staged の意味が分かりやすくなる。


3-2. 小さな commit と branch 分離が大切な理由

変更を小さく commit すると、どの変更で問題が起きたかを追いやすくなる。 また branch を分けて作業すると、未完成の変更を main に混ぜずに済むため安全である。 レビュー、デバッグ、取り消しのすべてがやりやすくなるため、実務ではとても重要である。


3-3. git restoregit revert の違い

git restore は、主に作業ツリーやステージングエリアの変更を戻すために使う。 一方 git revert は、すでに commit した変更を打ち消す新しい commit を作る。 つまり restore は commit 前の調整、revert は commit 後の安全な取消し、と整理できる。


3-4. 最初に git status を見る理由

Git で困ったときは、今どの branch にいて、何が未ステージで、何がステージ済みかを把握しないと正しい判断ができない。 git status は、その全体像を最短で確認できるコマンドである。 状態確認なしに戻す操作をすると、必要な変更まで消す危険があるため、まず git status を見る習慣が重要である。

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

① 練習用リポジトリを作る

Terminal window
$ mkdir -p ~/practice/git-basics
$ cd ~/practice/git-basics
$ git init
$ git branch -m main
$ git config user.name "Trainee"
$ git config user.email "trainee@example.com"
$ git status

ここでは練習用のローカルリポジトリを作っている。git config はこのリポジトリ内だけの設定なので、グローバル設定を汚さずに commit を試せる。 git status で branch 名と作業状態を確認するのが第一歩である。


② 最初の commit を作る

Terminal window
$ echo "Git practice" > memo.txt
$ git status
$ git add memo.txt
$ git status
$ git commit -m "Add initial memo"
$ git --no-pager log --oneline

memo.txt は最初 untracked で、git add すると staged になり、git commit すると履歴に入る。 この流れで「作業ツリー → ステージングエリア → リポジトリ」を体験できる。


③ 未ステージの変更を確認して戻す

Terminal window
$ echo "Second line" >> memo.txt
$ git --no-pager diff
$ git restore memo.txt
$ git status

git --no-pager diff で、今の作業ツリーにどんな差分があるか確認できる。 git restore memo.txt を実行すると、その未ステージ変更が取り消される。 ただし git restore memo.txt は変更を消すので、捨ててよい内容かを先に確認してから実行することが重要である。 つまり「まだ commit していない作業の取消し」を安全に試せる。


④ ステージしすぎた変更を戻す

Terminal window
$ echo "Second line" >> memo.txt
$ git add memo.txt
$ git status
$ git --no-pager diff --staged
$ git restore --staged memo.txt
$ git status
$ git --no-pager diff

git restore --staged は、変更内容そのものを消すのではなく、「次の commit に入れる予定」から外す。 そのため git status では unstaged changes に戻り、git --no-pager diff では差分がまだ見える。 この違いを体感することがとても重要である。


⑤ commit してから、安全に打ち消す

Terminal window
$ git add memo.txt
$ git commit -m "Add second line to memo"
$ git --no-pager log --oneline --graph
$ git revert HEAD --no-edit
$ git --no-pager log --oneline --graph

ここでは一度 commit に入れた変更を、git revert で打ち消している。 git revert は履歴を消すのではなく、逆向きの commit を新しく追加するので安全である。 共有済みの履歴でも扱いやすい、という実務上の利点がある。


⑥ branch を作って merge する

Terminal window
$ git switch -c feature/add-note
$ echo "Branch note" > note.txt
$ git add note.txt
$ git commit -m "Add branch note"
$ git switch main
$ git merge --no-ff feature/add-note -m "Merge feature/add-note"
$ git --no-pager log --oneline --graph --all

feature/add-note という別 branch で作業し、それを main に取り込む流れを確認する演習である。 今回は --no-ff を付けて merge commit を明示的に作り、履歴の合流を見やすくしている。 そのため git --no-pager log --graph --all を使うと、枝分かれしてから合流したことが視覚的に分かる。


⑦ 迷ったら状態を見る

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

この順で見ると、今の問題が「未ステージ変更なのか」「ステージ済み変更なのか」「すでに commit 済みなのか」を切り分けやすい。 Git の学習では、戻す技術以上に「どこを見るか」を身につけることが重要である。