唯一能真正跳过文件合并的方法是用.gitattributes+merge=ours,它通过自定义合并驱动使Git完全不比较、不合并、不冲突指定文件;需全局配置git config --global merge.ours.driver true,并将.gitattributes提交到分支。

用 .gitattributes + merge=ours 真正跳过文件合并
这是唯一能让 Git 在 merge 过程中**完全不比较、不合并、不冲突**指定文件的方法。它靠的是自定义合并驱动,不是“忽略变更”,而是“跳过该文件的整个合并逻辑”。
常见错误现象:改了 vue.config.js 后合并到 main,结果被覆盖或报冲突;或者用了 .gitignore,发现文件照样被合并——因为 .gitignore 只影响未跟踪文件,对已提交文件无效。
- 先全局启用
ours驱动:git config --global merge.ours.driver true - 在项目根目录创建或编辑
.gitattributes,写入要保护的文件路径,例如:vue.config.js merge=ours deploy.yml merge=ours infostation.js merge=ours
- 必须把
.gitattributes提交进当前分支(比如dev),否则其他分支看不到规则 - 首次生效有时间依赖:目标分支(如
main)上该文件的最后修改时间,需早于源分支(如dev)上的修改时间;否则 Git 会误判“main更旧”,仍尝试合并
git update-index --assume-unchanged 只对当前工作区临时生效
这个命令不会影响合并逻辑本身,只是告诉 Git “别管这个文件的改动”,适合开发阶段临时屏蔽本地修改干扰,但**不能用于跨分支合并保护**。
使用场景:你在 main 分支调试时改了 config.local.js,又不想每次 git status 都看到它,也不希望它意外被 add 或 commit。
- 执行:
git update-index --assume-unchanged config.local.js - 恢复跟踪:
git update-index --no-assume-unchanged config.local.js - 该状态不随分支切换保留,换到
dev分支后需重新设置 - 如果在
dev上执行了--assume-unchanged,然后切回main并git merge dev,config.local.js依然会被正常合并——这个标记根本不起作用
合并时手动排除文件的三种实操路径
当无法提前配置 .gitattributes,或只做一次性操作时,靠命令组合最直接。关键点是:**必须在 commit 前恢复文件,且不能遗漏 git add**。
-
方式一(推荐):
git merge --no-commit+git checkout HEAD -- <file>
执行git merge --no-commit --no-ff feature→ 恢复文件:git checkout HEAD -- infostation.js→git commit -
方式二:合并后 amend
先git merge feature→ 立即执行:git checkout HEAD~1 -- infostation.js→git add infostation.js→git commit --amend -
方式三:用临时文件保底
合并前先保存:git show HEAD:infostation.js > /tmp/infostation.bak→ 合并 → 覆盖:cp /tmp/infostation.bak infostation.js→git add→commit
为什么 .gitignore 对合并无效
很多人试过往 .gitignore 里加 infostation.js,发现合并时文件还是被更新了——因为 .gitignore 只控制“未跟踪文件是否加入暂存区”,而合并操作处理的是**已提交文件的版本差异**。
一旦文件已在历史中存在,Git 就认为它是受控对象,.gitignore 完全不参与 merge 决策流程。
真正容易被忽略的点是:.gitattributes 规则只对**它所在分支可见**。如果你在 dev 分支写了规则但没提交,或者提交了却没合并进 main,那在 main 上执行 git merge dev 时,Git 根本读不到那行 merge=ours。


















