2014年5月18日日曜日

git で作業を取り消したい!

gitでは作業がいろいろな方法で取り消せる。

以前ざっと調べたときにはそういうイメージを持ったのですが、
今回間違えてcommitしてしまって、
さらにpushまでしてしまい、
どうしたものか?と調べたことのまとめ。

結果的には、リモートまで行ってしまったものは『なかったことにできない』という理解。

reset について

基本的には、ローカルでの変更をなしにしよう、というときに使う。
3つの状態を整理しておく。
状態としては、ワーキングツリー、インデックス、HEADがある。
ワーキングツリーは、いま操作しているファイル、目の前にあるファイルの状態のこと。
インデックスは、commitするためにaddされているファイルのこと。
HEADは、ローカルリポジトリの最新ファイルのこと。

git resetは、上述した3つをどうするか?によってオプションが変わる。

$ git reset --soft HEAD^

ワーキングツリー、インデックスは変えずに、HEADの位置だけHEAD^に移動する。

$ git reset --hard HEAD^

ワーキングツリー、インデックス、HEADの位置すべてをHEAD^に移動する。

$ git reset --mixed HEAD^

ワーキングツリーを変えずに、インデックス、HEADの位置をHEAD^に移動する。

ややこしい。

rebase について

まず、rebaseの基本的な使い方を整理する。

rebaseは別ブランチの変更(commit)をいまいるブランチに取り込む方法の一つで、
mergeみたいにいまいるところの「後ろ」に加えるのではなく、
「前」に加える操作。もちろん、一番最初にというわけではなく、
別ブランチと共通の祖先、つまり分岐した部分にうまく追加する。

これをいまいるブランチの過去に対して実行すると、commitを選択して再commitできるようになる。つまり、そのとき、あるcommitを消してしまえばなかったことにできる、ということ。

$ git rebase HEAD~3

ただ、気をつけなくちゃいけないのは、すでに"push"してしまっていると、これ、リモートリポジトリに反映できないです。
ローカルではうまくいくので、しめしめ、と思っているとハマるので注意。

revert について

こちらも実行してしまったcommitをなかったことにするが、ログにちゃんと残る形で実行する。
そうすると、じつはうれしいことがあって、リモートリポジトリもちゃんと変更できる。

$ git revert HEAD

ただし、これも注意点があって。
このコマンドは一つのcommitを打ち消す、というのが機能。
なので、複数ある場合は一度に消されない。


0 件のコメント:

コメントを投稿