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 合并冲突的解决过程有了更深的理解。无论是同步原始仓库,还是处理复杂的团队协作场景,这些技能都非常重要。希望能帮助有类似问题的小伙伴!

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。