non-fast-forward拒否はforce要求ではありません。履歴の分岐と受信側の拒否を分け、保護を維持して取込み方を選びます。
| この記事の要点 |
|
このエラーの概要
git push 実行時に次のような拒否メッセージが返ってきます:
$ git push origin master
To gitserver:repo.git
! [remote rejected] master -> master (denying non-fast-forward refs/heads/master (you should pull first))
error: failed to push some refs to 'gitserver:repo.git'
# GitHub の場合の別パターン
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'github.com:user/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
「fast-forward でない」とは、リモートの履歴を直線的に進める形ではない push という意味です。更新前のリモート先端が送信するcommitの祖先でない更新です。分岐・巻戻し・別履歴・送り先間違いなどを実際のOIDで調べます。エラーだけでは誰の操作が原因か確定しません。
原因の典型
| 状況 | 意味 | 対処 |
|---|---|---|
| 他の人が先に push した | リモートが進んでいる | 未共有commitならrebase、共有済みならmerge等を検討。確認後に通常push |
git commit --amend 後 push | 旧commitとの関係を確認 | 未公開部分のみなら通常push候補。公開済みなら新branch等も検討 |
git rebase 後 push | 送信先が祖先か確認 | 祖先なら通常push候補。公開履歴変更は別途合意と保護確認 |
git reset --hard で過去戻し | 作業損失と履歴の巻戻しに注意 | 診断として実行しない。共有変更の取消しはrevert等を検討 |
| 保護ブランチで拒否 | GitHub/GitLab 設定 | 許可されたPR / MR経路でレビュー |
対処 1: 状況に応じて取込み方式を選び、再 push
他の人が先に push しただけなら、リモート最新を取り込んで自分のコミットを上に積み直します:
旧例の訂正・実行前の確認:このpullは現在branchへorigin/masterを取り込む例で、必ずmasterへ切り替わるわけではありません。先にstatus・branch・push URL・refspecを確認します。未共有の独自commitを積み直すときだけrebaseを選び、共有済みならmerge等を相談します。
# リモートの変更を取り込む(rebase で履歴をきれいに)
git pull --rebase origin master
# コンフリクトが出たら解決
# ファイルを編集 → git add → git rebase --continue
# 再 push
git push origin master
設定任せのgit pullはrebaseやff-onlyにもなり得ます。mergeを選ぶならgit pull --no-rebase等で方式を明示します。fast-forwardならmerge commitは作られず、分岐時も競合・依存・テストの確認が必要です。
対処 2: --force-with-lease の条件と限界
rebase / amend後でも強制pushが必須とは限りません。未公開commitだけを積み直して送信先の先端を祖先に含めれば通常pushできます。公開履歴を置き換える必要が本当にあるか、履歴を保ったmerge・revertや新しいbranchのレビューで済むかを先に判断します。
旧例の訂正・実行前の確認:以下の「推奨」「stale後に再度force」は旧コメントです。そのまま実行しません。stale時は停止して新しい先端と必要な変更を調べ、fetch→再forceを定型手順にしません。leaseも保護 / receive.denyNonFastForwards / hookを解除せず、--forceとの併用はleaseの検査も無効にします。
# 推奨: --force-with-lease
# リモートが自分が認識しているコミットから動いていない時のみ push 成功
git push --force-with-lease origin master
# 失敗した場合(他人が push 済 = 上書きすると消える)
# ! [rejected] master -> master (stale info)
# このときは pull --rebase で取り込んでから再度 force-with-lease
# 非推奨: 完全強制(他人の push があっても消す)
git push --force origin master
省略形のleaseは通常remote-tracking参照を期待値にします。手動やbackground fetchがその参照を進めると、未確認の他者commitを上書きする予定まで通り得ます。明示形 --force-with-lease=refs/heads/master:期待OID は比較する値を固定できますが、そのOIDの内容を捨ててよいかは人のレビューと合意が必要です。
対処 3: なぜ履歴書き換えになったか確認
旧例の訂正・実行前の確認:origin/masterはローカルの追跡参照で、常に現在のサーバー先端ではありません。取得refspecとpush先が一致するか確認し、fetchは追跡参照等を書き換える操作として別途実施します。reflogの日時や番号だけで復旧先を決めません。
# ローカルとリモートのログを比較
git log --oneline origin/master..master # ローカルにあってリモートに無い
git log --oneline master..origin/master # リモートにあってローカルに無い
# 直近の reflog(操作履歴)
git reflog -10
# amend / rebase 後はコミット SHA が変わる
git log --oneline -5
対処 4: 保護ブランチで拒否されている場合
GitHub / GitLab / Bitbucket では master / main を保護ブランチに指定し、直接 push を禁止できます。この場合のメッセージは少し違います:
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: At least 1 approving review is required by reviewers with write access.
対処は運用方針による:
- 正攻法: 別ブランチに push し Pull Request を作成、レビュー後マージ
- 保護で拒否されたら管理者にルールと許可されたレビュー経路を確認する。エラー解消のため保護を弱めない
- 緊急時も承認済みの事故対応手順で保全・影響評価を行う。サーバー直接resetで迂回しない
force を検討する前の判断基準
| シナリオ | 推奨手段 |
|---|---|
| 個人ブランチで自分しか触らない | 利用者・CI・PR等の参照と規則を確認。個人名だけで許可しない |
| feature ブランチを複数人で共有 | 周知だけでなく関係者の合意・退避・許可された経路が必要 |
| master / main / develop | 通常のレビュー / merge / revertを優先。通知だけで変更許可にならない |
| 公開 OSS の main | 公開利用者への影響が大きい。運用規則に従い履歴を保つ案を優先 |
force push の事故から復旧
復旧可能性は旧OIDの特定とオブジェクトの実在・到達可能性・保持期限に依存します。reflogは各ローカルの参照移動記録で、全員分やサーバー側に必ず存在するバックアップではありません。OIDだけ分かってもオブジェクトが失われていれば復元できません。活動ログから取得できる保証もありません。まず追加更新を止めて関係者と保全し、見つかった旧commitは新しい退避branch等に確保して内容を比較します:
旧例の訂正・実行前の確認:このreset --hardと再forceは復旧の標準手順ではなく、実行しません。hard resetは現在の作業を失い得て、再forceは事故後に追加された変更を再び除外し得ます。旧commitの実在と内容を確認し、別branchでレビューして必要な変更を通常の手続で反映します。
# 元のコミットを持っている人がいたら、その人のローカルから push
# または GitHub の場合 Events / Activity から SHA を発掘可能
# reflog から
git reflog
# abc123 HEAD@{2}: commit: lost commit
git reset --hard abc123
git push --force-with-lease origin master
FAQ
Q: pull --rebase でコンフリクトが大量に出る
A: 件数が少ない側を機械的に採用せず、必要な変更と依存を比較します。cherry-pickでも欠落や競合は起きます。進行中のrebaseを取りやめるなら--abortですが、途中に追加した作業まで完全復元する保証ではありません。
Q: --force-with-lease でも拒否される
A: stale infoは期待OIDの不一致を示し、権限・hook・保護等の拒否とは区別します。停止して相手先・期待値・実際の先端と差分を比較し、通常の取込み・新branch・管理者への確認を選びます。fetchしてleaseを更新しただけで再forceしません。
Q: 履歴を書き換えずに push したい
A: mergeは既存commitの親関係を保って統合する案ですが、競合解決で必要な変更を落とさない確認が必要です。独立した履歴や送り先間違いを通常mergeで解決できるとは限りません。
拒否を読み分けてから操作する
旧版にあった--sharedの説明は、git init --sharedが既定でreceive.denyNonFastForwardsを有効にするという条件です。bare作成一般や全サーバーに同じ設定があるという意味ではありません。この設定はforce付きの非fast-forwardも拒否します。旧版のサーバー側git reset --softという案は受信側の検査を迂回するため採用しません。管理者には設定 / hook / 権限を読取確認してもらい、保護を維持した解決経路を相談します。
送信先の先端が自分の祖先なら通常push候補、自分が遅れているだけならff-only候補、両側に独自commitがあればmergeまたは未共有部分のrebaseを検討します。秘密値の取消しならrevertだけで漏えいは解消しないため、資格情報の失効等も別途必要です。
通信しない確認例
Bashでrepoのトップから実行します。origin/masterは確認対象の例で、自動取得しません。URLやdiffには秘密情報が含まれ得るので出力を公開しないでください。引数が不正・参照が未取得なら停止します。
#!/usr/bin/env bash
set -eu
export GIT_OPTIONAL_LOCKS=0
if [ "$#" -ne 1 ] || [ ! -e .git ]; then
printf '%s\n' 'Run at a worktree root: bash inspect-rejection.sh origin/master' >&2
exit 2
fi
case "$1" in
refs/remotes/origin/*|origin/*) ;;
*) printf '%s\n' 'Pass a local remote-tracking ref, not a URL or option.' >&2; exit 2 ;;
esac
git rev-parse --verify "$1^{commit}" >/dev/null
git status --short --branch
git branch --show-current
git remote get-url --push --all origin
git config --show-origin --get-all remote.origin.fetch || test "$?" -eq 1
git rev-list --left-right --count "HEAD...$1"
git log --oneline --left-right --max-count=20 "HEAD...$1"
# No fetch, merge, rebase, push, ref update, or configuration write.
左右の件数は左がHEADだけ、右が指定参照だけにあるcommit数です。0/0でも作業ツリーやサーバー現在値の一致までは意味しません。比較の後に取込み方式を決め、通常pushが可能かを先に確認します。
明示leaseとdry-runの位置付け
合意された履歴変更を検討する場合に限り、確認済みの完全OIDを期待値として --force-with-lease=refs/heads/master:期待OID と明示refspec HEAD:refs/heads/master を指定し、まず --dry-run で予定を確認します。これはそのまま貼り付ける完成コマンドではありません。期待値を更新するたびに差分と合意を再確認します。--force-if-includesは省略形lease等の補助検査ですが、leaseなしや明示期待OID付きではno-opです。dry-runでは実更新しないので、実際の受信hook・保護・同時更新時の本実行成功や内容の安全を保証しません。
公式資料と検証範囲
2026年10月26日確認:pushのlease / dry-run、init --shared、receive.denyNonFastForwards、stashの保存 / pop / apply、rebaseの中断 / autostash、checkoutのindex参照、resetの範囲、cleanの予定表示、reflogのローカル記録。旧コードは比較資料として保持し、誤コメントは直前で訂正しています。追加例と合成履歴は隔離したローカルrepoで検証し、強制更新はdry-runのみで全ref不変を検査します。実サービスの保護 / hook / 権限、本番復旧、実clean / hard reset、全submodule構成を検証するものではありません。
子ページはありません
- fatal: remote origin already exists.
- fatal: '~' does not appear to be a git repository
- Cannot rebase: You have unstaged changes. Please commit or stash them.
- remote: error: denying non-fast-forward refs/heads/master (you should pull first)
- error: pathspec ... did not match any file(s) known to git.
- The following untracked working tree files would be overwritten by checkout
- fatal: Not a valid object name: 'master'.
- Unlink of file 'ファイル名' failed. Should I try again? (y/n)
- Another git process seems to be running in this repository
- error: Your local changes to the following files would be overwritten by checkout:
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09