Alwaysmeu

Alwaysmeu

Entry-level programmer

同步原始倉庫更新並解決合併衝突的完整實踐

問題描述#

問題的最開始是我在 Vercel 部署了 lobechat,但是我 fork 的倉庫從原倉庫經常同步失敗,然後在 Pull requests 頁面看到了有一個 request
Arc 2024-12-04 21.53.41

圖片中可以看到有一個合併衝突,需要解決這個衝突才能正常合併

在 GitHub 上,Pull Request(簡稱 PR)是一個請求,通常是由開發者發起,向項目的維護者提出將自己分支上的更改合併到項目的主分支中。Pull Request 允許開發者在代碼合併之前進行討論、審查和測試,確保代碼質量和功能符合預期。(你可以通過點擊 Pull Request 的標題來查看詳細信息,包括提交的更改、討論和審查狀態。)

為什麼我 fork 的倉庫也可以收到開發人員合併到原倉庫的請求呢?

當你 fork 一個倉庫時,你創建了一個與原始倉庫完全獨立的複製副本。然而,如果你在 fork 的倉庫中啟用了 GitHub Actions 或者某些自動化工具,這些工具可能會自動創建 Pull Request 來同步原始倉庫的更新。這通常是為了保持你的 fork 與上游倉庫的代碼同步。


具體情況#

我在 Fork 一個倉庫後( lobehub/lobe-chat),為了讓自己 Fork 的倉庫能夠保持和原始倉庫一致,我執行了與原始倉庫同步的操作(即將原始倉庫的最新更改拉取到我自己的分支)。在執行命令時,Git 報告了一些文件存在代碼衝突,具體錯誤如下:

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Auto-merging README.zh-CN.md
CONFLICT (content): Merge conflict in README.zh-CN.md
Automatic merge failed; fix conflicts and then commit the result.

這是由於我的 Fork 倉庫 (origin) 和原始倉庫 (upstream) 在某些文件(如 README.mdREADME.zh-CN.md)中都有修改,Git 無法自動合併這些衝突,所以需要手動解決。


解決問題的思路和方法#

基於以上問題,可以分為以下幾個步驟解決:

1. 配置 upstream 遠程倉庫#

Fork 後默認只關聯到自己的 GitHub 倉庫(origin),而未設置與原始倉庫(upstream)的關聯。為了同步原始倉庫,需要先添加一個名為 upstream 的遠程倉庫。

git remote add upstream https://github.com/lobehub/lobe-chat.git

解釋:

  • git remote add:用於添加遠程倉庫。
  • upstream:這是遠程倉庫的名稱(習慣將原始倉庫命名為 upstream)。
  • https://github.com/lobehub/lobe-chat.git:原始倉庫的地址。

通過以下命令可以確認遠程倉庫是否配置正確:

git remote -v

輸出示例:

origin    https://github.com/<your-username>/lobe-chat.git (fetch)
origin    https://github.com/<your-username>/lobe-chat.git (push)
upstream  https://github.com/lobehub/lobe-chat.git (fetch)
upstream  https://github.com/lobehub/lobe-chat.git (push)

2. 從原始倉庫拉取最新代碼#

配置完 upstream 後,可以拉取原始倉庫的最新代碼到本地:

git fetch upstream

這將獲取 upstream 倉庫的所有更新,並在本地形成一個更新的引用,如 upstream/main

接著需要將 upstream/main 的最新更改合併到自己的分支(假設是 main 分支):

git checkout main        # 確保切換到主分支
git merge upstream/main  # 將原始倉庫的更新合併到當前分支

如果一切順利,Git 會完成自動合併,但由於我們之前遇到了衝突,Git 會提示以下錯誤並停止:

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Auto-merging README.zh-CN.md
CONFLICT (content): Merge conflict in README.zh-CN.md
Automatic merge failed; fix conflicts and then commit the result.

3. 解決合併衝突#

此時需要手動解決衝突文件中的衝突問題。

3.1 定位衝突文件#

運行以下命令,查看哪些文件存在衝突:

git status

輸出會標記衝突的文件為 both modified,例如:

both modified:   README.md
both modified:   README.zh-CN.md
3.2 編輯文件解決衝突#

通過編輯器(如 VS Code)打開這些衝突文件。Git 會在衝突部分添加特殊標記,格式如下:

<<<<<<< HEAD
(分支 HEAD 的代碼內容)
=======
(來自 upstream/main 的代碼內容)
>>>>>>> upstream/main

你需要根據需要進行編輯,選擇保留哪部分內容,或合併兩部分內容。例如:

當前文件內容(衝突前)
<<<<<<< HEAD
我修改過的 README 內容在這裡。
=======
一個新的更新來自於上游倉庫。
>>>>>>> upstream/main
衝突解決後(調整後)

假設你希望保留兩部分內容並進行合併後:

我修改過的 README 內容在這裡。
一個新的更新來自於上游倉庫。

編輯完成後,保存文件,並確保衝突標記(<<<<<<<, =======, >>>>>>>)都已刪除。

3.3 標記衝突解決完成#

解決完衝突後,將已修改的文件添加到暫存區:

git add README.md README.zh-CN.md

或使用通配符一次性添加所有文件:

git add .
3.4 提交合併結果#

所有衝突解決並添加到暫存區後,提交此次合併的解決結果:

git commit -m "Resolve merge conflicts in README files"

4. 推送本地改動到遠程倉庫#

完成合併後,將本地的更改推送到自己的 Fork 倉庫:

git push origin main

此時,GitHub 上會顯示你的分支已經與原始倉庫同步。如果這是為了解決 GitHub 上的 Pull Request 衝突,你現在可以在 GitHub 網站上將 PR 合併完成。


總結#

這是一個完整的 Git 合併衝突的處理實踐,通過上面的操作,我成功解決了文件衝突問題,並完成了原始倉庫更新同步到自己的 Fork 倉庫。

  • 問題:在同步原始倉庫更新時,因兩個分支對同一文件的修改不同,導致合併衝突。
  • 解決方案
    1. 配置並拉取原始倉庫的更新。
    2. 合併更新到當前分支時,識別衝突文件。
    3. 手動解決衝突文件中的標記內容,保留合適的代碼。
    4. 提交修改並推送更新到遠程倉庫。

相關關鍵命令總結

  • 添加 upstream 遠程倉庫:
    git remote add upstream <url>
    
  • 拉取並與原始倉庫同步:
    git fetch upstream
    git merge upstream/main
    
  • 查看衝突文件:
    git status
    
  • 自動或手動解決衝突後,提交改動:
    git add <file>
    git commit -m "Resolve conflicts"
    git push origin main
    

通過這次實踐,我對 Git 合併衝突的解決過程有了更深的理解。無論是同步原始倉庫,還是處理複雜的團隊協作場景,這些技能都非常重要。希望能幫助有類似問題的小夥伴!

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。