今回は、Gitのreflogコマンドについて解説します。
Gitを使っていると、次のような場面はないでしょうか。
resetでコミットを消してしまった- ブランチを削除したらコミットが消えた
- 間違って
checkoutやswitchしてしまった - 消えたコミットを元に戻したい
このようなときに役立つのが、Gitの操作履歴を確認できるgit reflogです。
git reflogでは、HEADやブランチなどが過去にどのコミットを指していたかを確認できます。
git reflogを使えば、通常のgit logでは見つからない過去のコミットを発見し、復元できる場合があります。
この記事では、git reflogの基本的な使い方から、消したコミットやブランチを復元する方法まで解説します。
git reflogとは?
git reflogは、Gitリポジトリ内で行った操作履歴を確認するコマンドです。(※HEADやブランチの参照履歴)
例えば、次のような操作の履歴を確認できます。
- コミットした
git resetした- ブランチを切り替えた
rebaseしたmergeした
基本的な使い方は、次のコマンドを実行するだけです。
git reflog
実行すると、以下のような履歴が表示されます。
abc1234 HEAD@{0}: commit: 最新のコミット
def5678 HEAD@{1}: reset: moving to HEAD~1
ghi9012 HEAD@{2}: commit: 復元したいコミット
左側のabc1234やdef5678はコミットハッシュです。
また、HEAD@{0}やHEAD@{1}は、HEADが過去にどのコミットを参照していたかを表しています。
HEAD@{0}は現在のHEAD、HEAD@{1}は1つ前の操作時点のHEADです。
つまり、git reflogを確認することで、過去にどのコミットを指していたのかを追跡できます。
git logとgit reflogの違い
git logとgit reflogはどちらも履歴を確認するコマンドですが、確認できる内容が異なります。
| コマンド | 確認できる内容 |
|---|---|
git log |
現在のブランチにつながっているコミット履歴 |
git reflog |
HEADやブランチなどの参照履歴 |
例えば、次のような履歴があるとします。
A -- B -- C
↑
HEAD
この状態で、次のコマンドを実行します。
git reset --hard HEAD~1
すると、HEADはBに移動します。
A -- B
↑
HEAD
C
現在のブランチからCへの参照がなくなったため、通常のgit logではCを確認できなくなる場合があります。
しかし、git reflogにはHEADがCを参照していた履歴が残っています。
そのため、Cのコミットハッシュを確認して復元できます。
git reflogの基本的な使い方
git reflogの基本的な使い方についてです。
HEADの操作履歴を確認する
HEADの操作履歴を確認するには、次のコマンドを実行します。
git reflog
例えば、次のような結果が表示されます。
904d9b1 (HEAD -> main) HEAD@{0}: commit: test3 file commit
cdb4343 HEAD@{1}: commit: test2 file commit
f659651 HEAD@{2}: commit: test file commit
上から順番に新しい操作履歴です。
それぞれの履歴では、次の内容を確認できます。
コミットハッシュ HEADの履歴番号 操作内容
復元したいコミットがある場合は、左側のコミットハッシュを確認しましょう。
特定のブランチのreflogを確認する
特定のブランチの操作履歴を確認することもできます。
例えば、mainブランチの履歴を確認する場合は、次のように実行します。
git reflog main
特定ブランチの参照履歴を確認したい場合に便利です。
git reflogで消したコミットを復元する方法
ここからは、git reflogを使って消したコミットを復元する方法を紹介します。
1. git reflogで消したコミットを探す
まずは、次のコマンドを実行します。
git reflog
例えば、次のように表示されたとします。
abc1234 HEAD@{0}: reset: moving to HEAD~1
def5678 HEAD@{1}: commit: add new feature
ghi9012 HEAD@{2}: commit: initial commit
git resetによって消えてしまったadd new featureのコミットを復元したい場合、コミットハッシュdef5678を使用します。
2. コミットを復元する
コミットを現在のブランチに戻す場合は、git resetを使用します。
使用する際には、探し出した復元したいコミットハッシュを使います。
git reset --hard def5678
これで、HEADが復元したいコミットまで移動します。
A -- B
↑
HEAD
git logを実行すると、復元したコミットを確認できます。
git log --oneline
ただし、git reset --hardは現在の変更内容を削除するため注意が必要です。
現在の作業内容を残したい場合は、後述するgit branchやgit switchを使った方法もおすすめです。
git reflogで削除したブランチを復元する方法
削除したブランチを復元したい場合も、git reflogが役立ちます。
例えば、featureブランチを削除してしまった場合、まずreflogを確認します。
git reflog
削除したブランチの最後のコミットがHEADのreflogに残っている場合、そのコミットを探すことでブランチを復元できます。
例えば、test_branchで作業したあとにmainブランチへ切り替えていた場合、次のような履歴が表示されることがあります。
def5678 HEAD@{3}: checkout: moving from test_branch to main
72d8825 HEAD@{4}: commit: マージテストコンフリクト
この例では、test_branchで最後に作成したコミットが72d8825だとします。
次のコマンドを実行すると、72d8825を先頭としたtest_branchを作成できます。
git branch test_branch 72d8825
これで、削除したブランチを復元できます。
作成したブランチは下記で一覧を確認できます。
git branch
また、ブランチを作成してすぐに切り替えたい場合は、次のように実行できます。
git switch -c test_branch 72d8825
git reflogで過去の状態を確認する
git reflogで確認した過去の状態を一時的に確認することもできます。
例えば、HEAD@{1}の状態を確認したい場合は、次のコマンドを実行します。
git show HEAD@{1}
特定のコミットハッシュを指定することも可能です。
git show def5678
ファイルの内容やコミットメッセージを確認してから復元したい場合に便利です。
git reflogから安全にコミットを復元するには?
「本当にこのコミットで合っているか分からない」という場合は、いきなりgit reset --hardを実行しない方が安全です。
まずは、復元したいコミットから新しいブランチを作成します。
(recoveryブランチをdef5678コミットの内容で作ります)
git branch recovery def5678
その後、ブランチを切り替えます。
git switch recovery
これで、現在のブランチを変更せずに、過去のコミットの内容を確認できます。
問題がなければ、必要に応じてコミットを現在のブランチに取り込むこともできます。
例えば、特定のコミットだけ取り込みたい場合は、git cherry-pickを使用します。
git cherry-pick def5678
誤操作が心配な場合は、まず別ブランチに復元する方法がおすすめです。
git reflogのよくある使い方
git reflogが役立つ代表的なケースをまとめます。
git resetで消したコミットを戻す
git reflog
git reset --hard コミットハッシュ
削除したブランチを復元する
git reflog
git branch ブランチ名 コミットハッシュ
過去のコミット内容を確認する
git show HEAD@{1}
間違った操作をする前の状態に戻す
例えば、直前の操作前の状態に戻したい場合は、次のように実行できます。
git reset --hard HEAD@{1}
ただし、作業内容が削除される可能性があるため注意しましょう。
git reflogを使うときの注意点
git reflogを使う際には、いくつか注意点があります。
reflogは永久に保存されるわけではない
git reflogの履歴は永久に保存されるわけではありません。
不要になった参照履歴は、Gitの設定やガベージコレクションなどによって削除される場合があります。
そのため、誤ってコミットを削除した場合は、できるだけ早くgit reflogで確認するのがおすすめです。
reset –hardは作業内容を削除する
次のコマンドは、現在の作業ディレクトリの変更も消去します。
git reset --hard コミットハッシュ
まだコミットしていない変更がある場合は、必要に応じてgit stashなどで退避してから実行しましょう。
リモートにpush済みの場合は注意する
すでにGitHubなどのリモートリポジトリにpushした履歴を戻す場合は注意が必要です。
ローカルでgit reflogを使ってコミットを復元しても、リモートの履歴は自動的には変更されません。
また、共有ブランチに対してgit reset後の履歴を強制pushすると、他の開発者に影響する可能性があります。
共有ブランチでは、状況によってはgit revertを使った方が安全です。
Git reflogの使い方まとめ
今回は、Gitのreflogコマンドについて解説しました。
git reflogを使うことで、次のような操作ができました。
- HEADやブランチの操作履歴を確認する
resetで消したコミットを探す- 消したコミットを復元する
- 削除したブランチを復元する(ブランチを作成して復元)
- 過去の状態を確認する
コミットを消してしまったときは、あせって作業を続けるのではなく、まずgit reflogを確認してみましょう。
git logでは見つからないコミットでも、git reflogから見つけられる可能性があります。
Gitを使っていると誤ってresetしたり、ブランチを削除したりすることもあります。
そんなときのために、git reflogは「困ったときに過去の状態を探すためのコマンド」として覚えておくと便利です。
コメント