git push が rejected になる原因と解決方法|non-fast-forward・branch protection・LFS対応
- 作成日 2026.06.25
- git
Git でリモートにプッシュしようとした時に頻発するエラー:
$ git push origin main
To github.com:user/repo.git
! [rejected] main -> main (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.
または:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:user/repo.git'
git push は Git 操作の最後の関門。せっかく書いたコードがリモートに送れない状況は本当にストレスです。
しかも、
- なぜ rejected されるのか分からない
git pullしてまた push、を繰り返してマージコミットが大量発生--forceでいいの?--force-with-leaseとの違いは?commit --amendした後の push が通らない- rebase 後の push が通らない
- branch protection で force push できない
- 100MB のファイルが原因?
- 初回 push でいきなり rejected
など、状況によって対処が分かれます。
本記事では、git push で発生する rejected エラーのすべての原因と解決方法を、現場で即使えるトラブルシューティングとして整理します。エラーの本質、pull --rebase vs merge、--force-with-lease vs --force、amend/rebase 対応、branch protection、Git LFS、初回プッシュ、pre-receive hook、ベストプラクティス、FAQまで完全網羅。この1本で push 関連のトラブルに自信を持って対処できます。
- 1. 結論:今すぐ試すべき3ステップ
- 2. まず押さえる:rejected エラーの本質
- 3. 【原因①】リモートが先行している(最頻出)
- 4. 【原因②】git commit –amend 後のpush
- 5. 【原因③】git rebase 後のpush
- 6. –force-with-lease vs –force
- 7. 【原因④】初回プッシュで rejected
- 8. 【原因⑤】Branch Protection(GitHub/GitLab)
- 9. 【原因⑥】大きすぎるファイル
- 10. 【原因⑦】pre-receive hook で拒否
- 11. 【原因⑧】間違ったブランチを指定
- 12. 解決パターン早見表
- 13. reflog による救済
- 14. CI/CD での push rejected
- 15. 安全なワークフロー
- 16. トラブルシューティング
- 17. よくある質問(FAQ)
- 17.1. Q1. pull –rebase と pull はどっちを使うべき?
- 17.2. Q2. force push はいつしていい?
- 17.3. Q3. –force-with-lease で stale info エラー
- 17.4. Q4. 共有ブランチで間違えてforce push した
- 17.5. Q5. branch protection を一時解除する権限がない
- 17.6. Q6. 巨大ファイルを誤ってcommit してしまった
- 17.7. Q7. push で改行コードエラー
- 17.8. Q8. リモートとローカルの差分確認
- 17.9. Q9. push 前に確認するベストプラクティス
- 17.10. Q10. GitHub Enterprise や GitLab Self-Hosted
- 17.11. Q11. main ブランチに直接 commit してしまった
- 17.12. Q12. git pull で merge commit を増やしたくない
- 18. 参考リンク・関連資料
- 19. まとめ
結論:今すぐ試すべき3ステップ
時間がない方向けに、最短の対処手順を示します。
ステップ1:状況確認
# リモートの最新状態を取得(push せず)
git fetch origin
# 現在の状況確認
git status
git log --oneline -5
git log --oneline origin/main -5
# 差分確認
git log HEAD..origin/main --oneline # リモートにあって自分にないコミット
git log origin/main..HEAD --oneline # 自分にあってリモートにないコミット
ステップ2:標準的な解決
# パターンA: リモートの変更を取り込む(推奨)
git pull --rebase origin main
git push origin main
# パターンB: マージで取り込む
git pull origin main
git push origin main
ステップ3:force push が必要なケース
# 自分の feature ブランチで rebase / amend した
git push --force-with-lease origin feature
# ⚠️ 共有ブランチでは絶対NG
詳細は以下で解説します。
まず押さえる:rejected エラーの本質
Git のプッシュルール
Git は 「リモートのコミット履歴を上書きしない」 ことを基本ルールとします。リモートに自分が知らないコミットがある場合、プッシュは拒否されます。
fast-forward とは
リモート: A → B → C
ローカル: A → B → C → D → E
git push → OK(remote が ローカルの祖先)
remote が A → B → C → D → E に「早送り」
non-fast-forward(rejected の理由)
リモート: A → B → C → F ← 誰かがF追加
ローカル: A → B → C → D → E ← 自分はD, E追加
git push → 拒否
リモートの F がローカルに存在しないため、上書きすると F が消える
これが non-fast-forward エラー。Git は データロスを防ぐためにプッシュを拒否。
エラーメッセージの種類
| メッセージ | 原因 |
|---|---|
(non-fast-forward) | リモートが先行 |
(fetch first) | リモートに新規コミット |
(needs force) | ローカルが履歴改変済み |
(stale info) | force-with-lease で remote が変更されている |
Cannot force-push to this protected branch | ブランチ保護 |
file is X MB, exceeds the maximum file size | 巨大ファイル |
pre-receive hook declined | リモート側hook で拒否 |
それぞれ対処が異なります。
【原因①】リモートが先行している(最頻出)
最も多いケース。他の開発者がプッシュしたか、Web UI でコミットがあった。
確認
git fetch origin
git log HEAD..origin/main --oneline
# a1b2c3d Fix bug in login
# e4f5g6h Update dependencies
リモートに自分が持っていないコミットがある。
解決A:merge で取り込む(標準的)
git pull origin main
# = git fetch + git merge
git push origin main
メリット:
- シンプル
- 履歴がそのまま残る
デメリット:
- マージコミットが増える
- 履歴が複雑になる
解決B:rebase で取り込む(推奨)
git pull --rebase origin main
# = git fetch + git rebase
git push origin main
メリット:
- マージコミットなし
- 履歴が線形でクリーン
デメリット:
- 自分のコミットハッシュが変わる
- コンフリクト解消を各コミットごとに行う場合がある
merge vs rebase
| 観点 | merge | rebase |
|---|---|---|
| 履歴 | 複雑(マージコミット) | 線形 |
| コンフリクト | 1回 | コミット毎 |
| コミットハッシュ | 維持 | 変わる |
| 共有ブランチ | 安全 | 注意(既プッシュ後は危険) |
| 推奨 | 共有ブランチ | フィーチャーブランチ |
デフォルト設定
# Git 2.27+ で警告される
hint: Pulling without specifying how to reconcile divergent branches is
hint: discouraged.
対処(推奨):
# 全体設定(rebase デフォルト)
git config --global pull.rebase true
# またはローカル設定
git config pull.rebase true
これで git pull が git pull --rebase と同じ動作に。
【原因②】git commit –amend 後のpush
直前のコミットを修正(amend)した場合:
# プッシュ済みコミットを amend
git commit --amend -m "Better commit message"
git push origin feature
# rejected: non-fast-forward
なぜrejected?
amend は新しいコミット(別ハッシュ)を作成。元のコミットを置き換えるため、リモートと履歴が乖離します。
解決
ブランチが自分専用なら force push:
git push --force-with-lease origin feature
他人と共有しているブランチでは絶対 NG。事前に通知 & 合意を。
推奨:amend 前の確認
# プッシュ済みかチェック
git log origin/feature..HEAD
# 何も出なければプッシュ済み
# まだプッシュしてない場合のみ amend が安全
【原因③】git rebase 後のpush
リベース後は全コミットのハッシュが変わるため、リモートと完全に履歴乖離:
git checkout feature
git rebase main
# 全コミットのハッシュ変更
git push origin feature
# rejected
解決
# 自分の feature ブランチで rebase した場合
git push --force-with-lease origin feature
公開済みブランチでは rebase 禁止
# ❌ main / develop など共有ブランチで rebase
git checkout main
git rebase feature
git push --force-with-lease origin main
# 他の開発者のローカル history と整合性崩壊
共有ブランチには merge を使う。
–force-with-lease vs –force
–force(強制上書き、危険)
git push --force origin feature
リモートの状態を問答無用で上書き。他人のコミットも消える。
–force-with-lease(安全版、推奨)
git push --force-with-lease origin feature
最後にfetchした時のリモート状態から変わっていなければプッシュ。誰かが新しくpush していたら拒否(自分のローカルでは見えない変更を保護)。
比較
| 観点 | –force | –force-with-lease |
|---|---|---|
| チェック | なし | リモート状態確認 |
| 他人のコミット保護 | ❌ | ✅ |
| 安全性 | 危険 | 安全 |
| 推奨度 | ほぼ非推奨 | 標準的なforce push |
alias で安全に
# git pushf で --force-with-lease を実行
git config --global alias.pushf 'push --force-with-lease'
# 利用
git pushf origin feature
これで誤って --force を打たない仕組みに。
【原因④】初回プッシュで rejected
新規リポジトリの初回プッシュで:
git init
git add .
git commit -m "Initial commit"
git remote add origin git@github.com:user/repo.git
git push -u origin main
# rejected: failed to push some refs
なぜ?
GitHub/GitLab でREADME/LICENSE/.gitignore を自動生成したリポジトリは、既に1コミットあります。ローカルとリモートに共通の祖先がない状態。
解決A:リモートの内容を取り込む
git pull origin main --allow-unrelated-histories
# 「無関係な履歴」も許可してmerge
git push -u origin main
解決B:ローカルで上書き(リモートのREADME等を捨てる)
git push --force origin main
リモートの README / LICENSE が必要なら事前に手動コピー。
推奨:リモートを空で作る
GitHub でリポジトリ作成時に 「Initialize this repository with」のチェックを全て外す。これで初回プッシュがスムーズに。
【原因⑤】Branch Protection(GitHub/GitLab)
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Cannot force-push to this protected branch
main / develop などのブランチが保護されている。
確認
GitHub: Settings → Branches → Branch protection rules
GitLab: Settings → Repository → Protected branches
対応A:プルリクエスト経由
# 別ブランチを作って PR
git checkout -b fix/my-changes
git push origin fix/my-changes
# GitHub/GitLab で PR 作成、Web で merge
これが推奨フロー。直接 push せず、PR/MR を通す。
対応B:保護の一時解除(管理者のみ)
GitHub の場合:
- Settings → Branches → 該当ルール編集
- “Allow force pushes” を一時的に有効化
- 作業後、必ず元に戻す
対応C:管理者に依頼
直接 push が必要なら、リポジトリ管理者にコンタクト。
【原因⑥】大きすぎるファイル
remote: error: GH001: Large files detected. You may want to try Git Large File Storage
remote: error: Trace: ...
remote: error: See https://gh.io/lfs for more information.
remote: error: File large_data.csv is 150.00 MB; this exceeds GitHub's file size limit of 100.00 MB
GitHub は1ファイル 100MB、リポジトリ合計1GB 推奨。
解決A:ファイルを削除
# 削除してコミット履歴からも除外
git rm --cached large_data.csv
echo "large_data.csv" >> .gitignore
git add .gitignore
git commit -m "Remove large file"
git push origin main
ただし過去のコミットにあると消えない。
解決B:履歴からファイル削除(破壊的)
# 全履歴から large_data.csv を削除
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch large_data.csv" \
--prune-empty --tag-name-filter cat -- --all
git push --force-with-lease origin --all
または git-filter-repo(推奨):
# インストール
pip install git-filter-repo
git filter-repo --path large_data.csv --invert-paths
git push --force-with-lease origin --all
解決C:Git LFS
# Git LFS インストール
sudo apt install git-lfs
git lfs install
# 大きいファイルを LFS で管理
git lfs track "*.csv"
git lfs track "*.zip"
git add .gitattributes
git commit -m "Track large files with LFS"
# 通常通り push
git add large_data.csv
git commit -m "Add data"
git push origin main
LFS は別の保管場所に大ファイルを保存し、Git リポジトリには参照のみ。
詳細はDocker no space left on device の記事(容量管理)も参照。
【原因⑦】pre-receive hook で拒否
remote: error: pre-receive hook declined
サーバー側の pre-receive フックがプッシュを拒否。
原因例
- コミットメッセージ規約違反
- ファイル名規約違反
- テスト失敗
- 秘密鍵・APIキー混入検知
- 巨大ファイル検知
解決
エラーメッセージをよく読む:
remote: ERROR: commit message must start with [JIRA-]
remote: error: pre-receive hook declined
→ コミットメッセージ修正:
git commit --amend -m "[JIRA-123] Fix bug"
git push origin feature
秘密情報の混入
remote: error: GH013: Repository rule violations found
remote: - A secret was detected
→ 該当ファイルから秘密情報を削除し、ローテーション:
# .env をうっかりコミット
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit --amend
# 秘密情報は必ずローテーション(無効化+新規発行)
【原因⑧】間違ったブランチを指定
git push origin
# rejected: ???
確認
git status
# On branch feature
# Your branch is up to date with 'origin/feature'.
# 自分が今どのブランチか
git branch --show-current
# upstream の設定
git branch -vv
修正
# 明示的に指定
git push origin feature
# upstream 設定
git push -u origin feature
または push.default 設定:
git config --global push.default simple
# 現在のブランチを同名で push(デフォルト)
解決パターン早見表
| 状況 | 解決コマンド |
|---|---|
| リモートが先行(通常) | git pull --rebase origin BRANCH && git push |
| マージで取り込みたい | git pull origin BRANCH && git push |
| amend した自分のブランチ | git push --force-with-lease origin BRANCH |
| rebase した自分のブランチ | git push --force-with-lease origin BRANCH |
| 初回プッシュ(リモートに既存) | git pull --allow-unrelated-histories origin main |
| ブランチ保護 | Pull Request 経由でmerge |
| 大きいファイル | Git LFS or 履歴から削除 |
| 共有ブランチで間違えた | 手動 revert(force push 禁止) |
| 意図せず amend した | reflog から復元、force push |
reflog による救済
force push で他人のコミットを上書きしてしまったら…
自分のローカルから復元
# reflog でこれまでの HEAD 履歴
git reflog
# d4e5f6g HEAD@{0}: push: ...
# a1b2c3d HEAD@{1}: commit: My work
# 7890abc HEAD@{2}: pull: ... ← 復元したい
# その時点に戻る
git reset --hard 7890abc
# 元の状態をpush
git push --force-with-lease origin main
他人のローカルから復元
# 他のメンバーのローカルに上書きされる前の commit があれば取得
git fetch origin
git reset --hard origin/main
または GitHub の Events / Activity から復元可能なケースも。
⚠️ 完全に消えるとリカバリ不能。force push は慎重に。
CI/CD での push rejected
GitHub Actions / GitLab CI で自動 commit/push する時に発生:
競合状態
# .github/workflows/auto-commit.yml
- name: Commit changes
run: |
git add -A
git commit -m "Auto update"
git push # ← 他のCIと同時実行で rejected
解決:pull –rebase 後 push
- name: Commit and push
run: |
git pull --rebase
git add -A
git commit -m "Auto update" || echo "No changes"
git push
# またはリトライ
- name: Push with retry
run: |
for i in 1 2 3; do
git pull --rebase && git push && break
sleep 5
done
rake task 作り方の記事、crontab 書き方 例の記事も自動化の参考に。
安全なワークフロー
1. 共有ブランチでは絶対にforce push しない
# ❌ 絶対NG
git push --force origin main
git push --force-with-lease origin develop
main / develop / 共有ブランチでは通常の push のみ。
2. feature ブランチでは –force-with-lease
# ✅ 自分のfeature ブランチなら OK
git push --force-with-lease origin feature/my-work
3. PR 経由のマージ
feature/my-work(force push可)
↓ Pull Request
main(force push禁止)
4. rebase の前に必ず pull
git checkout feature
git pull --rebase origin main
git push --force-with-lease origin feature
5. 定期的に rebase でクリーンに
# 朝に1回
git fetch origin
git rebase origin/main
長期間放置するとマージが大変に。
6. コミット粒度を細かく
# ❌ 1日溜めて一気にpush
# 100ファイル変更、1コミット
# ✅ こまめにcommit & push
git commit -m "Add feature skeleton"
git push
# 続けて作業
git commit -m "Implement logic"
git push
頻繁にpushすれば乖離が小さい。
7. リモートを fetch する習慣
# 作業開始前
git fetch origin
# pull は変更が確実な時だけ
fetch は副作用なし。pull は merge/rebase が発生。
トラブルシューティング
何度 pull しても rejected
ローカルとリモートで同じ問題を繰り返し起こしている可能性。
# 状態確認
git fetch origin
git status
# logで詳細
git log --graph --oneline --all -10
# 完全リセット(ローカルの変更を捨てる)
git fetch origin
git reset --hard origin/main
# ⚠️ ローカルの未push変更は失われる
Merge conflict が解消できない
# 状態確認
git status
# both modified: file.txt 等
# 該当ファイルを開いて手動編集
# <<<<<<< HEAD ... ======= ... >>>>>>> ブランチ名 マーカー削除
# 解消後
git add file.txt
git rebase --continue # rebase中の場合
git commit # merge中の場合
# rebase をやめたい
git rebase --abort
push が遅い・タイムアウト
# 大量のオブジェクト
git gc # ガベージコレクション
git push origin BRANCH
# またはSSH 設定確認
# ~/.ssh/config
# Host github.com
# ServerAliveInterval 60
詳細はSSH host key verification failed の記事も参照。
git push –force で誤って消した
# reflog から救済
git reflog show origin/main
# d4e5f6g refs/remotes/origin/main@{0}: update by push
# a1b2c3d refs/remotes/origin/main@{1}: update by push ← 戻したい
git push --force-with-lease origin a1b2c3d:main
ローカルにreflogが残っていれば復旧可能。
Permission denied (publickey)
これは別エラー。SSH鍵設定:
# 鍵の確認
ssh -T git@github.com
# 鍵生成
ssh-keygen -t ed25519 -C "your_email@example.com"
# 公開鍵を GitHub に登録
cat ~/.ssh/id_ed25519.pub
詳細はSSH host key verification failed の記事も参照。
Untracked working tree files would be overwritten by merge
# pull する前に未追跡ファイルが衝突
git status
# 該当ファイルを移動 or commit
mv conflicting_file conflicting_file.bak
git pull
よくある質問(FAQ)
Q1. pull –rebase と pull はどっちを使うべき?
| 状況 | 推奨 |
|---|---|
| feature ブランチで開発中 | pull --rebase |
| main/develop を更新 | pull(merge) |
| 履歴を線形に保ちたい | pull --rebase |
| マージコミットが許容される | pull |
Git 2.27+ なら pull.rebase=true をデフォルトに設定推奨。
Q2. force push はいつしていい?
自分専用のブランチで rebase/amend した時のみ。共有ブランチでは絶対NG。
Q3. –force-with-lease で stale info エラー
! [rejected] feature -> feature (stale info)
→ リモートが最後にfetchした時から変わっている。
git fetch origin
# 確認後
git push --force-with-lease origin feature
Q4. 共有ブランチで間違えてforce push した
# 自分のローカルで戻す
git reset --hard d4e5f6g # 元のcommit
git push --force-with-lease origin main
# できれば他のメンバーから完全な履歴をもらう
すぐにチームに連絡。
Q5. branch protection を一時解除する権限がない
→ リポジトリ管理者に依頼。または PR 経由でマージ。
Q6. 巨大ファイルを誤ってcommit してしまった
# pushしてないなら
git reset --soft HEAD~1
echo "large_file.bin" >> .gitignore
git add .gitignore
git commit -m "Add to gitignore"
# pushしてしまった場合
# git filter-repo で履歴から削除
Q7. push で改行コードエラー
warning: LF will be replaced by CRLF
Windows/Mac の混在。
# 自動変換の設定
git config core.autocrlf input # Linux/Mac
git config core.autocrlf true # Windows
Q8. リモートとローカルの差分確認
# リモートにあって自分にないコミット
git log HEAD..origin/main --oneline
# 自分にあってリモートにないコミット
git log origin/main..HEAD --oneline
# 両方
git log --left-right HEAD...origin/main
詳細はLinuxでファイル差分を確認する方法の記事も参照。
Q9. push 前に確認するベストプラクティス
git fetch origin
git status
git diff origin/main..HEAD
git log --oneline origin/main..HEAD
push 前に何を送るかを確認する習慣。
Q10. GitHub Enterprise や GitLab Self-Hosted
エラーメッセージは同じだが、企業独自の pre-receive hook がある可能性。エラー詳細を管理者に確認。
Q11. main ブランチに直接 commit してしまった
# プッシュ前なら
git branch feature/my-work # 新ブランチ作成
git reset --hard origin/main # main を元に戻す
git checkout feature/my-work
git push -u origin feature/my-work
# PR作成
Q12. git pull で merge commit を増やしたくない
# 全体設定
git config --global pull.rebase true
# fast-forward only
git config --global pull.ff only
# fast-forward可能なpullしか許可しない
参考リンク・関連資料
Git 公式
- git-push Documentation – push 公式
- Pro Git Book – 包括的なGitガイド
- Dealing with non-fast-forward errors(GitHub Docs)
関連ツール
- Git LFS – 大きいファイル管理
- git-filter-repo – 履歴書き換え
- pre-commit – クライアント側hook
関連記事(本サイト)
- Linuxでファイル差分を確認する方法 – diff/colordiff/vimdiff(git diffも)
- Linuxでプロセスをバックグラウンド実行する方法 – nohup/&/disown
- Linuxでシンボリックリンクを作成・確認・削除する方法 – ファイル管理
- SSH host key verification failed – SSH接続問題
- Docker no space left on device – ディスク容量管理
- crontab 書き方 例 – 定期実行
- rake task 作り方 – 自動化スクリプト
- Rails 8 アップグレードガイド – Rails 全般
まとめ
git push rejected エラー、要点を再整理します。
エラータイプ早見表
| メッセージ | 原因 | 解決 |
|---|---|---|
non-fast-forward | リモートが先行 | pull --rebase または pull |
fetch first | 同上 | 同上 |
needs force | 履歴改変済み | push --force-with-lease |
Protected branch | branch protection | PR経由 |
Large files | 100MB超 | Git LFS |
pre-receive hook | サーバhook拒否 | hook規約に従う |
解決の流れ
# 1. 状況確認
git fetch origin
git log HEAD..origin/main --oneline
# 2. 取り込み(推奨)
git pull --rebase origin main
# 3. 解決後 push
git push origin main
force push の安全運用
# ❌ 危険:他人のコミット消す
git push --force
# ✅ 安全:リモート変更検知で拒否
git push --force-with-lease
# 自分専用ブランチでのみ使う
ベストプラクティス
- 頻繁な pull: 朝・夕に rebase
- 小さい単位でcommit/push: 乖離を最小化
- 共有ブランチでforce push 禁止
- PR経由のmerge: branch protection 設定
pull.rebase=true: 全体設定で履歴クリーンalias pushf: force-with-lease をデフォルト- 大きいファイルはLFS
主なコマンド
git fetch origin # リモート情報取得
git pull --rebase origin main # rebase で取り込み
git push --force-with-lease origin BR # 安全な force push
git reflog # 操作履歴(救済)
git reset --hard origin/main # リモートに合わせる
これらの知識は、Git を使ったあらゆる開発作業で活用できます。本記事をブックマークしておけば、push 関連のトラブルに自信を持って対処できるようになります。
本記事は2026年6月時点の情報をもとに、Git 2.40+ での動作確認・公式ドキュメント・GitHub/GitLab のドキュメントに基づき作成しています。Git のバージョンや使用するホスティングサービスによって挙動が異なる場合があるため、最新の情報はGit公式ドキュメント、GitHub Docs、GitLab Docs もあわせてご確認ください。
-
前の記事
docker: Error response from daemon よくあるエラーと対処法まとめ 2026.06.25
-
次の記事
【完全版】Ruby/Rails「undefined method ‘X’ for nil:NilClass」エラーの原因と対処法|nilエラーの全パターン徹底解説 2026.06.25
コメントを書く