Gitコマンドで失敗してしまうこともあると思います。
今回はそんなときに私が使うコマンドをまとめていきたいと思います。
コミットしたけど、修正したい。
またはコミットメッセージが不適切で修正したい、という時はあると思います。
そういう時にamendオプションを使用することで、直前のコミットを修正することができます。
$ git commit --amend
ただ、すでに直前のコミットをプッシュ済みの場合、amendしたコミットはすでにリモートにあることになっているので、Force Pushしなくてはいけません。
$ git push -f origin my_branch
Force Pushは、複数の人と共同で作業していたりすると面倒なので極力使わない方が良いかと思います。
コミットしたけど、元に戻したい。
また、最新のコミットをテストせずに本番にあげたらエラーが起こり、すぐに元に戻したいことがあると思います。(私は何度かあります笑)
そういう時はrevertを使うことをオススメします。
後ほど出てくるresetと似ていますが、こちらは「元に戻した」ログを残すことができます。
特別な理由がない限り、「元に戻したログ」はあっても問題ないかと思います。
(一緒に開発している人にも分かりやすいです。)
基本的には直前のコミットを元に戻すので、直前のコミットのIDを調べます。
$ git log commit aaaaabbbbbbbcccccccddddd (HEAD -> my_branch, origin/my_branch) Merge: ..... Author: ...... Date: ...... ...... commit eeeeeeffffffgggggghhhhhh (origin/master, origin/HEAD)
このaaaaabbbbbbbcccccccdddddになります。
だいたい前3文字くらい指定すればよいので、このコミットをなかったことにします。
$ git revert aaaa
こうすると、新たに「元に戻したコミット」が生成され、実際のファイルも元に戻っているかと思います。
複数のコミットを打ち消す場合も、基本は直前のコミットをrevertしていくのがよいかと思います。
ただ、毎回打ち消しログができてしまうのが嫌な方は、下記のような方法もあるようです。
(こちらの記事を引用させていただきました。)
まずは打ち消したいコミットをrevertします。
(no-editをつけることでエディタが立ち上がらなくて済みます。)
$ git revert --no-edit 2a7824e1 $ git revert --no-edit eda48916 $ git revert --no-edit 007ac11a
その後、rebase -iで対象の打ち消しコミットを統合します。
$ git rebase -i HEAD~3
すると3つのコミットが統合されます。
逆にそもそもコミット自体をなくすこともできます。
個人的には、普通にやっていたらそこまで必要になる場面はないかと思っていますが、
私自身遭遇したのは、コミットしたら違うブランチだった、という時です。
(集中力が欠けています。)
複数ブランチを行ったり来たりしているとたまにやってしまいます。
そもそもそのブランチにこの修正をコミットしたくないし、本来のブランチに持っていきたい。。。resetはコミット自体をなくすことができますが、主に使うのはsoftとhardの2つの方法です。
上記の私のケースですと、コミットは消したいが、差分は別のブランチに持っていきたいので、以前の記事で解説しましたstashと併用して、下記のように実施します。
$ git reset --soft HEAD^
これで差分が戻ってくるので、あとは1度stashして別ブランチに移動します。
$ git add . $ git stash save 'tmp' $ git checkout another_branch $ git stash pop stash@{0}
これで元のブランチに戻って来ました。
ちなみにhardの場合は、
$ git reset --hard HEAD^
になります。
まさに先日やってしまったことです。
(ある意味これを一番書きたかった。)
別ブランチにコミットしてしまい、「あー、やっちまった。切り替えなきゃ」と思います。
あの時、大量の差分があったため、一から修正し直すのは面倒でした。
ただ、何を思ったか(集中力が切れていたと思います。)、`reset –hard`してしまいました。
もちろん差分もなかったことになります。
私は焦りました。またあの修正をしないといけないのか、と。
とりあえずGoogle先生に聞いてみたところ、なんと復旧させる方法がありました!
git reset –hardした内容を取り消す (git reset –hard, reflog, HEAD@{x}, 取り消してしまったコミットを元に戻す)
reset --hard
すると、git log
上からログが消えてしまいます。
ただ、reflogに記録が残っています。
reflogはまだちゃんと説明ができませんが、HEADの位置が動いたコマンドなどを記録しているようです。
reset --hard
した後も、ちゃんとその記録を確認することができます。
(上記の記事のサンプルを引用させていただきました。)
$ git reflog -n 5 74f21a7 HEAD@{0}: reset: moving to HEAD^^ <<--ここがさっき間違えてresetした地点 64606a0 HEAD@{1}: commit: third commit <<--取り消される前のコミット履歴が残っている 6be52a3 HEAD@{2}: commit: second commit 74f21a7 HEAD@{3}: commit: first commit
あとはこのHEAD@{1}
まで戻して上げれば良いです。
これも`git reset –hard`で実施します。
$ git reset --hard "HEAD@{1}"
これでコミットが復活したので、再度git reset --soft
から実施しました。
上記でまとめた他にも様々な便利技があります。
Gitの理解を深めるほど、ソース管理がしやすくなると思います。
まだ試したことがない方はぜひ試してみてください。