Git merge 应在目标分支(即要保留历史的主干分支)上执行:如将 feature/login 合入 main,需先 checkout main 再 merge feature/login;同步 main 到 dev 则先 checkout dev 再 merge main。

merge 命令到底该在哪个分支上执行
Git merge 不是“把 A 合到 B”,而是“把目标分支的变更,合进当前所在分支”。很多人卡在这一步:切错了分支,结果把 main 合进了 feature,白忙活。
正确做法是先 git checkout 到你想保留历史、作为主干的那个分支,再运行 merge:
- 要把
feature/login的改动并入main→ 先git checkout main,再git merge feature/login - 想把
main的最新修复同步进dev→ 先git checkout dev,再git merge main
误操作后如果还没 push,可以用 git reset --hard HEAD~1 撤回合并提交;但一旦推了远程,就得用 git revert,否则会污染他人历史。
遇到 “Already up to date” 却没看到代码?
这通常不是 Git 弄错了,而是你本地没拉取远程最新状态。Git 只对比本地分支的 HEAD 和目标分支的本地引用(比如 origin/main),它根本不知道远程仓库里有没有新提交。
检查步骤很直接:
- 运行
git fetch origin,把远程分支最新信息拉下来(不改工作区) - 再用
git log --oneline main..origin/main看main落后多少 - 确认无误后
git merge origin/main或先git pull(本质是fetch + merge)
注意:git pull 默认用 merge 策略,如果你设过 pull.rebase true,行为就变了——这点常被忽略,导致团队协作时日志混乱。
merge 冲突时,编辑器里看到的
那是 Git 插入的冲突标记,不是你代码里的内容。它分三块: 后是你当前分支的版本,<code>======= 下面是待合并分支的版本,>>>>>> feature/name 是结束符。
解决它只要三步:
- 手动删掉所有冲突标记(包括
、<code>=======、>>>>>>这三行) - 留下你想要的代码逻辑(可以混合两段,也可以全删重写)
- 保存文件后,运行
git add <file>标记已解决,最后git commit
别用 git merge --abort 太随意——它会丢弃所有已解决的冲突文件,得重来一遍。真想放弃,先 git status 看哪些文件已 added,心里有数再 abort。
fast-forward 合并和三方合并的区别在哪
Fast-forward(快进)发生于目标分支是当前分支的直接上游时,Git 只移动指针,不产生新提交;而三方合并(true merge)会生成一个新提交,包含两个父提交,能清晰体现分支交汇点。
区别影响实际协作:
- 快进合并后,
git log看不到分支存在痕迹,不利于追溯功能开发周期 - 用
git merge --no-ff强制三方合并,哪怕能快进,也会留一个合并提交(推荐在main或release分支上这么做) - CI/CD 工具常依赖合并提交触发构建,快进可能让某些自动化流程“失联”
要不要 --no-ff 不是技术问题,是团队约定问题。一旦选了,所有人得保持一致,否则日志会混着两种风格,查问题时多绕三步。


















