変更の取り消しと reset

INPUT · スライド

変更の取り消し(restore / reset / revert)

01 / 11

Git を使う最大のメリットは「安全に戻れること」

これまでの章では commit を「残す」操作を学んできました。しかし、バージョン管理システムを使う最大の恩恵は、過去の任意の時点へ確実に巻き戻せることにあります。

「いつでも安全に戻れる」という安心感があるからこそ、大胆なリファクタリングやコード変更に挑戦できます。

この章では4つの主要な取り消しコマンドを学びます。重要なのは「どの領域の変更を戻したいのか」によって使うコマンドが異なるという点です。

02 / 11

まず「どの領域を戻したいのか」を特定する

Git の3つの領域(working tree・stage・repository)ごとに、取り消しコマンドが明確に分かれています。

  • working tree(未 stage の作業差分)を破棄したい → git restore <file>
  • staging area(index)から降ろしたい → git restore --staged <file>
  • local の commit 履歴を巻き戻したい → git reset
  • remote に push 済みの commitを打ち消したい → git revert

「変更を戻す」と一口に言っても、対象の領域によって実行すべき操作は全く異なります。対象領域を意識することが迷わない秘訣です。

03 / 11

git restore — working tree の変更を破棄する

ファイルを編集したものの、その変更が不要になった場合は git restore <ファイル名> を実行します。

直前の commit 時の状態に working tree のファイルが一瞬で復元されます。

ただし、一度破棄した未 commit の変更は二度と復元できません。commit されていない変更は Git のデータベースに記録されていないためです。

$ git restore nedan.txt$ git statusOn branch mainnothing to commit, working tree clean

04 / 11

git restore --staged — stage を解除(unstage)する

git add を実行した後に「このファイルは今回の commit に含めたくない」と気づいた場合は、--staged オプションを付けて実行します。

staging area から除外されるだけで、working tree で編集したファイル内容は一切消えません。

--staged を付け忘れると working tree の編集内容そのものが破棄されてしまうため、実行前にオプションの有無を必ず確認しましょう。

$ git add .$ git restore --staged himitsu.txt$ git statusChanges to be committed:	new file:   recipe.txtUntracked files:	himitsu.txt

05 / 11

git commit --amend — 直前の commit を修正する

commit message を書き間違えた場合や、ファイルを1つ commit に含め忘れた場合は、git commit --amend を使用します。

新しい commit を追加するのではなく、直前の commit の内容を上書き(作り直し) します。ファイルの追加忘れがある場合は、先に git add してから --amend を実行します。

内部的には古い commit を破棄して新しい commit hash で再生成するため、commit ID が変化します。

$ commit -m "とりあえ"$ git commit --amend -m "メモを置いた"[main 7c1e4a9] メモを置いた

06 / 11

remote push 済みの commit を amend してはいけない

commit ID が変わるということは、Git の履歴が書き換わることを意味します。

すでに git push してチームメンバーと共有済みの commit に対して --amend を行うと、同じ内容に見えても ID が異なる commit が local に作られ、remote repository と履歴が分岐・衝突します。

鉄則として、git commit --amend はまだ remote へ push していない local commit に対してのみ実行してください。

07 / 11

git reset — branch の HEAD ポインタを巻き戻す

commit そのものを取り消して過去の時点に戻したい場合は git reset を使います。

branch が指している HEAD ポインタを、過去の commit(例: HEAD~1 で1つ前、HEAD~2 で2つ前)へ付け替えます。

git reset には影響範囲の異なる3つの主要オプションが存在します。

$ git log --oneline9f2a1c4 不要な変更のコミット3b7e5d1 正常なコミット$ git reset --soft HEAD~1$ git log --oneline3b7e5d1 正常なコミット

08 / 11

reset の3つのモード(--soft / --mixed / --hard)

巻き戻した際に「手元の作業内容をどこまで残すか」が異なります。

  • --soft … commit のみ取り消す。staging area と working tree の変更はそのまま保持される
  • --mixed(オプション省略時のデフォルト) … commit と stageを取り消す。working tree の変更は保持される
  • --hard … commit・stage・working tree のすべてを取り消す。未 commit の作業内容も含めて完全に破棄される

「commit をやり直したいだけ」なら --soft または --mixed を使います。

--hard は作業内容が完全に消失し、取り返しがつきません。実行前に必ず内容を確認しましょう。

09 / 11

git revert — 打ち消し commit を作成する

git reset は履歴を直接書き換えるため、すでに remote repository へ push 済みの commit には使用できません。

remote 共有済みの commit を取り消したい場合は git revert <commitID> を使用します。

これは過去の commit を消去するのではなく、「その commit の変更内容を逆向きに打ち消す新しい commit」を追加するコマンドです。履歴が改変されないため、他の開発者と競合することなく安全に修正を共有できます。

$ git revert HEAD[main 4d8b2f1] Revert "まちがえて消した"$ git log --oneline4d8b2f1 Revert "まちがえて消した"9f2a1c4 まちがえて消した3b7e5d1 値段表を作成

10 / 11

reset と revert の使い分け基準

判断基準は極めて明確です。

  • まだ remote に push していない local commit → git reset(履歴をきれいに保つ)
  • すでに remote に push して共有済みの commit → git revert(安全に打ち消し commit を追加する)

自分だけの local 環境であれば reset で柔軟に修正し、チームに共有した後は revert で安全に対処する、と覚えておきましょう。

11 / 11

演習の進め方

この章の演習では、意図的に誤った操作や commit が行われた状態からスタートします。

まず git status や git log --oneline を実行して、現在の working tree・stage・commit 履歴の状態を把握してから適切なコマンドを実行しましょう。