git合并后代码运行不一致,本质是工作区、暂存区与head提交快照三者状态错位:可能未在目标分支执行merge、未push远程、ci部署旧commit、ide缓存未刷新、换行符静默转换或依赖lock文件缺失等导致“看似成功实则失效”。

合并后代码运行不一致,不是“没合并成功”,而是 Git 已完成提交图谱更新,但你预期的代码变更没出现在工作区或运行时 —— 这通常意味着你看到的“合并结果”和实际生效的代码快照不匹配。
git merge 后 git status 显示干净,但运行结果不对
这是最常见误判点:Git 认为“已合并”,不代表你的修改进入了目标分支的最新提交快照。
- 检查是否真的在目标分支上执行了
merge:比如你在feature/login上运行了git merge main,那只是把main合进feature/login,不是把 feature 合进 main - 确认当前所在分支:
git branch看星号在哪,再用git log --oneline -n 5确认 HEAD 指向的提交是否包含你要的变更 - 检查是否漏掉
git push:本地 merge 成功 ≠ 远程分支更新,别人拉取的仍是旧 commit - 留意 CI/CD 部署是否基于 tag 或特定 commit,而非最新分支 tip —— 可能部署的是 merge 前的版本
VSCode 或 IDE 中看到的代码 vs 实际运行的代码不一致
编辑器显示的是工作区文件,而运行时加载的是 Git 当前 HEAD 对应的快照 —— 如果你有未提交修改,或刚 checkout 但没 reload,就会错乱。
- 执行
git diff确认工作区是否干净;若有输出,说明你本地改了但没提交,运行的是修改后版本,不是 merge 后的版本 - 重启 VSCode 或手动触发 “Reload Window”,避免缓存导致文件视图滞后
- 用
git show HEAD:src/utils.js直接查看当前 HEAD 下某文件的真实内容,和你编辑器里打开的做比对 - 注意 .gitattributes 或
core.autocrlf导致换行符被静默转换,可能让逻辑行为变化(比如 shell 脚本、JSON 配置)
合并后某行代码“明明改了却还是旧的”
这不是 Git 失效,而是你改的那部分被后续提交覆盖、或根本没进入 merge 基础路径。
- 用
git blame -L <line>,<line> -- filename.js</line></line>查看该行最后一次变更来自哪个 commit,再用git show <commit-id></commit-id>确认它是否在当前分支历史中 - 检查 merge 是否发生 fast-forward:如果目标分支没新提交,
merge只是移动指针,不会产生 merge commit,容易误以为“什么都没发生” - 警惕回滚后又 merge 的陷阱:比如你在
feature上git reset --hard commit-A,再git merge test,但test分支早已包含 commit-A 及其后代 —— Git 会跳过已存在 commit,你的 reset 后新改的内容若没形成新 commit,就不会被带入 - 用
git merge-base feature test找共同祖先,再分别git diff <base>..feature和git diff <base>..test,比对你认为该有的变更是否真存在于 feature 分支的差异中
CI 构建产物和本地运行结果不一致
构建环境读取的是 Git 快照,但可能受构建缓存、依赖版本、环境变量干扰,导致“同一份代码跑出不同结果”。
- 确认 CI 使用的 commit ID 和你本地
git rev-parse HEAD一致;不一致就直接排除代码问题 - 检查
package-lock.json或pnpm-lock.yaml是否被忽略或未提交 —— 缺失 lock 文件会导致依赖解析结果漂移 - CI 中是否启用了构建缓存?尝试加
--no-cache或清空缓存重跑,排除缓存污染 - 对比本地和 CI 的 Node.js / Python / JDK 版本,某些语法或库行为在不同版本下有差异(比如
Object.hasOwn在旧 Node 不可用)
真正麻烦的从来不是冲突报错,而是“看起来合并成功了,但代码没生效”——这种静默失效往往卡在分支指针、工作区状态、部署链路或 Git 提交图谱的理解断层上。动手前先问一句:我看到的“代码”,到底是工作区文件、暂存区快照,还是 HEAD 提交里的内容?











