Ruby, Rails, Git再入門 git add, git commit, git pushの操作を各段階で取り消す方法

Sleeping dog

photo credit: Scott Kinmartin via photopin cc

Ruby on Rails チュートリアル:実例を使って Rails を学ぼうの手順通りにコピペしていると、タイトルのようなことは発生しない。だが、演習課題を解いている最中によくコマンドを間違ってしまう。そこで、その際の対応方法を調べたので、手順を記載する。

git addを取り消す

2つの方法がある。

$ git checkout [ファイル名]
$ git reset HEAD [ファイル名]

ただどちらもまだ一度もcommitされていないリポジトリに対して、addしたものは取り消しができない。

git commitを取り消す

ファイルの変更はそのままにコミットだけ取り消す

コミットだけ取り消したい(=ワーキングディレクトリの内容はそのままでコミットだけを取り消したい)、というコミットするファイルが不足していた場合などに以下のコマンドを実行する。

$ git reset --soft [commit id or HEAD等]

ファイルの変更とコミットも取り消す

コミットを取り消した上にワーキングディレクトリの内容も元に戻したい、という間違った対応をやり直したい場合などに以下のコマンドを実行する。git reset –softとgit checkoutを同時にするコマンド。

$ git reset --hard [commit id or HEAD等]

コミットをやり直す

コミットをやり直したい場合などに以下のコマンドを実行する。git reset –softとgit commitを同時に実行するコマンド。

$ git commit --amend -m "Initial commit"

コミットするファイルが抜けていた、といった場合はこのコマンドの直前にgit addしておけば一緒にコミットされる。

git pushを取り消す

git pushする前に間違いに気づけば良いが後で気づく場合もある。そんな時は以下のコマンドを実行する。

$ git push -f [変更を反映したいリモートブランチ、origin master等]

-fはforceの略で強制という意味。rm -rfと一緒。リモートとローカルに差異があろうが、問答無用で強制的にローカルをリモートに上書きするということ。

取り消すコマンドをやり直す

コマンドを取り消そうとしたら、勢い余って失敗する、ということは良くある。特にgit reset –softなどで対象をHEAD^といったように指定しているとね(実体験)。そんな時は以下のコマンドを実行する。

$ git reflog
f68cb7c HEAD@{0}: merge filling-in-layout-exercises-03: Fast-forward
a45a83c HEAD@{1}: checkout: moving from filling-in-layout-exercises-03 to master
f68cb7c HEAD@{2}: commit (amend): Finish filling in layout exercises 3

このコマンドを実行すると、HEADがどのように移り変わって来たのかを示すログが出力される。HEAD@{0}が現在のHEADの位置。ログの中からやり直ししたいポイント=コミットメッセージを見つけて、そこに向けて、git resetをし直せば良い。