やり直す②(revert・reflog)

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

このページで分かること

  • git reset と git revert の違いと、選ぶ基準が分かる
  • git revert で、記録を残したまま変更を打ち消せる
  • git reflog で、取り消したはずのコミットを探し出せる
  • reflog でも取り戻せないものが何かが分かる

第2部の14の最後に、「やることに郵便局を追加」のコミットを変更ごと取り消しました。このページでは、まずそのコミットを取り戻します。そのうえで、記録を消さずに打ち消す、もう1つの取り消し方を扱います。


reset と revert の違い

上段は git revert で、A・B・C の後ろに C を打ち消すコミットを足し、C は履歴に残る。下段は git reset --hard で、main を B に戻し、C が履歴から外れる
上段は git revert で、A・B・C の後ろに C を打ち消すコミットを足し、C は履歴に残る。下段は git reset –hard で、main を B に戻し、C が履歴から外れる

どちらも「C の変更をなかったことにする」操作ですが、やり方が逆です。

  • git reset は、ブランチを過去のコミットに戻します。C は git log に出なくなり、履歴そのものが書き換わります
  • git revert は、C と正反対の変更を新しいコミットとして足します。C は履歴に残ったまま、中身だけが C の前の状態に戻ります

選ぶ基準は、そのコミットを誰かと共有したかどうかです。

状況 使うもの 理由
自分の手元にしかないコミット reset(第2部の14) 履歴がきれいに保てる。困る人がいない
他の人と共有したコミット revert 履歴を書き換えないので、相手の履歴と食い違わない
迷ったとき revert 記録が増えるだけで、何も失わない

注意

図の下段の git reset --hard は、コミットの取り消しと同時に、記録していない変更も消します(第2部の14)。実行前に git status で確かめてください。

共有の仕組みは第6部で扱います。第2〜5部では練習用フォルダの中だけで作業しているので、どちらを使っても困ることはありません。両方を試せるうちに、違いを手で確かめておきます。


reflog:HEAD が動いた記録

git log は「今のブランチからたどれるコミット」だけを表示します。取り消したコミットはもう出てきません。

cd ~/git-practice
git log --oneline -n 2

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

ところが Git は、コミットそのものをすぐには消しません。そして、HEAD がいつ、どのコミットへ動いたかを別に記録しています。それが reflog(reference log)です。

git reflog -n 3

# 出力:
# 1acb8f0 HEAD@{0}: reset: moving to HEAD~1
# fd7152c HEAD@{1}: commit: やることに郵便局を追加
# 1acb8f0 HEAD@{2}: commit: 買い物メモにパンを追加

新しい順に、HEAD の移動が並んでいます。

  • HEAD@{0}:今。reset で 1acb8f0 に戻ってきた
  • HEAD@{1}:その直前。fd7152c のコミットを作った
  • HEAD@{2}:さらにその前

HEAD@{1} の fd7152c が、取り消した「やることに郵便局を追加」です。ハッシュが分かれば、そこへ戻れます。

取り消したコミットを取り戻す

git status -s

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

git reset --hard fd7152c

# 出力:
# HEAD is now at fd7152c やることに郵便局を追加

ブランチが fd7152c を指すように戻り、todo.txt にも「郵便局に行く」の行が戻りました。

git log --oneline -n 3

# 出力:
# fd7152c やることに郵便局を追加
# 1acb8f0 買い物メモにパンを追加
# b90cd28 config.txt を追跡から外す

注意

ここでも git reset --hard を使っています。実行する前の git status で、何も表示されないこと(記録していない変更がないこと)を確かめたのはそのためです。記録していない変更があると、取り戻すつもりで別の変更を消してしまいます。


revert:記録を残したまま打ち消す

取り戻した「やることに郵便局を追加」を、今度は revert で打ち消します。

git revert --no-edit HEAD

# 出力:
# [main bb5686f] Revert "やることに郵便局を追加"
#  Date: Thu Oct 22 01:03:21 2026 +0900
#  1 file changed, 1 deletion(-)

HEAD は打ち消したいコミットの指定です。直前のコミット以外も、git revert 1acb8f0 のようにハッシュで指定できます。--no-edit を付けないと、打ち消しのコミットのメッセージを編集するエディタが開きます。

git log --oneline -n 3

# 出力:
# bb5686f Revert "やることに郵便局を追加"
# fd7152c やることに郵便局を追加
# 1acb8f0 買い物メモにパンを追加

元のコミット fd7152c は残ったまま、その上に打ち消しのコミット bb5686f が足されました。todo.txt から「郵便局に行く」の行は消えていますが、「一度追加して、あとで取り消した」という経緯が履歴に残っています。

補足

打ち消すコミットのあとに、同じ行をさらに書き換えたコミットがあると、revert の途中で Git が止まることがあります。2つの変更がぶつかった状態(コンフリクト)で、直し方は第4部の24で扱います。


reflog でも取り戻せないもの

reflog は強力ですが、万能ではありません。

取り戻せるもの 取り戻せないもの
一度でもコミットした内容 一度もコミットしていない編集(第2部の14の「消える」操作で捨てたもの)
reset・amend で取り消したコミット 期限を過ぎた古い reflog の記録
別のPCでの操作(reflog はそのPCの中だけにある)

取り消したコミットは、初期設定ではおおむね30日は reflog からたどれます。それを過ぎると、Git が掃除のときに削除することがあります。

ここから分かることは1つです。コミットさえしてあれば、Git はほぼ何でも取り戻せます。 作業の区切りでこまめにコミットすることが、いちばん確実な保険になります。


よくある疑問

Q. reflog に同じハッシュが何度も出てきます。
A. HEAD がそのコミットに何度も戻ってきた、という意味です。reflog は「どのコミットがあるか」ではなく「HEAD がどう動いたか」の記録なので、同じコミットが繰り返し現れます。

Q. revert したコミットを、さらに revert するとどうなりますか?
A. 打ち消しの打ち消しになり、元の変更が戻ってきます。履歴には3つのコミットがすべて残ります。


まとめ

  • reset はブランチを戻して履歴を書き換え、revert は打ち消しのコミットを足して履歴を残す
  • 共有したコミットは revert で打ち消す。迷ったら revert
  • git reflog は HEAD の移動の記録で、取り消したコミットのハッシュを探せる
  • 一度もコミットしていない編集は、reflog でも取り戻せない
  • こまめなコミットが、いちばん確実な保険になる

次のページ

16. Gitは差分ではなくスナップショットを保存する ── ここから第3部です。Git がコミットの中に何を保存しているのかを、仕組みから見ていきます。

→ ガイドの目次に戻る

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

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