Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

Git push 因 non-fast-forward 被拒?修復前先證明遠端參照

拒絕是圖結構安全訊號,不是要求強推。先確認目標參照與目前 OID,再抓取稽核副本,最後選擇合併、變基或經批准的明確 lease。

原創示意圖:共同基點、遠端 tip 與本地 tip 的 non-fast-forward 圖。
原創示意圖:共同基點、遠端 tip 與本地 tip 的 non-fast-forward 圖。 Watch at Ease

non-fast-forward 表示目標分支不是擬推送提交的祖先;接受更新會讓至少一個遠端提交從分支可見歷史消失。第一步應鎖定精確目標參照並保存遠端 tip,而不是盲目 pull 或 force。

在一次性本地測試中,共同基點為 15c1b740f8f4,遠端前進到 ff5235c58d12,第二個 clone 產生分叉 tip 220186e6d9a6。普通 push 與舊 lease 都失敗;觀察目前 OID 後,只有明確綁定該值且獲准的測試強推成功。

測試只證明機制,不代表授權。團隊規則、分支保護、PR 規則與遠端提交意義決定整合或改寫。lease 只防止覆蓋未見變化,不會讓歷史損失變合理。

改歷史前先確認目標

記錄遠端 URL、目前分支、upstream 與 push refspec,並寫出 refs/heads/main 這種精確目標。

用 git ls-remote --heads 直接查詢並保存 OID 與時間。沒有結果就停止核對名稱、權限與類型,勿以陳舊 tracking ref 代替。

抓取已觀察 tip 並判斷圖

將目標抓到專用 audit ref,確認 OID 相符,再檢查兩側獨有提交。背景 fetch 不會改掉這份已審證據。

執行 merge-base --is-ancestor。退出 0 表示本地包含遠端 tip;非 0 表示落後或分叉。選策略前閱讀兩側提交。

必須保留共享歷史時整合

共享分支按規則 merge audit ref,或只 rebase 未發佈本地提交。解決衝突、測試、複查圖後普通 push。

不要在記錄目標與 OID 前盲目 pull;它會依設定改變工作分支,可能先破壞解釋拒絕所需證據。

僅在獲准改寫時用明確 lease

維護者批准後,才以 --force-with-lease=refs/heads/main:<observed-oid> 綁定已審值。舊 lease 在測試中被拒。

推後重讀目標並記錄新舊 OID、批准與理由。lease 被拒不可自動刷新重試,因為審核條件已變。

原創示意圖:從目標確認到依政策整合或改寫的五步流程。
原創示意圖:從目標確認到依政策整合或改寫的五步流程。 Watch at Ease