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

《 Git & GitHub 完全ガイド 目次へ 》

このページで分かること

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

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


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

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

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

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

注意

赤い枠の git restore ファイル と git reset --hard は、実行すると記録していない変更が消えます。それぞれの節で、実行前に確かめることを説明します。


編集を捨てる:git restore

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

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

# 出力:
#  M shopping.txt

git restore shopping.txt
git status -s

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

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

注意

git restore ファイル名 で捨てた編集は、Git では取り戻せません。一度も記録していないため、Git の中のどこにも残っていないからです。エディタの「元に戻す」が残っていれば、そちらで戻せることはあります。実行する前に git diff で、何が消えるかを確かめてください。

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


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

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

メッセージを直す

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(+)

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

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

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

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

注意

他の人と共有したコミットには --amend を使わないでください。相手の手元にある履歴と食い違い、混乱の元になります。このあと扱う git reset でコミットを取り消す場合も同じです。共有の仕組みは第6部で扱います。


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

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

HEAD と HEAD~1

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:コミットだけを取り消す

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

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

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

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

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

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

git reset HEAD~1

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

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

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

–hard:変更ごと捨てる

git reset --hard HEAD~1

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

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

注意

git reset --hard は、記録していない変更をすべて消します。ステージに載せた変更も、編集中のファイルも、Git では取り戻せません。実行する前に git status で、消えて困る変更が残っていないかを必ず確かめてください。

取り消したコミットのほう(「やることに郵便局を追加」)は、実はまだ 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 消える

注意

「消える」の2つは、実行前に git status と git diff で、消えて困る変更がないかを確かめてから使います。


よくある疑問

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) ── 記録を消さずに打ち消す方法と、取り消したはずのコミットを取り戻す方法を見ます。

→ ガイドの目次に戻る

この記事の最終確認日: 2026年10月

タイトルとURLをコピーしました