これは何
新人プログラマ応援イベントの参加記事です。
gitにはreflogというコマンドがあります。このコマンドを学んでおくとやらかしちゃった時も大体なんとかなるので記事にします。
git reflogってなに?
git reflog
とは、Gitで操作履歴を見ることができるコマンドです。
例えば
-
branch1
にチェックアウト -
branch1
でbranch1.txt
を作成し、コミットを作る -
master
にチェックアウト
をすると、以下のようなreflogになります。
$ git reflog
4a4125a (HEAD -> master) HEAD@{0}: checkout: moving from branch1 to master
826a9dc (branch1) HEAD@{1}: commit: Create branch1.txt
4a4125a (HEAD -> master) HEAD@{2}: checkout: moving from master to branch1
このコマンド自体はそれだけなのですが、他のコマンドで一緒に表示される作業番号(HEAD@{0}
)はHEAD
などと同じ作業ポインタとしてさまざまなコマンドに指定できます。
その特性を生かしたやらかし解決法を紹介していきます。
やらかしをなんとかする
@ryozi_tn さんに、より詳しい説明や、注意点、参考資料についてコメントいただいたので、本文と合わせて読んでみてください
https://qiita.com/getty104/items/cfd98f5f0ea89ef07bf0#comment-8585c38b84ae67c281f0
間違えてgit reset --hard
で必要な変更も消しちゃった
上の例で、例えばbranch1
でgit reset --hard HEAD~
を実行し、間違えてコミットした変更を削除してしまったとします。しかし変更した内容は必要なものだったので、このままだと全く同じ作業をまたやらないといけなくなります。最悪です。
しかしこんな場合もgit reflog
を使えばなんとかなります。
まずはgit reflog
で作業ログを出します。
$ git reflog
4a4125a (HEAD -> branch1, master) HEAD@{0}: reset: moving to HEAD~
826a9dc HEAD@{1}: checkout: moving from master to branch1
このgit reflog
を見ると、HEAD@{0}
という作業番号で誤ったgit reset --hard HEAD~
を行っていることがわかります。この作業を取り消し、コミットを復活させたいです。
git reflog
の作業番号、実はそのままgit reset
の引数に指定することで、その作業を行っていた時の状態に戻せます。
今回はHEAD@{1}
に戻りたいので、git reset --hard HEAD@{1}
を実行します。
実行を行うことで、コミットも元通り、変更内容も復活します。
間違えて必要なブランチ消しちゃった
続いて、間違えてmaster
にいる状態でbranch1
を削除してしまった場合を考えます。
削除後のgit reflog
の結果は以下の通りです。
$ git reflog
4a4125a (HEAD -> master) HEAD@{0}: checkout: moving from branch1 to master
9d0bac1 (branch1) HEAD@{1}: commit: Create branch1.txt
4a4125a (HEAD -> master) HEAD@{2}: checkout: moving from master to branch1
間違って削除をしてしまったブランチに戻りたいです。
git reflog
を見ると、HEAD@{1}
でbranch1
でのコミットを作っていたようです。
そこで、git branch branch1 HEAD@{1}
を実行します。そうすることで、HEAD@{1}
までの作業履歴をbranch1
としてコピーすることができるので、ブランチが復活します。
git commit --amend
でコミットに不要な変更混ぜちゃった
branch1
でbranch1-2.txt
というファイルを作成し、新たにコミットを作るはずが誤ってgit commit --amend
を用いて一つ前のコミットに変更を混ぜてしまったとします。
git reflog
の結果は以下の通りです。
a04365e (HEAD -> branch1) HEAD@{0}: commit (amend): Create branch1.txt
9d0bac1 HEAD@{1}: checkout: moving from master to branch1
一旦コミットを取り消し、再度コミットを作り直したいです。
HEAD@{1}
に作業だけ戻り、ファイルの変更は残しておければそのままコミットを作り直せそうです。
そこでgit reset --soft HEAD@{1}
を実行し、作業だけ巻き戻します。
これでファイルの変更は残しておいたまま、作業だけ取り消せたのでコミットを作り直すことができます。
まとめ
git reflog
自体はただ履歴を確認するためのシンプルなコマンドですが、それを応用することでいろんなやらかしを取り消すことができます。
ここで紹介したやらかし以外でも解決できることはたくさんあるので、もしGitを使って何かやらかしてしまった際はgit reflog
を使ってなんとかできないか考えてみてください。