Gitコマンド入門::restore(marge,その3,reflog)「第十三回」
「第十二回」までの振り返り
みなさん、こんにちは! 前回は、ブランチmainから、ブランチsubを作成して、それぞれで、README.md を追加編集して、mergeするところまで学習してきましたが、いかがでしょうか?
とにかく、コミットさえして置けば、その履歴を辿って元に戻すことが容易にできるのが、gitの便利なところですね。また、両者が同一ファイルを編集していても、そのファイルの差分に対して、一応は自動でファイルにコメント挿入してくれるので、それもちょっと助かりそうです。まあ~ここまでにも何回か話題にましたけど、基本は複数に人数で同じファイルを編集しないように、ファイルを分けるのが、基本中の基本ですので、なんでもかんでも、gitに頼りすぎないようにしましょう!(苦笑)
前回の記事はこちらになります。
git reset を元に戻すには? git reflog を使う!
そして、第十一回使った、git reset --head コマンドですが、これとワンセットで覚えて欲しいのが、git reflog ですね。まずは、実際に、コマンドを打ってみましょう!
$ git reflog
c72eda2 (HEAD -> main) HEAD@{0}: reset: moving to HEAD@{6}
b8c6432 HEAD@{1}: reset: moving to HEAD^
c06db10 HEAD@{2}: reset: moving to HEAD^
c72eda2 (HEAD -> main) HEAD@{3}: reset: moving to c72eda2
c06db10 HEAD@{4}: reset: moving to HEAD^
c72eda2 (HEAD -> main) HEAD@{5}: checkout: moving from sub to main
73bb8d5 (sub) HEAD@{6}: checkout: moving from main to sub
c72eda2 (HEAD -> main) HEAD@{7}: commit (merge): main sub merge
c06db10 HEAD@{8}: commit: 3rd main
b8c6432 HEAD@{9}: checkout: moving from sub to main
73bb8d5 (sub) HEAD@{10}: commit: 3rd sub
b8c6432 HEAD@{11}: checkout: moving from main to sub
b8c6432 HEAD@{12}: checkout: moving from main to main
// 以下、HEADが変更された履歴分が表されますね。
[2]
HEADが移動するのは、以下3つのパターンですね。- commit: コミットしたとき。ここでは、README.mdを、commit した時
- checkout: ブランチ間で移動したとき。ここでは、main,sub の切り替え!
- reset: 任意の地点に移動したとき。過去にも未来にも移動可!
それでは実際に、3rd subに戻って、また今の地点に戻ってくるように、コマンド操作をしてみましょう!
$ git log --oneline
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
ハッシュ値の長さは40桁ですけど、指定するときの最小桁数は、どこまで短くできるのかな?![考察]
$ git log --oneline HEAD
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git log --oneline c72eda2 // まずは、通常の7桁 good!
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git log --oneline c72eda // 6桁 good!「末尾の2を削って!」
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git log --oneline c72ed // 5桁 good!「末尾のa2を削って!」
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git log --oneline c72e // 4桁 good!「末尾のda2を削って!」
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git log --oneline c72 // 3桁 bad!「削りすぎでした!」
fatal: ambiguous argument 'c72': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
まあ~、当初から、所々で40桁ではなく、7桁で省略表示されていたので、どうしてかな? って、私も不思議でしたけどね。どうやらgit側で勝手にそう暗示してくれていたんですね。7桁も指定すれば、問題なく指定できますよ!・・・ってことなんです。(笑)
完全に脱線してしまいましたけど、本題のHEADを過去に戻して、また、現在に戻す方法を実行しましょう!
[3]
(sub) 3rd subへ、git reset --hard 73bb8d5$ git log --oneline
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub // ここに戻るので、7桁のハッシュ値を確認!
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ git reset --hard 73bb8d5 // git reset --hard sub も可
HEAD is now at 73bb8d5 3rd sub
$ git log --oneline
73bb8d5 (HEAD -> main, sub) 3rd sub // 成功!
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ cat README.md
# test
# (^^)
# sub add
// ブランチsub側で、行を追加した状態に戻っています!
git reflog で、リストの中から、commit (merge): main sub merge の行を探して、ハッシュ値を取得!
$ git reflog | grep 'main sub merge'
c72eda2 HEAD@{8}: commit (merge): main sub merge
ということで、ハッシュ値、c72eda2 の7桁を指定するか、HEAD@{8} のどちらかを使って、元の状態に、HEADを戻しましょう! git reset --hard c72eda2 or HEAD@{8}
$ git reset --hard c72eda2 // 今回は7桁のハッシュ値を指定
HEAD is now at c72eda2 main sub merge
$ git log --oneline // HEADが元の最新の位置に戻ったか?
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
// 無事に戻っていますので、最後に、README.mdの中身も!
$ cat README.md
# test
# (^^)
# main add
# sub add
// main subの両方をマージした内容に戻っています!
$ git reflog // 最後に、もう一度、reflogを見てみましょう!
c72eda2 (HEAD -> main) HEAD@{0}: reset: moving to c72eda2
73bb8d5 (sub) HEAD@{1}: reset: moving to sub
// 最初の2行のみ、以下、省略。
これで、一通りの操作が可能になりましたね。もう、git reset コマンドの恐怖や不安も解消されてきたと思います。頭が真っ白になることもない事でしょう。そう、、、全ての履歴が残っているのですからね。
では、初期状態に戻る練習をして、終わりにしましょう!
$ git log --oneline
: // コロンマークが出たら、q=quitで終了、改行で一行表示、スペースキーを押すと、
最後まで出力します。ここでは、最終行の末尾を確認したいので、スペースキー[改行]
a467fbd (origin/main) HEAD@{129}: checkout: moving from main to main
a467fbd (origin/main) HEAD@{130}: Branch: renamed refs/heads/master to refs/heads/main
a467fbd (origin/main) HEAD@{132}: commit (initial): first commit
// ハッシュ値の確認ができましたね。first commit 懐かしい!(笑)
// 一応、git log で詳細常時で確認!
$ git log a467fbd // HEAD@{129} HEAD@{130} HEAD@{132} も同じ結果
commit a467fbdd7e989b224f388e048823068a0f122d51 (origin/main)
Date: Wed Feb 10 15:28:42 2021 +0900
first commit
$ git reset --hard a467fbd
HEAD is now at a467fbd first commit
$ git log
commit a467fbdd7e989b224f388e048823068a0f122d51 (HEAD -> main, origin/main)
Date: Wed Feb 10 15:28:42 2021 +0900
first commit
$ cat README.md
# test
// ファイルの中身が一行のみ、初期状態の内容になっています。
// これで、初期状態のコミットに移動できました!
// では、また、最新のHEADに戻しましょう!
$ git reflog // 今回も最初の3行ぐらいまで表示しておきます。
a467fbd (HEAD -> main, origin/main) HEAD@{0}: reset: moving to a467fbd
c72eda2 HEAD@{1}: reset: moving to c72eda2
73bb8d5 (sub) HEAD@{2}: reset: moving to sub
// 3行目は、前回、HEADをsubに移動したログが記録されてます。
// 2行目は、それを元の最新のHEADに戻したログが記録!
// 1行目は、そして今、一番最初の状態にHEADを移動したログが記録!
// 戻す方法は、以下の2通りどちらでも!
// $ git reset --hard c72eda2 // 7桁のハッシュ値を指定
// $ git reset --hard HEAD@{1} // 前回のコマンドを再利用も可能!
// 今回は、HEAD@{1}で、挑戦してみます!
$ git reset --hard HEAD@{1}
HEAD is now at c72eda2 main sub merge
// はい、無事に、HEAD@{1}==c72eda2 となっています!
$ git log --oneline
c72eda2 (HEAD -> main) main sub merge
c06db10 3rd main
73bb8d5 (sub) 3rd sub
b8c6432 2nd commit
a467fbd (origin/main) first commit
$ cat README.md
# test
# (^^)
# main add
# sub add
// ハイ!・・・手品ではありませんけど!ワオー!歓声!
これで、もう、そろそろ慣れたと思いますが、いかがでしょうか?
又、HEAD@{1}=='c72eda2' だとイメージすることが、今回のコマンド操作でも理解できたと思います。まあ、HEADを移動するたびに「commit,checkout,resetコマンド操作」HEAD@{xx} の配列の中に、その時のハッシュ値を保存しているんですよね~ 尚、{xx}のインデックスは、随時変化するので、その都度、git reflog
で確認してくださいね。
それでは、今日はここまで、長い間、本当にお疲れさまでした!
Discussion