以前ざっと調べたときにはそういうイメージを持ったのですが、
今回間違えてcommitしてしまって、
さらにpushまでしてしまい、
どうしたものか?と調べたことのまとめ。
結果的には、リモートまで行ってしまったものは『なかったことにできない』という理解。
reset について
基本的には、ローカルでの変更をなしにしよう、というときに使う。
3つの状態を整理しておく。
状態としては、ワーキングツリー、インデックス、HEADがある。
ワーキングツリーは、いま操作しているファイル、目の前にあるファイルの状態のこと。
インデックスは、commitするためにaddされているファイルのこと。
HEADは、ローカルリポジトリの最新ファイルのこと。
git resetは、上述した3つをどうするか?によってオプションが変わる。
ワーキングツリー、インデックスは変えずに、HEADの位置だけHEAD^に移動する。
ワーキングツリー、インデックス、HEADの位置すべてをHEAD^に移動する。
ワーキングツリーを変えずに、インデックス、HEADの位置をHEAD^に移動する。
ややこしい。
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を消してしまえばなかったことにできる、ということ。
ただ、気をつけなくちゃいけないのは、すでに"push"してしまっていると、これ、リモートリポジトリに反映できないです。
ローカルではうまくいくので、しめしめ、と思っているとハマるので注意。
rebaseは別ブランチの変更(commit)をいまいるブランチに取り込む方法の一つで、
mergeみたいにいまいるところの「後ろ」に加えるのではなく、
「前」に加える操作。もちろん、一番最初にというわけではなく、
別ブランチと共通の祖先、つまり分岐した部分にうまく追加する。
これをいまいるブランチの過去に対して実行すると、commitを選択して再commitできるようになる。つまり、そのとき、あるcommitを消してしまえばなかったことにできる、ということ。
$ git rebase HEAD~3
ただ、気をつけなくちゃいけないのは、すでに"push"してしまっていると、これ、リモートリポジトリに反映できないです。
ローカルではうまくいくので、しめしめ、と思っているとハマるので注意。
revert について
こちらも実行してしまったcommitをなかったことにするが、ログにちゃんと残る形で実行する。
そうすると、じつはうれしいことがあって、リモートリポジトリもちゃんと変更できる。
ただし、これも注意点があって。
このコマンドは一つのcommitを打ち消す、というのが機能。
なので、複数ある場合は一度に消されない。
そうすると、じつはうれしいことがあって、リモートリポジトリもちゃんと変更できる。
$ git revert HEAD
ただし、これも注意点があって。
このコマンドは一つのcommitを打ち消す、というのが機能。
なので、複数ある場合は一度に消されない。