作为开发者,我们经常会遇到各种 Git 问题,其中最让人头疼的莫过于 fatal: refusing to merge unrelated histories
这个错误。最近在项目开发中遇到了这个问题,并且还伴随着65个冲突文件,经过一番折腾终于解决了。在这里分享一下完整的解决过程和经验总结。
fatal: refusing to merge unrelated histories
git pull origin dev
时出现上述错误git pull origin dev --allow-unrelated-histories
后出现65个冲突文件很多人认为这个错误是因为:
refusing to merge unrelated histories
的真正原因是:
两个仓库没有共同的历史记录
git init
重新初始化的Git 的安全机制
# 允许合并不相关的历史记录
git pull origin dev --allow-unrelated-histories
# 或者分步执行
git fetch origin
git merge origin/dev --allow-unrelated-histories
优点:保留了两边的完整历史记录
缺点:可能产生大量冲突文件需要处理
# 获取最新的远程信息
git fetch origin
# 强制重置到远程分支
git reset --hard origin/dev
优点:快速解决,一步到位
缺点:会丢失所有本地未提交的更改
# 1. 备份当前本地更改
git stash push -m "backup before reset"
# 2. 重置到远程版本
git fetch origin
git reset --hard origin/dev
# 3. 如需要,可以恢复部分本地更改
git stash pop # 谨慎使用,可能产生冲突
当使用 --allow-unrelated-histories
后出现大量冲突文件时:
# 查看冲突文件列表
git status
# 只显示冲突文件名
git diff --name-only --diff-filter=U
# 统计冲突文件数量
git diff --name-only --diff-filter=U | wc -l
# 批量接受所有远程版本(推荐)
git checkout --theirs .
git add .
git commit -m "Accept all remote changes"
# 批量接受所有本地版本
git checkout --ours .
git add .
git commit -m "Keep all local changes"
# 大部分用远程版本
git checkout --theirs .
# 个别重要文件用本地版本
git checkout --ours src/config/important.js
git checkout --ours package.json
# 提交结果
git add .
git commit -m "Resolve conflicts with mixed strategy"
初次尝试
git pull origin dev
# 结果:fatal: refusing to merge unrelated histories
允许合并不相关历史
git pull origin dev --allow-unrelated-histories
# 结果:出现65个冲突文件,人都麻了
最终解决方案
git fetch origin
git reset --hard origin/dev
# 结果:一秒解决,完美!
# 每天开始工作前
git fetch origin
git pull origin dev
# 或者设置自动拉取
git config --global fetch.prune true
# 设置 pull 时使用 rebase
git config --global pull.rebase true
# 或者每次手动指定
git pull --rebase origin dev
# 创建功能分支
git checkout -b feature/new-feature
# 定期同步主分支
git checkout dev
git pull origin dev
git checkout feature/new-feature
git rebase dev
# 当目标分支是当前分支的直接后继时
git merge feature-branch
# 当两个分支有分叉时
git merge feature-branch --no-ff
# 优先使用远程版本解决冲突
git merge origin/dev -X theirs
# 优先使用本地版本解决冲突
git merge origin/dev -X ours
# 忽略空白字符差异
git merge origin/dev -X ignore-space-change
Git 冲突文件中的标记含义:
<<<<<<< HEAD
本地版本的代码
=======
远程版本的代码
>>>>>>> origin/dev
# 使用 vimdiff
git config --global merge.tool vimdiff
# 使用 meld(Linux/Mac)
git config --global merge.tool meld
# 启动合并工具
git mergetool
feature/功能名称
bugfix/问题描述
hotfix/紧急修复
release/版本号
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 代码重构
test: 测试相关
chore: 构建过程或辅助工具的变动
merge --no-ff
rebase
或 squash merge
A: 只有在确定要合并两个不相关的仓库时使用,比如:
A: 会丢失:
不会丢失:
A:
# 查看操作历史
git reflog
# 恢复到指定提交
git reset --hard HEAD@{n}
A:
遇到 fatal: refusing to merge unrelated histories
错误时:
--allow-unrelated-histories
reset --hard
记住,Git 是工具,服务于开发,不要被工具束缚。选择最适合当前情况的解决方案,快速解决问题,继续专注于代码开发才是王道!
希望这篇文章能帮助到遇到类似问题的开发者们!如果有其他 Git 问题,欢迎交流讨论。