gitを使っているとよく目にするgit re○○○○というコマンド。
git reset,revert,rebaseなんかが挙げられるが、これらは結局どれをどういう時に使えばいいのか分かりづらい。
というわけで、調べた結果をまとめてみます。(半分以上昨日の講義のまとめ
レポジトリの状況を分かりやすく伝えるためsource treeを使用しています。
この記事用に一つのレポジトリを作り、masterからwork1,work2二つのブランチを切っています。
複数のブランチが関わるのは後半になります。
こんな状況
git reset
「なんかコミットミスったから元に戻したい!!」というときに『git commit 戻す』とかでググると出てくるこのコマンド。
resetという名前も相まって直感的にミスを無かったことにしてくれるコマンドである気がします。
git resetは正確には「HEADの位置を変更するコマンド」です。(ここでいう「HEAD」は、「現在の最新のコミット」の意味に等しい)
git resetにはいくつかのオプションがありますが、それによってリセットの度合いが異なります。
具体的に見ていきましょう。
こんな感じであるコミット(work1用の編集という一行を追加)をしたとして、
これをなかったことにしたい、という状況です。
- git reset --soft
こちらは指定したコミット番号の元へHEADを移動する(元に戻す)が、ステージ(ファイルがaddされたときに上げられる場所)とファイルそのものの状態は変わりません。
つまり、コミットしたという事実だけを消してくれており、以下のような状態。
- git reset --mixed
こちらは指定したコミット番号の元へHEADを移動し、ステージからも下ろします。しかし、ファイルは編集後の状態になっています。
このときは以下のようになっています。
ファイルは編集後の状態ですがステージからは下ろされていますね。
- git reset --hard
こちらは師匠曰く「最強のreset」らしく、よくググったときに「元の状態に戻す」という目的に対して出てくる気がします。
これを実行すると、指定したコミット番号へHEADを移動し、ステージからも下し、さらにファイルも編集前の状態に戻します。コミットだけでなくそのコミットに対するアクションそのものがなかったことになります。
最初の状態に戻っているのが確認できますね。
git revert
「pushミスったから元に戻したい!」という時に使うのがこのコマンド。
このような状況のとき、プッシュされた'add "まあ、どうでもいいか!" 'コミットを無かったことにしたい場合、取り消したいコミットに対してgit revertを行うことで、そのコミットと全く逆のコミットを行います。
つまり、ここで言うと「"まあ、どうでもいいか!"という行を消す」というコミットを行い、これをプッシュすることでリモートはプッシュ前の状態に戻ります。
「全く逆のコミットをする」というrevertの性質上、一連の複数のプッシュを消したい場合は新しいコミットから順にさかのぼっていくことが望ましいようです。
また、revertしたものをさらにrevertすることで、revert自体を無かったことにすることももちろんできます。
こういうことはあまりないでしょうけども。。
git rebase
複数のブランチで並行して編集を行い、以下のような状態になっているとします。
一連の流れを一つにする方法としてmaster(又は親ブランチ)にそれぞれをマージする方法が上げられると思いますが、master上でマージをするのは危険だし、ログも見辛くなってしまいます。
そんなとき使うといいのがこのgit rebaseです。
git rebase をすると、ほかのブランチの歴史を自分の元へ取り込むことができます。
実際に行うには、
くっつけたい枝のブランチになった状態で
git rebase [相手の側のブランチ名]とします。
すると、
このように、歴史が一つになります。
ちなみに、git rebase についてはhttp://liginc.co.jp/web/tool/79390に非常に分かりやすく載っています。とても参考になりました。
以上、git re○○○○についてでした。
昨日知ったことをまとめたので、間違っている箇所、足らない箇所等あるかと思います。
もし訂正や補足がありましたら、言っていただけると幸いです!
ではでは。