Git reset/rebase/revert
いろいろ元に戻したいときもある
git で戻す系の操作
編集をやり直したいとか commit をやり直したいとかいろいろとにかくやり直したい場面というのはやってくる。
push 前なら、git は考えうるほとんどのやり直しを実現してくれる。
checkout
編集した内容を取り消す。ただし、add されたものまでは取り消さない。
$ git checkout -- path/to/file
HEAD 時点に戻す。
$ git checkout HEAD path/to/file
git-checkout は、branch の切り替えだけでなく、ファイルパスを引数にすることでファイルの編集をある地点に戻す(たぶん checkout というコマンド名からすれば直感的)という挙動をする。
reset
add したのを取り消す。
$ git reset path/to/file
ワークツリー全体の add したのを取り消す。
$ git reset HEAD
1つ前のコミットを取り消す。ただし、手元の編集分はそのまま。
$ git reset HEAD^
1つ前のコミットを取り消す。そして手元の編集分もなかったことにする(--hard)。
$ git reset --hard HEAD^
取り消したコミットは、「ORIG_HEAD」で参照できる。
以下のようにすると、取り消したコミットとの差分を参照できる。
$ git diff ORIG_HEAD
rebase
rebase は、現在の差分のはじまり(分岐点)を変更する。
$ git checkout master
$ git pull
$ git co -b sample-branch
.-- sample-branch
/
D---E-- master
その後、master/sample-branch 両ブランチともに編集が進む。
[こんな状況とする]
A---B---C sample-branch
/
D---E---F---G master
現在は master は G までコミットが進んでいる
$ git rebase master
[こうなる]
A'--B'--C' sample-branch
/
D---E---F---G master
sample-branch での差分は、G から分岐したものになる。
カレントのブランチの派生元を操作するのが rebase
master から乖離した手元のブランチに、差分を取り込む場合に、
$ git rebase master
すると、master の差分を入れた後に、自分がブランチに入れていた差分が入る。
* rebase は他にもいろいろと機能がある。
revert
revert は指定するコミットまでtreeを差し戻す。
reset との違いは、コミットを取り消して差し戻したという作業が、履歴に残る。
$ git revert <HASH>
remote のコミットをやり直す
remote を操作するのは危なっかしいので推奨しないが、以下のようにすると、remote のコミットを強制的に消せる。
$ git push -f origin HEAD^:master