症状

git commit --amend でコミットを修正した後、git push が rejected される。

    ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'origin/main'
  

結論:まずこれを確認

  • --amend はコミットを「書き換える」ため、リモートと履歴が分岐する
  • 解決には git push --force-with-lease を使う
  • 他の人と共有しているブランチでは使用禁止

操作フロー

    flowchart TD
    A[amend後にpushがreject] --> B{ブランチは自分専用?}
    B -->|Yes| C[git push --force-with-lease]
    B -->|No| D[force pushは危険]
    D --> E[新しいコミットで修正を追加]
    C --> F{pushできた?}
    F -->|Yes| G[完了]
    F -->|No| H[リモートが更新されている]
    H --> I[git fetch して状況確認]
  

よくある原因

  • 履歴の分岐: --amend は新しいコミットを作成し、古いコミットを置き換えるため
  • リモートに既にpush済み: amend前のコミットがリモートに存在する
  • 他の人がpush済み: 自分がfetch後に他の人がpushしている
  • ブランチ保護ルール: GitHubでforce pushが禁止されている
  • 権限不足: リポジトリへのwrite権限がない
  • 間違ったリモート指定: originが期待と異なるリポジトリを指している

操作手順

ステップ1: 現在の状態を確認する

    git status
  

🔍 チェックポイント: 「Your branch and ‘origin/xxx’ have diverged」と表示されれば、履歴が分岐している

ステップ2: リモートとの差分を確認する

    git log --oneline origin/main..HEAD
git log --oneline HEAD..origin/main
  

🔍 チェックポイント:

  • 1つ目のコマンドでローカルにしかないコミットが表示される
  • 2つ目のコマンドでリモートにしかないコミットが表示される
  • 2つ目が空なら、自分のamendのみが原因

ステップ3: ブランチが自分専用か確認する

    git log --oneline -5 origin/main
  

🔍 チェックポイント: コミットの作者が全て自分であれば、force pushしても他者への影響は少ない

ステップ4: force push を実行する(自分専用ブランチの場合)

    git push --force-with-lease
  

🔍 チェックポイント:

  • --force-with-lease--force より安全
  • リモートが予期せず更新されていた場合は失敗する

ステップ5: 共有ブランチの場合は新規コミットで対応する

    # amendを取り消して元のコミットに戻す
git reflog
# 該当するHEAD@{n}を探す

git reset --soft HEAD@{1}
git commit -m "修正内容を説明するメッセージ"
git push
  

🔍 チェックポイント: 履歴を書き換えずに、新しいコミットとして修正を追加する

NG行動(やってはいけないこと)

  • 共有ブランチで git push --force: 他の人の作業が消える可能性がある
  • --force を安易に使う: --force-with-lease を使う習慣をつける
  • 確認せずにforce push: git log で差分を確認してから実行する
  • mainブランチへのforce push: 多くのプロジェクトでは禁止されている
  • リモートの状態を確認せずに操作: git fetch で最新状態を取得してから判断する

よくある質問(FAQ)

Q1: --force--force-with-lease の違いは?

A: --force は無条件で上書きする。--force-with-lease は、ローカルが把握しているリモートの状態と実際のリモートが一致する場合のみ上書きする。他の人がpushしていた場合は失敗するため、より安全。

Q2: ブランチ保護でforce pushできない場合は?

A: GitHubの Settings > Branches > Branch protection rules でforce pushが禁止されている。管理者に相談するか、新しいコミットで修正を追加する方法を取る。

Q3: 間違えてforce pushしてしまった場合の復旧方法は?

A: git reflog でforce push前のコミットハッシュを探し、git push --force origin <hash>:main で復元できる可能性がある。ただし、他の人がfetchしていた場合は完全な復旧は難しい。

関連するトラブル

準備中

解決しない場合