git同步分支衝突解決方法
有一次我把本地已經開發一段時間的專案推到新建的 GitLab 遠端儲存庫,結果第一個 push 就撞到 fatal: refusing to merge unrelated histories。這個錯誤不難解,但如果當下不理解原因,很容易會誤以為是遠端權限、分支名稱或 pull/push 順序出了問題。
這篇整理一下這個錯誤真正代表什麼、什麼情況會出現,以及比較安全的處理流程。
這個錯誤是什麼意思
refusing to merge unrelated histories 的意思是,目前你的本地分支歷史和遠端分支歷史,Git 判定它們不是從同一條提交鏈分支出來的,所以不願意直接幫你合併。
常見情境有這幾種:
- 你本地專案早就自己
git init過,後來才接上一個已經有初始 commit 的遠端儲存庫。 - 遠端平台自動幫你建立了
README.md、.gitignore或 License,導致遠端已經有一個獨立歷史。 - 你是從別的來源複製過來,再硬接到另一個不相關的 repo。
最直接的處理方法
如果你確定本地和遠端就是要合併成同一個專案,可以先 pull 並允許合併不相關歷史:
|
|
如果你的遠端預設分支是 main,就把 master 改成 main:
|
|
接著 Git 可能會要求你解衝突,處理完之後再 commit,最後再 push。
比較完整的安全流程
我自己會比較建議用下面這種順序:
- 先確認遠端預設分支名稱是
master還是main。 - 先做一次
git status,確保本地工作目錄是乾淨的。 - 執行
git pull origin <branch> --allow-unrelated-histories。 - 如果發生衝突,逐一修正檔案內容。
git add .後建立合併 commit。- 最後再
git push origin <branch>。
如果想看目前遠端設定,也可以先查:
|
|
另一種做法:重新 clone 再搬檔案
我後來也想到另一種比較直觀的方法,就是先把遠端 repo 重新 clone 下來,再把舊專案檔案複製進去後重新 commit。
這種方式的優點是流程單純、比較不容易被 Git 歷史搞混;缺點也很明顯,就是本地原本的 commit 歷史通常不會一起保留下來。
所以如果你很在意歷史完整性,還是應該走 --allow-unrelated-histories 的正規合併方式。
什麼時候不該這樣做
如果你其實是接錯 repo,或把不相干的兩個專案硬湊在一起,那就不應該用這個參數。因為它只是強迫 Git 接受合併,不代表兩邊內容真的應該混在一起。
實務上先確認下面兩件事會比較保險:
- 遠端 repo 是不是你真正要推送的專案。
- 遠端初始 commit 裡面有沒有使用者已經正式提交的重要內容。
小結
refusing to merge unrelated histories 本身不是大問題,重點是先判斷兩邊歷史為什麼會分開。如果只是本地專案要接上一個剛建立的遠端 repo,那用 git pull origin <branch> --allow-unrelated-histories 就能解;如果是接錯專案,硬合併反而會把歷史弄亂。
參考來源