Gitで間違ったコミットをリモートリポジトリに push してしまった後に、それを無かったことにするには、リモート側での作業が必要だと思っていたのですが、ローカルからの操作でもできることがわかったので備忘録的に書いておきます。
次の状態にあるとします。アルファベットはコミットだと思ってください。
リモート: A-B-C master ローカル: A-B-C-D master
ローカルで変更を加えてDの状態になっています。
git push すると次のようになるのですが、
リモート: A-B-C-D master ローカル: A-B-C-D master
ここで、D は間違いだったと気づきました。
リモートリポジトリの master のバックアップ用のブランチを作ります。これは必須ではありませんが、念のため。
% git push origin master:master_bak
これで次の状態になります。
リモート: A-B-C-D master A-B-C-D master_bak ローカル: A-B-C-D master
リモートの master ブランチを削除します。
% git push origin :master
リモート: A-B-C-D master_bak ローカル: A-B-C-D master
ローカルを一つ戻します。
% git reset HEAD^
リモート: A-B-C-D master_bak ローカル: A-B-C master
リモートに push します。
% git push origin master
リモート: A-B-C master A-B-C-D master_bak ローカル: A-B-C master
すべてが順調にいって master_bak が要らなくなったら削除します。
% git push origin :master_bak
リモート: A-B-C master ローカル: A-B-C master
最後のコミットを消す前にリモートリポジトリが誰かに pull されてたりしたら、その人が混乱するので一声かけるか、素直にあきらめましょう。
なんかもっと簡単にできるような気もするのですけどわかりませんでした。もっと良い方法を知っている人がいたら教えてください。
追記
コメントで id:akitsukada さんに教えてもらいました。
上記の
% git push origin :master % git reset HEAD^ % git push origin master
の手順は
% git push -f origin HEAD^:master
…と簡単にできるみたいです。
この場合はローカルのコミット状態は変わらないので、必要に応じて git reset などをやりましょう。