git reflog
このページでは、git reflog
コマンドについて詳しく説明します。Git では、参照ログ、または「reflog」と呼ばれるメカニズムを使用して、ブランチの先端に対する更新を記録します。多くの Git コマンドでは、コミットを示す参照または「ref」を指定するパラメーターを使用できます。一般的な例:
Reflogs は、ローカル リポジトリでいつ Git refs が更新されたかを記録します。Git stash 内には、ブランチ tip reflog 以外に、特別な reflog が格納されています。Reflogs は、ローカル リポジトリの .git
ディレクトリ内に保存されています。git reflog
ディレクトリは .git/logs/refs/heads/.
、.git/logs/HEAD
、および .git/logs/refs/stash
にあります。git stash
がリポジトリで使用されている場合。
git reflog
の詳細については、「履歴の書き込み」ページに記載されています。このドキュメントでカバーされている内容: git reflog
の拡張構成オプション、git reflog
の一般的な使用事例と落とし穴、git reflog
で変更を元に戻す方法など。
基本的な使用法
最も基本的な Reflog 使用事例が呼び出されます。
git reflog
基本的には、以下と同等のショートカットです。
git reflog show HEAD
これにより、HEAD
reflog が出力されます。出力は次のようになります。
eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from main to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to main
39b159a HEAD@{4}: commit: expand on git context
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support
9962aed HEAD@{7}: commit: a git editor -> the Git editor
一般的な reflog アクセスについては、履歴ページの書き換えをご覧ださい。
Reflog の参照
既定では、git reflog
は HEAD
ref の reflog を出力します。HEAD
は、現在アクティブとなっているブランチの記号参照です。reflog は他の ref でも使用できます。git ref へアクセスするための構文は name@{qualifier}
です。HEAD
ref 以外にも、他のブランチ、タグ、リモート、および Git stash を参照することができます。
以下を実行し、すべての ref の完全な reflog を取得できます。
git reflog show --all
git reflog show
へブランチ名を渡す特定のブランチの reflog を見るには
git reflog show otherbranch 9a4491f otherbranch@{0}: commit: seperate articles into branch PRs 35aee4a otherbranch{1}: commit (initial): initial commit add git-init and setting-up-a-repo docs
この例を実行すると、otherbranch
ブランチの reflog が表示されます。以下の例では、git stash
コマンドを使用して、いくつかの変更に stash を行ったと想定しています。
git reflog stash 0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro
Git stash の reflog を出力します。返された ref ポインターは他の Git コマンドに渡すことができます。
git diff stash@{0} otherbranch@{0}
実行すると、このコードによって、stash@{0}
の変更を otherbranch@{0}
ref が比較され、Git diff 出力が表示されます。
時間付の reflog
すべての reflog エントリにはタイムスタンプが添付されています。これらのタイムスタンプは、Git ref ポインター構文の qualifier
トークンとして使用できます。これによって、時間別に Git reflog をフィルタリングすることができます。利用可能な時間修飾子の例をいくつかに以下に示します。
1.minute.ago
1.hour.ago
1.day.ago
yesterday
1.week.ago
1.month.ago
1.year.ago
2011-05-17.09:00:00
時間修飾子は組み合わせることができ (例: 1.day.2.hours.ago
)、複数形も使用できます (例: 5.minutes.ago
)。
時間修飾子の ref は他の git コマンドに渡すことができます。
git diff main@{0} main@{1.day.ago}
この例では、1 日前の main に対する現在の main ブランチを差分しています。この例は、タイム フレーム内で発生した変更を把握する際に便利です。
サブコマンドと構成オプション
git reflog
では、サブコマンドと見なされるいくつかの追加引数を使用できます。
表示 - git reflog show
show
は、既定により、暗示的に渡されます。たとえば、次のようなコマンドの場合:
git reflog main@{0}
は次のコマンドに相当します。
git reflog show main@{0}
さらに、git reflog show
は git log -g --abbrev-commit --pretty=oneline
のエイリアスです。git reflog show を実行すると、
渡された
期限切れ - git reflog expire
expire サブコマンドは、古い reflog エントリやアクセスできないできない reflog エントリを整理します。expire
サブコマンドを使用すると、データが失われる可能性があります。このサブコマンドは一般的に、ユーザーではなく、git 内部で使用します。-n
または --dry-run
オプションを git reflog expire
に渡すと、「dry run」が実行されます。これにより、どの reflog エントリに prune とマークされるかが出力されますが、実際にはそれらに対して prune は実行されません。
既定では、直近の有効期限は 90 日に設定されています。コマンド ライン引数 --expire=time
を git reflog expire
に渡すか、gc.reflogExpire
の git 構成名をsっていすることで、有効期限を指定できます。
削除 - git reflog delete
delete
サブコマンド自体は明示的であり、reflog エントリ内で passed を削除します。expire
と同様に、delete
を使用するとデータが失われる可能性があり、一般的にエンド ユーザーによって呼び出されることはありません。
失われたコマンドを復活させる
リバースやコミットの変更などの履歴書き換え操作を実行した場合であっても、Git で何かが失われることはありません。次の例では、リポジトリにいくつかの新しい変更を加えたと想定します。git log --pretty=oneline
は次のようになります。
338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs
次に、これらの変更をコミットして以下を実行します。
#make changes to HEAD git commit -am "some WIP changes"
新しいコミットを追加すると、ログは次のようになります。
37656e19d4e4f1a9b419f57850c8f1974f871b07 some WIP changes 338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs
この時点で、以下を実行して main ブランチに対するインタラクティブなリベースを実行します。
git rebase -i origin/main
rebase 中、s
rebase サブコマンドを使用して squash するコミットをマークします。rebase 中、いくつかのコミットを、最新の「一部の WIP 変更」コミットへまとめます。
コミットをで squash を実行したため、git log
出力は次のようになります。
40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs some WIP changes 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs
この時点で git log
を調べると、squash をマークしたコミットはなくなったように見えます。squash を実行したコミットの 1 つを操作したい場合はどうすればよいでしょうか。履歴に対する変更を削除するのでしょうか。このときに、reflog を利用します。
git reflog 37656e1 HEAD@{0}: rebase -i (finish): returning to refs/heads/git_reflog 37656e1 HEAD@{1}: rebase -i (start): checkout origin/main 37656e1 HEAD@{2}: commit: some WIP changes
rebase
の最初と最後には reflog エントリがあり、そのさらに前には先程の「一部の WIP 変更」コミットがあります。reflog ref へ git reset
と渡し、rebase の前のコミットへとリセットできます。
git reset HEAD@{2}
この reset コマンドを実行すると、HEAD
を、「いくつかの WIP 変更」が追加されたコミットへと移動し、他のスカッシュされたコミットを基本的に復元します。
概要
このチュートリアルでは、git reflog
コマンドについて説明しました。カバーされているいくつかの重要なポイントを次に示します。
- 特定のブランチの reflog を表示するには
- reflog を使用して git rebase をもとに戻すには
- 時間ベースの reflog エントリを指定および表示するには
git reflog
は、git checkout、git reset、git merge などの他の git コマンドと使用できることについて簡単に触れました。詳細については、それぞれのページをご覧ください。ref や reflog の詳細については、こちらをご覧ください。