CH 14 / 75第2部 Gitの基礎 ── 手元で完結する操作

やり直す①(restore・reset・amend)

このページで分かること

  • ワークツリーの編集を、最後の記録の状態に戻せる
  • 直前のコミットのメッセージや入れ忘れを --amend で直せる
  • git reset の --soft・(指定なし)・--hard の違いが分かる
  • 記録していない変更が消える操作を見分けられる
このページの目次14 items

第2部の13までで、変更を記録し、ファイルを整理できるようになりました。このページでは、その途中で間違えたときにどの段階まで戻すかを選んで取り消す方法を扱います。

まず全体像:どのエリアを戻すか#

取り消しのコマンドと、それぞれが最後の記録の状態に戻すエリアの対応。git restore はワークツリー、git restore –staged はステージ、git reset –soft はリポジトリ、git reset はステージとリポジトリ、git reset –hard は3つすべてを戻す。ワークツリーを戻すものは記録していない変更を消す

行がコマンド、塗った枠がそのコマンドで戻るエリアです。赤い枠がワークツリーにかかっているコマンドだけが、記録していない変更を消します。 黄色の枠のコマンドは、取り消した変更を左隣のエリアに残します。

迷ったら「黄色で済むものを選ぶ」が原則です。

編集を捨てる:git restore#

ファイルを書き換えたが、記録した状態に戻したいときに使います。

text12 lines
cd ~/git-practice
echo "まちがえた行" >> shopping.txt
git status -s

# 出力:
#  M shopping.txt

git restore shopping.txt
git status -s

# 出力:
# (何も表示されない)

shopping.txt が最後に記録した内容に戻りました。

ステージから降ろす git restore --staged は第2部の08で扱いました。こちらはファイルの中身を変えないので、安全に使えます。

直前のコミットを作り直す:git commit –amend#

コミットした直後に、メッセージの誤字や、入れ忘れたファイルに気づくことがあります。

メッセージを直す#

text14 lines
echo "パンを買う" >> shopping.txt
git add shopping.txt
git commit -m "パンをつか"

# 出力:
# [main ccf1352] パンをつか
#  1 file changed, 1 insertion(+)

git commit --amend -m "買い物メモにパンを追加"

# 出力:
# [main 1acb8f0] 買い物メモにパンを追加
#  Date: Thu Oct 22 01:02:18 2026 +0900
#  1 file changed, 1 insertion(+)

入れ忘れたファイルを足す#

text3 lines
echo "郵便局に行く" >> todo.txt
git add todo.txt
git commit --amend --no-edit

--no-edit は「メッセージはそのまま使う」の指定です。ステージに載せた todo.txt の変更が、直前のコミットに合流します。

ハッシュが ccf1352 から 1acb8f0 に変わったことに注目してください。--amend は直前のコミットを書き換えるのではなく、中身を差し替えた新しいコミットを作り、古いほうと入れ替える操作です。

コミットを取り消す:git reset#

git reset は、コミットを取り消して、その変更をどのエリアまで戻すかを選ぶコマンドです。

HEAD と HEAD~1#

text5 lines
git log --oneline -n 2

# 出力:
# ff5986c 買い物メモにパンを追加
# b90cd28 config.txt を追跡から外す

HEAD(ヘッド)は「今いる位置」、つまり最新のコミットを指す名前です。HEAD~1 はその1つ前のコミットを表します。この例では HEAD が ff5986c、HEAD~1 が b90cd28 です。HEAD の正体は第3部の18で扱います。

git reset HEAD~1 は「HEAD を1つ前のコミットまで戻す」、つまり最新のコミットを取り消すという意味になります。

–soft:コミットだけを取り消す#

text6 lines
git reset --soft HEAD~1
git status -s

# 出力:
# M  shopping.txt
# M  todo.txt

コミットはなくなりましたが、変更はステージに載ったまま残っています。メッセージを付け直したい、別の変更とまとめ直したい、というときに使います。

text1 lines
git commit -m "パンと郵便局を追加"

指定なし:ステージまで戻す#

オプションを付けない git reset は、コミットを取り消し、ステージからも降ろします(--mixed を付けたのと同じです)。変更はワークツリーに残ります。

text6 lines
git reset HEAD~1

# 出力:
# Unstaged changes after reset:
# M shopping.txt
# M todo.txt

コミットの分け方をやり直すときに便利です。第2部の09で見たように、1つの意味ごとに選んで記録し直せます。

text4 lines
git add shopping.txt
git commit -m "買い物メモにパンを追加"
git add todo.txt
git commit -m "やることに郵便局を追加"

–hard:変更ごと捨てる#

text4 lines
git reset --hard HEAD~1

# 出力:
# HEAD is now at 1acb8f0 買い物メモにパンを追加

コミットの取り消しに加えて、ステージとワークツリーも最後の記録の状態に揃えます。todo.txt を開くと、「郵便局に行く」の行は消えています。

取り消したコミットのほう(「やることに郵便局を追加」)は、実はまだ Git の中に残っています。第2部の15の reflog で取り戻します。

早見表#

やりたいこと コマンド 記録していない変更
編集を捨てて、最後の記録に戻す git restore ファイル 消える
ステージから降ろす git restore --staged ファイル 残る
直前のコミットのメッセージを直す git commit --amend -m "…" 残る
直前のコミットにファイルを足す git add → git commit --amend --no-edit 残る
コミットを取り消し、ステージに残す git reset --soft HEAD~1 残る
コミットを取り消し、ワークツリーに残す git reset HEAD~1 残る
コミットも変更もすべて捨てる git reset --hard HEAD~1 消える

よくある疑問#

Q. 2つ以上前のコミットを取り消せますか?
A. HEAD~2 で2つ前、HEAD~3 で3つ前を指せます。git reset --soft HEAD~3 なら、直近3つのコミットを取り消して1つにまとめ直せます。

Q. 古い資料にある git checkout -- ファイル と git reset HEAD ファイル は何ですか?
A. それぞれ git restore ファイル と git restore --staged ファイル の古い書き方です。どちらも今も動きますが、1つのコマンドにいくつもの役割があって紛らわしかったため、Git 2.23 で restore が追加されました。このガイドでは restore を使います。

まとめ#

  • 取り消しのコマンドは「どのエリアを最後の記録の状態に戻すか」で選ぶ
  • ⚠️ ワークツリーを戻す git restore ファイル と git reset --hard だけが、記録していない変更を消す
  • --amend は直前のコミットを、中身を差し替えた新しいコミットと入れ替える
  • git reset は --soft でステージに、指定なしでワークツリーに変更を残す
  • 共有したコミットには --amend も reset も使わない

次のページ#

15. やり直す②(revert・reflog) ── 記録を消さずに打ち消す方法と、取り消したはずのコミットを取り戻す方法を見ます。