DevToolBox

git push rejected (non-fast-forward) の直し方

! [rejected] main -> main (non-fast-forward) は、リモートの履歴が 自分のローカルと直線的に繋がらない時に出ます。闇雲に --force すると他人の コミットが消えるため、段階的な直し方を押さえましょう。

non-fast-forwardmeans the remote has commits yours don't. Blind--force can erase teammates' work; use --force-with-leaseinstead.

TL;DR

1. 原因の切り分け / Diagnose

git fetch origin
git log --oneline origin/main..HEAD   # ローカル側の独自コミット
git log --oneline HEAD..origin/main   # リモート側の独自コミット

両方に独自コミットがあれば「真の分岐」、自分側だけなら「fast-forward 可能」、 相手側だけなら単なる「pull 忘れ」です。

2. ケース別の直し方 / Fix by case

状況 / Situationコマンド / Command備考 / Notes
同じブランチに他人が pushgit pull --rebase && git push衝突解決後 --continue
rebase / commit --amend したgit push --force-with-lease自分の feature branch 限定
誤ったコミットを残したくないgit reset --hard origin/main 後 pushローカル変更は消える。先に git stash
保護ブランチで弾かれるPR 経由に切り替えmain は force push 禁止が正解

3. --force-with-lease を使う理由 / Why --force-with-lease

--force は「上書き」。他の人が push した直後だと、その変更を黙殺して自分の履歴に 置き換えます。--force-with-lease は「私が最後に見たリモート状態と一致する場合に限り、 上書きを許す」という条件付き強制。事故を自動検知して止まります。

# ❌ 危険
git push --force

# ✅ 安全
git push --force-with-lease

4. 予防策 / Prevention

5. English summary

A non-fast-forward rejection means your local branch and the remote have diverged. If a teammate pushed first, run git pull --rebase then push. If you rewrote history locally (rebase, amend), use git push --force-with-lease — never plain--forceon a shared branch, as it silently overwrites other people's commits. On main/master, protect the branch and push via pull requests only.

関連ツール / Related tools

関連ガイド / Related guides