pushしてはじめて「やってしまった」と気づくミスは多いものです。機密情報をうっかり含めた、間違ったブランチに直pushした、テストが通っていないコミットをmainに流した、マージの方向を間違えた——どれもpush後だからこそ対応が難しい問題です。
この記事では、push後の取り消しに特化して実践的な対処法を解説します。共有後の履歴書き換えリスクを踏まえた判断基準、git revertによる安全な打ち消し、やむを得ない場合の--force-with-leaseの使い方、機密情報漏洩時の緊急対応、そしてチーム運用で気を付けるべき点までまとめます。コミット自体の取り消し方は【Git】コミットの取り消し方に詳しいので、本記事は「push後どう動くか」にフォーカスしています。
この記事で学べること
- push後の取り消しで確認すべき4つの質問(保護ブランチ・共有範囲・機密性・単独作業)
- 最推奨ルート:
git revertで打ち消しコミットを追加する方法 - 個人ブランチに限って使う
--force-with-leaseの安全な使い方 - 機密情報をpushしてしまったときの緊急対応(rotate→履歴書き換え)
- 間違った共有ブランチに直接pushしたときのリカバリ手順
git push --forceで壊してしまったリモートをreflogで救う方法- チーム運用でpush取り消しの影響を最小化する作法
まず確認:4つの質問で取り消し方が決まる
push後の取り消しは「履歴を書き換えるか」「打ち消しコミットで追記するか」の選択です。この選択を間違えると他メンバーのローカルを破壊したり、機密情報が履歴に残り続けるといった二次被害が発生します。以下の4つを必ず確認してから行動してください。
基本原則:「押したらもう戻せない」と考え、原則revertで打ち消しコミットを追加するのが最も安全です。git push --force/--force-with-leaseは自分しか触っていない個人ブランチ限定の武器として使い分けましょう。
最推奨:git revert で push済みコミットを打ち消す
push後の取り消しは、原則としてgit revertで打ち消しコミットを追加します。履歴を書き換えないため、他メンバーのローカルに影響を与えません。pushした瞬間に「やってしまった」と気づいたら、まずこれを検討してください。
# 取り消したいコミットのSHAを確認 git log --oneline -5 # 単一コミットを打ち消す(打ち消しコミットが追加される) git revert <SHA> # エディタでコミットメッセージ編集が開くので保存して閉じる # 打ち消しコミットをpushして完了 git push origin <branch>
複数のpush済みコミットをまとめて打ち消す
直近N件をまとめて取り消すなら範囲指定が便利です。A^..B記法でAからBまでを逆順に打ち消します。
# 直近3件をまとめて打ち消す(新しいものから順に打ち消しコミット作成) git revert HEAD~2..HEAD # 中間コミットだけ打ち消したい場合 git revert a1b2c3d^..f4e5d6a # 打ち消しコミットを個別に作らず、1つにまとめたい git revert --no-commit HEAD~2..HEAD git commit -m "revert: 直近3コミットの変更を一括で打ち消し" # 最後にpush git push origin <branch>
pushしてしまったマージコミットを打ち消す
マージコミットには親が2つあるため、-mで「どちらの親を基準に戻すか」を指定します。mainに機能ブランチをマージしてしまった場合、mainを基準(-m 1)にして打ち消すのが通例です。
# マージコミットのSHAを確認 git log --merges --oneline -5 # -m 1 で親1(マージ先ブランチ)を基準に打ち消し git revert -m 1 <マージコミットSHA> git push origin <branch>
ポイント:revert済みのコミットを後から再適用したい場合、単に再マージすると「打ち消しコミットがあるせいで取り込まれない」ことがあります。その場合は「打ち消しコミット自体をさらにrevertする」か、cherry-pickで個別にコミットを持ち込む必要があります。
revertの詳細(コンフリクト解消、--no-commitの使い方など)はコミットの取り消し方ガイドとmergeコミットを取り消して履歴を元に戻す方法も参照してください。
個人ブランチ限定:–force-with-lease で安全に履歴を書き換える
自分しか触らない個人ブランチでpushしてしまった場合は、履歴を書き換えてpush --force-with-leaseする選択肢があります。「push前の状態に戻す」「コミットメッセージを修正する」「不要なコミットを削除する」ときに使います。
–force と –force-with-lease の違い
--forceは無条件でリモートを上書きしますが、--force-with-leaseは「リモートが自分の想定通りの状態なら上書き、違ったら拒否」という安全装置付きです。これにより、他メンバーが間に何かpushしていた場合の事故を防げます。
# 危険:他人のpushを知らずに上書きしてしまう可能性 git push --force origin feature/my-branch # 安全:リモートが自分のローカルのorigin/xxxと一致していればpush、違えば拒否 git push --force-with-lease origin feature/my-branch # さらに明示的に「この状態なら上書きOK」を指定(Git 2.30+) git push --force-with-lease=feature/my-branch:<期待SHA> origin feature/my-branch
pushを巻き戻す典型例
# push前に最新リモートを取得して判定を正確に git fetch origin # 1コミット前まで戻す(変更も完全破棄) git reset --hard HEAD~1 # 安全チェック付きでpush git push --force-with-lease origin feature/my-branch # 「stale」エラーが出たらfetchし直してから再度試す git fetch origin git push --force-with-lease origin feature/my-branch
禁止事項:main/develop/master等の保護ブランチにforce pushは絶対に行わないでください。GitHub/GitLabの設定で物理的に禁止するのが安全です。保護ブランチでの取り消しは必ずrevert+PRで行います。
force push前のチェックリスト
実行前に必ず確認
- このブランチは自分しか触っていないか?
- 保護ブランチではないか?(GitHub Settingsで確認)
- 他メンバーがこのブランチをベースに作業していないか?
- PRをレビュー中のブランチで、レビュアーの作業が無駄にならないか?
- 最新の
git fetch originを済ませたか?
誤ってmainやdevelopに直接pushしてしまった
「PRを作らずにmainにpushしてしまった」は頻出事故です。基本方針はrevertで打ち消してから、そのコミットを正しいブランチに移動します。
# 1. 打ち消したいSHAを確認(直近のpushコミット) git log --oneline -3 # 2. 新しい作業用ブランチを作って、そこにコミットを持っていく git switch -c feature/recover-push <誤pushしたSHA> git push -u origin feature/recover-push # 3. main に戻ってrevertで打ち消し git switch main git pull origin main git revert <誤pushしたSHA> git push origin main # 4. feature/recover-push からPRを出して通常のレビューフローに乗せる
ポイント:誤pushに気付いた瞬間に「force pushで消せばいい」と考えがちですが、CIが走ったりSlack通知が飛んでいたりする可能性があるため、履歴は残したままrevertで打ち消す方が後々のトラブルが少ないです。保護ブランチ設定が未導入なら、これを機にGitHubのBranch protection rulesを有効化しましょう。
保護ブランチの運用詳細はGitHub公式ドキュメントやDevOps系のガイドを参照してください。この記事では取り消しの手順にフォーカスします。
機密情報(APIキー・パスワード)をpushしてしまった
これはpush取り消しで最も緊急度が高いケースです。GitHubのパブリックリポジトリならpushした瞬間に世界中のbotがクロールし始めます。「取り消す」より「既に漏洩したものとして扱う」のが鉄則です。
絶対に最初にやること:漏洩した認証情報を即座にrotate(無効化・再発行)してください。AWSキー・DBパスワード・APIトークン・SSH秘密鍵——すべて使えなくしてから、Git側の履歴処理に進みます。履歴を消しても、一度pushされた情報は既にキャッシュ・ミラー・botに取得されている前提で動きましょう。
緊急対応フロー
# STEP 1: 認証情報を即時rotate(AWS Console・DB・APIサービス側で対応) # STEP 2: .gitignore に該当ファイルを追記 echo "config/secrets.env" >> .gitignore git add .gitignore git commit -m "chore: add secrets.env to .gitignore" git push # STEP 3: git filter-repo で履歴から該当ファイルを完全削除 # (BFG Repo-Cleaner でも可。filter-branch は非推奨) pip install git-filter-repo git filter-repo --path config/secrets.env --invert-paths # STEP 4: 履歴書き換え後は全員再clone推奨。強制pushで共有 git push origin --force --all git push origin --force --tags # STEP 5: GitHubのSecret Scanningアラートを確認(有効化されていれば) # STEP 6: 漏洩対象に応じて社内インシデント報告
注意:filter-repoは履歴を全面書き換えるため、全メンバーの再cloneが必要になります。チームに事前通知し、進行中のPR・作業中のローカル作業を退避してもらってから実行してください。詳細は履歴に含まれる機密情報を完全に削除する方法を参照。
force pushで壊したリモートをreflogで救う
git push --forceで誤って他人のコミットを消してしまった、間違ったブランチをforce pushしてしまった——そんなときもpush直後なら救済可能です。リモート側のreflog(サーバーサイド)、もしくはチームメンバーのローカルreflogから失われたSHAを探し出します。
# ローカルreflogでpush前のSHAを探す
git reflog
# 出力例:
# a1b2c3d HEAD@{0}: reset: moving to HEAD~3
# e4f5g6h HEAD@{1}: commit: 消してしまったコミット
# 消えたSHAが分かれば、そこからブランチを作って復元
git switch -c recover/lost-work e4f5g6h
git push -u origin recover/lost-work
# GitHub側のreflogを使う(管理者権限があれば)
# Repo設定 → Events / APIで確認 or GitHub Support に問い合わせ
ポイント:消えたように見えるコミットも、GitHubのサーバー側には通常約90日間残っています(参照されなくなっただけ)。PRをベースに作業していた場合は、PRページのcommitsタブから消えたSHAを確認できることもあります。諦める前にまずPRとreflogを確認しましょう。
チーム内でまだそのブランチを触っている人がいれば、その人のローカルに完全な履歴が残っています。依頼してgit pushしてもらえば元に戻せます。
取り消し方法の選び方フロー
実務でpush後に直面する代表的ケースと推奨アクションをまとめました。
チーム運用:取り消しの影響を最小化する
pushの取り消しは技術的な操作に加えてチームへのコミュニケーションが重要です。無言で履歴を変更すると、他メンバーが混乱してpull失敗の原因になります。
push取り消し時の動き方
- force pushする前にSlack/チャットに予告する(対象ブランチ・影響範囲)
- 他メンバーに
git fetch --all --prune+作業退避を依頼 - 機密情報絡みならセキュリティチームに即時エスカレート
- 取り消し後は「何をどう直したか」をPRやコミットメッセージに残す
- 再発防止:Branch protection rules・pre-commit hook・Secret Scanning導入
# force push後にこれを各メンバーが実行 git fetch origin # 作業中のブランチを保全してから git stash # リモートに合わせてリセット(個人ブランチのみ) git reset --hard origin/<branch> # もしくは一度ブランチを消して取り直す git switch main git branch -D <branch> git switch <branch>
やってはいけない落とし穴
保護ブランチにforce pushする
mainやdevelopといった共有ブランチにforce pushすると、他メンバーのpull時にnon-fast-forwardエラーが発生し、最悪の場合はローカル変更をrebase/mergeで失う人が出ます。必ずrevertで打ち消しコミットを追加する方式にしてください。GitHubのBranch protection rulesでforce pushを物理的に禁止するのが根本対策です。
機密情報を「revertで打ち消せば解決」と考える
revertは履歴に打ち消しコミットを追加するだけで、過去のコミット内に含まれる機密情報はそのまま残ります。APIキーはgit log -pで誰でも拾えます。rotate→filter-repoでの履歴書き換えまでがセットです。
push –force を –force-with-lease と同じ感覚で使う
--forceは他人の作業を問答無用で消します。共同作業ブランチで使うと、本人が気付かないうちにチームメンバーの作業を破壊する事故が起きます。--force-with-leaseを既定にし、--forceは最終手段に留めましょう。gitエイリアスでforcepush = push --force-with-leaseと登録する運用が有効です。
force push後に事実を共有しない
履歴が書き換わった事実をチームに伝えないと、他メンバーのpull時に混乱を招きます。「force pushしました」「対象ブランチはxxx」「時刻はyyy」を明示し、メンバーにfetch&必要ならreset --hard origin/xxxを依頼しましょう。
force pushで消したコミットを諦める
push直後(90日以内)ならローカルreflog・GitHubサーバー側・他メンバーのローカルのいずれかに必ず履歴が残っています。慌ててさらに操作する前にgit reflogを確認し、SHAを特定してから救済ブランチを作りましょう。
よくある質問
--force-with-lease、それ以外はrevertです。迷ったらrevertを選ぶのが安全です。git revertするか、該当コミットを別ブランチでcherry-pickして持ち込みます。単純なmergeでは打ち消しが勝って取り込まれないケースがあります。origin/xxx)と一致していない状態です。git fetch originでリモート追跡を最新化してから再実行してください。他メンバーがpushしていた場合は、その内容を確認してから上書きするか判断します。revert+PR経由で行ってください。どうしても必要な緊急時は管理者権限でルールを一時解除します。git switch -c feature/xxx <誤pushSHA>で新ブランチを作ってpushし、mainではgit revert <誤pushSHA>で打ち消すのが定石です。詳細は過去コミットから新ブランチを作る方法も参考になります。git commit --amend+push --force-with-lease、共有ブランチなら既存メッセージは放置し、次のコミットで注記するのが無難です。詳細はコミットメッセージの変更方法を参照。関連記事
- 【Git】コミットの取り消し方 — reset/revert/amendの使い分け全体像
- 【Git】revertとresetの違いと使い分け — 概念の深掘り
- 【Git】mergeコミットを取り消して履歴を元に戻す方法 — マージ専用
- 【Git】履歴に含まれる機密情報を完全に削除する方法 — filter-repoの使い方
- 【Git】pushしようとしたら”non-fast-forward”で拒否されたときの解決方法 — force push前後のトラブル
- 【Git】リモートとローカルの履歴が食い違ったときの同期方法 — fetch/rebaseの選び方
- Gitで過去のコミットから新しいブランチを作り作業をやり直す方法 — 誤pushの救済に使う派生ブランチ
- 【Git】コミットメッセージの変更方法 — amendの詳しい使い方
- 【Git】誤ってmaster/mainを削除したときの復旧方法 — ブランチ消失系の事故対応
まとめ
- pushの取り消しは原則
revertで打ち消しコミットを追加するのが最も安全 - 個人ブランチかつ保護ブランチ外なら
--force-with-leaseで履歴書き換え可 --forceは避け、--force-with-leaseを既定にする- 機密情報pushは「rotate最優先」→
filter-repoで履歴削除 - mainへの誤pushは「新ブランチに移動→mainでrevert」が定石
- force pushで壊しても
reflog・GitHubサーバー・メンバーのローカルから救済できる - 技術的操作に加えチームコミュニケーションが欠かせない
push後の取り消しは「何を直したいか」ではなく「誰に影響するか」で判断するのがコツです。自分だけが影響する個人ブランチならforce系で素早く、共有ブランチならrevertで丁寧に——この基本を押さえれば、慌てずに正しいリカバリができます。あわせて保護ブランチ設定・Secret Scanning・pre-commit hookといった事故予防の仕組みを整え、そもそも取り消しが必要な状況を減らしていきましょう。

