292
Help us understand the problem. What are the problem?

posted at

updated at

Organization

Gitを使ってやらかした時、git reflogさえ使えればわりかしなんとかなる

これは何

新人プログラマ応援イベントの参加記事です。

gitにはreflogというコマンドがあります。このコマンドを学んでおくとやらかしちゃった時も大体なんとかなるので記事にします。

git reflogってなに?

git reflogとは、Gitで操作履歴を見ることができるコマンドです。
例えば

  • branch1にチェックアウト
  • branch1branch1.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で必要な変更も消しちゃった

上の例で、例えばbranch1git 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でコミットに不要な変更混ぜちゃった

branch1branch1-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を使ってなんとかできないか考えてみてください。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
292
Help us understand the problem. What are the problem?