问题描述#
问题的最开始是我在 Vercel 部署了 lobechat,但是我 fork 的仓库从原仓库经常同步失败,然后在 Pull requests 页面看到了一个 request
图片中可以看到有一个合并冲突,需要解决这个冲突才能正常合并
在 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.md
和 README.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 仓库。
- 问题:在同步原始仓库更新时,因两个分支对同一文件的修改不同,导致合并冲突。
- 解决方案:
- 配置并拉取原始仓库的更新。
- 合并更新到当前分支时,识别冲突文件。
- 手动解决冲突文件中的标记内容,保留合适的代码。
- 提交修改并推送更新到远程仓库。
相关关键命令总结:
- 添加
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 合并冲突的解决过程有了更深的理解。无论是同步原始仓库,还是处理复杂的团队协作场景,这些技能都非常重要。希望能帮助有类似问题的小伙伴!