2024/02/13 22:13:39

Git reset/rebase/revert

[git]

いろいろ元に戻したいときもある

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
サイト内検索