はじめに
誤ってリモートにpushしてしまったコミットを取り消したい場面は、開発をしていると一度は経験するのではないでしょうか。
git reset でローカルを戻した後、git push --force-with-lease でリモートにも反映する手順を紹介します。
前提
- 誤ったコミットがすでにリモートにpush済み
- そのコミットをなかったことにしたい(履歴から消したい)
手順
1. 現在の状態を確認する
git status
On branch release
Your branch is up to date with 'origin/release'.
nothing to commit, working tree clean
ワーキングツリーがクリーンであることを確認します。
2. ローカルのコミットを取り消す
git reset --hard HEAD^
HEAD^ は「直前のコミットの一つ前」を意味します。これでローカルの履歴が一つ前の状態に戻ります。
--hard を使うと、変更内容も完全に消えます。変更を残したい場合は --soft や --mixed を使ってください。
| オプション | コミット | ステージ | ワーキングツリー |
|---|---|---|---|
--soft |
取り消す | 残る | 残る |
--mixed(デフォルト) |
取り消す | 取り消す | 残る |
--hard |
取り消す | 取り消す | 取り消す |
3. リモートに強制プッシュする
ローカルだけ戻しても、リモートにはまだ誤ったコミットが残っています。リモートにも反映するために強制プッシュを行います。
git push --force-with-lease origin ${現在のブランチ名を指定}
--force ではなく --force-with-lease を使う理由
通常の --force でも強制プッシュはできますが、--force-with-lease のほうが安全です。
| コマンド | 挙動 |
|---|---|
--force |
無条件にリモートを上書きする |
--force-with-lease |
他の人がpushしていた場合は拒否してくれる |
自分がリセットしている間に、他のメンバーが同じブランチにpushしていた場合、--force だとその変更も消してしまいます。--force-with-lease なら、そのような状況を検知して拒否してくれるため、事故を防げます。
4. 結果を確認する
git log
意図通りの履歴になっていれば完了です。
注意点
チーム開発の場合は事前共有を
force pushはリモートの履歴を書き換えるため、同じブランチで作業している他のメンバーのローカルと不整合が起きる可能性があります。実行前に必ずチームに共有しましょう。
他のメンバーは以下のコマンドでリモートの状態に合わせることができます。
git fetch origin
git reset --hard origin/release
push前なら force push は不要
まだpushしていない段階であれば、git reset だけで十分です。force pushが必要になるのは、あくまでリモートに反映済みの場合のみです。
まとめ
| 手順 | コマンド |
|---|---|
| 状態確認 | git status |
| ローカルを戻す | git reset --hard HEAD^ |
| リモートに反映 | git push --force-with-lease origin <ブランチ名> |
| 結果確認 | git log |
誤pushの取り消しは焦りがちですが、手順自体はシンプルです。--force-with-lease を使うことを習慣にして、安全に運用しましょう。