Gitで勢い余って間違ったコミットを git push してしまった時、それを取り消す方法です。
目次
git push の取り消し方法
あ、間違って push しちゃった・・・
Git を使っていると、間違ってgit pushしてしまって、それを取り消したくなるようなケースは、時々あります。
- 間違えて master ブランチで作業して、中途半端なコミットを作ってしまった。しかもなぜか、間違って push してしまった・・・。
- チームで共有しているリモートレポジトリに push したが、テスト不足で思いっきりバグを含んでいたので、いったん取り消したい。
間違いは、誰にでもあります。間違ったらやり直せば良いのです。
git push したコミットを取り消す
それでは取り消しの方法です。解決の方針ですが、大きく2つの方針があります。
git push したコミットの取り消し方法の選択肢
- ?過ちを隠す :push した、コミットを取り消し、リモートから削除。無かったことにする。
- ?過ちを認める:間違いコミットを打ち消す「revertコミット」を作成して、追加 push する
天使と悪魔のささやき、というわけではないですが・・・、これらの手段は、状況によって使い分ける事になるでしょう。
方法1pushしたコミットを削除する
ローカル履歴から変更を取り消して、履歴を push しなおす
まずは悪魔の囁き(?)から?ですが、まず、ローカルでコミットを強制的に書き換えます。直前のコミットを取り消すだけならHEAD^を指定して、ブランチの先頭を一つ昔の戻します。
// 直前のコミットを取り消す git reset --hard HEAD^
この書き換えたブランチを pushしようとすると、リモートにある、以前のコミットとコンフリクト(リモートより歴史が短いブランチをプッシュしようとしている)してpushできません(エラーで怒られます)。
ここは強制させるオプションである「-f 」を付けて強引に上書きします。
// 強制的にPushする git push -f origin master
はい、これでリモートのmasterを修正できました。簡単ですね?
こっそり削除は、罪悪感を感じざるを得ない・・。よくやるけどね・・。
[参考]ローカルの変更内容はそのままで、 push 操作だけを取り消す(=リモートからだけ削除)
「いや、ちょっとまって、できればローカルの新しいコミットはそのままで、Push だけ取り消したいんだけど・・・。」なんていうわがままなケースもあるあもしれません。
そんな場合は、リモートのブランチ参照だけを取り消すことができます。強制的に戻したいコミットのSHA-1 を指定して、コロンで区切った目的地ブランチの指定を行います。
「<ローカルのコミット>:<リモートの参照>」という引数になります。下記は、リモートのmaster を8dj2dg に強制する例ですね。
// リモートの master 参照を強制に戻す
$ git push -f origin 8dj2dg:master
履歴を巻き戻すような git push はエラーになりますので、-f で強制することが必要です。
git push の引数の使用はやや複雑ですので、こちらもあわせてどうぞ。
注意点:
この修正の間に、push したリモートの master が誰にも見られていない事に注意しましょう。間違った master ブランチの先頭コミットから別の開発を開始してしまったチームメンバーがいたら、きっと怒られます。ばれないように、素早く、素早く行いましょう?。。
修正するのが、masterなどの共有された統合用のブランチではなく、トピックブランチだったり、一人だけで開発しているときはけっこうバシバシ使ってOKです。使い方を間違えると危ないけど、パワフルなやり方、くらいに捉えています。
こちらはpushの強制に関する参考記事です:
方法2git revert で取り消しコミットを作成する
こちらは比較的安全な取り消し方法です?。変更を打ち消すgit revert コマンドを使います。下の2つは同義で、HEADでの変更を打ち消すコミットを作成し、その前のHEAD^と同じ状態を作ります。。
// 直前のコミットを打ち消すコミット git revert git revert HEAD
例えば、複数のコミットならこのようにも書けます。
// 最新をふくめ、過去4つ分のコミットを打ち消す git revert HEAD~3
revertコマンドによって、過去のコミットをちょうど打ち消す、新しいコミットが追加されます。
あとは、push するだけ。新しいコミットなので、コンフリクトはしません、-f オプションは不要です。
git push origin master
このrevert は過去の歴史を書き換えない、比較的安全な取り消し方法ですが、どうしても不用意なコミットが増えて、履歴が見にくくなってしまうのが難点です。一人だけでの開発においては reset で取り消してしまったほうが分かりやすいので、revert はあまり使わないかもしれません。
こちら参考記事です:
しっかり状況をふまえて、使い分けよう。
git push の取り消しに関する参考情報
git push に関してです。
git revert の公式ドキュメントです。
僕もしょっちゅう間違ってPushしちゃうよ〜。取り消したい!