Git(九)你真的会合并代码到 master 吗?

技术栈摘要
协作侧:Git 分支模型 +master主干 / 功能分支 / 待合入分支
工具侧:Git CLI(merge / reset)+ IntelliJ IDEA(冲突可视化、Reset)+ 平台 MR(合入master)
目标:不依赖某仓库「照抄命令」即可跑通——先对齐最新master、冲突在功能分支消化、Mixed reset 压成一次提交,再提 MR 合主干。
官方资源
Git 官网:https://git-scm.com
Git 官方文档(中文):https://git-scm.com/book/zh/v2
GitLab Merge Request 文档:https://docs.gitlab.com/ee/user/project/merge_requests/
GitHub Pull Request 文档:https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
IntelliJ IDEA Git 文档:https://www.jetbrains.com/help/idea/using-git-integration.html
写在前面
很多团队「合到 master」其实是这样做的:功能分支上积累十几次调试提交 → 直接提 MR 撞 master → 冲突丢给主干处理 → 历史脏、回滚难、评审费劲。
更稳妥的合入纪律是:
- 冲突在功能分支消化:每个功能分支先合入最新
master,冲突当场解决。 - 历史压成一次提交:基于最新
master再拉一条「待合入」干净分支,把功能分支成果带过去,用 Mixed reset 落回基线后再做成一条清晰 commit。 - 用 MR 合入主干:推送待合入分支后,创建 MR(Merge Request,GitHub 上常叫 PR)合并到
master,走评审与 CI。
整体链路如下:

图 1:完整五步——① 功能分支先合最新 master 解冲突 → ② 从 master 建待合入分支并合入功能 → ③ Mixed reset(文件不变、不 staged)→ ④ 压成一次提交并推送 → ⑤ 创建 MR 合入 master。
最终操作清单
| 步骤 | 做什么 | 结果 |
|---|---|---|
| ① | 功能分支 merge 最新 master,解决冲突 |
功能代码已兼容主干 |
| ② | 从最新 master 新建「待合入」分支,再把功能分支合进来 |
起点干净;工作区已是「master + 功能」 |
| ③ | 相对 远程基线 做 Mixed reset(文件不变,变化不会被 staged) | 历史回到干净 tip,改动留在工作区未暂存 |
| ④ | 重新 add → 压成 1 次提交并推送 |
评审/回溯只看一条变更 |
| ⑤ | 创建 MR,合并到 master |
主干经评审合入,历史清晰、可回滚 |
下文「选型」对比常见合入方式与工具;正文按:环境准备 → 合入纪律(含 Mixed reset 原理)→ IDE 冲突 / Reset → 验收 → 生产注意 展开。
合入策略选型
合到主干时,常见有三种历史整理方式。本文推荐「对齐 + Mixed reset 压平 + MR」的组合,而不是直接把脏历史打进 master。
| 方案 | 做法概要 | 历史是否干净 | 冲突在哪解决 | 本文是否选用 |
|---|---|---|---|---|
| 普通 Merge | 功能分支直接 merge 进主干 | 常带合并节点与琐碎提交 | 往往在主干上爆冲突 | 否(最终进主干用 MR,本地先压平) |
| Rebase 到 master | 功能分支 rebase 到最新主干 | 可较线性 | 在功能分支 | 可选;多人同分支时风险高 |
| 对齐 + Mixed Reset 压平 | 先合 master 解冲突,再从 master 拉干净分支,merge 后 Mixed reset,再提交一次 | 一条业务提交 | 在功能分支 | 是 |
工具选型
命令能精确表达意图;IDE 适合看冲突与点选 Reset;平台 MR 负责进 master。
| 方案 | 优势 | 劣势 | 本文是否选用 |
|---|---|---|---|
| 纯 Git CLI | 步骤可复制、CI 友好、意图清晰 | 冲突文件多时导航弱 | 主流程命令以 CLI 为准 |
| IntelliJ IDEA | 三方对比、Reset 模式可选(Soft / Mixed / Hard) | 点错 Hard 会丢改动 | 冲突与 Reset 可视化 |
| 平台 MR / PR | 评审、CI、权限门禁 | 本地未先对齐时,冲突仍甩到合入点 | 步骤⑤合入 master |
1. 环境准备
1.1 约定
| 角色 | 示例命名 | 说明 |
|---|---|---|
| 主干 | master |
始终可发布的基线;只通过 MR 合入 |
| 功能分支 | feat/订单导出 |
日常开发、可有多次提交 |
| 待合入分支 | ready/订单导出 |
从最新 master 新建,最终只保留一次提交,再提 MR |
1.2 同步远端
git fetch origin
git checkout master
git pull origin master
确认本地 master 与远端一致后再开后续分支。
2. 合入纪律:对齐 → Mixed reset → 一次提交 → MR
2.1 原理:为何要用 Mixed reset?
功能分支往往有:试错提交、临时调试、多次「再改一下」。若直接并入主干,git log 会变成噪声。
Mixed reset(IDEA 里选项名就是 Mixed)的价值是:相对「干净基线」把分支头(HEAD)挪回去,工作区文件内容不变,但暂存区清空——差异不会被 staged。你再按需 add,最后做成一次有业务语义的提交。

图 2:左侧是功能开发中积累的「调试 / 再改一下 / merge」杂乱历史;中间做 Mixed reset(文件内容保留、暂存区清空)再 add + commit;右侧只保留一条 feat: 业务改动,便于评审与回滚。
IDEA 中 Reset 对话框请选 Mixed:

图 3:实操截图——务必选 Mixed:Files won’t change, differences won’t be staged。不要点 Soft(会全部 staged),更不要点 Hard(会丢工作区改动)。
三种模式对比(本文用 Mixed):
| 模式 | 文件(工作区) | 暂存区(index) | 典型用途 |
|---|---|---|---|
| Soft | 不变 | 仍 staged | 想直接再 commit 一次 |
| Mixed(本文) | 不变 | 清空,不 staged | 重新挑选文件再提交 |
| Hard | 回退到目标提交 | 随之回退 | 丢弃本地改动(危险) |
职责对照:
| 动作 | 改什么 | 不改什么 |
|---|---|---|
merge master 到功能分支 |
引入主干代码并可能制造冲突 | 不整理历史 |
从 master 建待合入分支 |
提供干净起点 | 还不包含功能改动 |
merge 功能分支 |
把改动带过来 | 历史仍可能很乱 |
git reset --mixed <基线> |
挪 HEAD;清空暂存区 | 文件内容仍在工作区 |
git add + commit 一次 |
得到一条清晰历史 | — |
2.2 分支职责

图 4:只涉及三条线——master(主干基线)← MR ← ready(从 master 新建后 Mixed reset 压平)← merge ← feat(先合 master 消化冲突)。预发 / 灰度不在本流程内。
2.3 步骤一:功能分支先合最新 master(冲突在这里消化)
git fetch origin
git checkout feat/订单导出
git merge origin/master
# 若有冲突:逐个解决 → git add <文件> → git commit
#(IDEA 解冲突见第 3 章)
git push origin feat/订单导出
此时功能分支已经「站在最新主干肩膀上」,后续压平与 MR 时不应再爆大面积主干冲突。
2.4 步骤二:从 master 新建待合入分支,并合入功能分支
git checkout master
git pull origin master
git checkout -b ready/订单导出
git push -u origin ready/订单导出
git merge feat/订单导出
# 此时 log 可能很乱;工作区已是「master + 功能」的完整代码
先 push 一次的意义:远程上留下一个与 master 齐平的 tip,下一步 Mixed reset 就对准它。
2.5 步骤三:相对远程基线做 Mixed reset
# 相对「干净基线」reset(推荐对准刚推送的远程 tip)
git reset --mixed origin/ready/订单导出
# 等价默认写法:git reset origin/ready/订单导出
# 此时:HEAD 回到基线;文件还在;改动未 staged
git status
IDEA:在 Log / 目标提交上右键 → Reset Current Branch to Here… → 选 Mixed → Reset。
2.6 步骤四:压成 1 次提交并推送
# 重新暂存需要合入的改动
git add -A
# 或按需 add 指定路径,避免把垃圾文件带上
git status
git diff --cached --stat
# 写成一条有业务语义的提交
git commit -m "feat: 订单导出支持多仓库筛选"
# 历史已重写,需要推远程(仅针对自己的待合入分支)
git push --force-with-lease origin ready/订单导出
要点:
- 用
--force-with-lease,比裸--force更安全:远端若被别人先推了新提交会拒绝覆盖。 - 不要对共享的
master做 force push。 - Mixed reset 之后务必看一眼
git status,去掉不该带上的文件再commit。
等价理解(便于记忆):
待合入分支起点 = 最新 master
+ merge 功能分支得到全部 diff
+ mixed reset 回到起点(文件保留,未 staged)
+ add + commit
= 相对 master 的一次业务提交
2.7 步骤五:创建 MR,合并到 master
- 打开 GitLab / GitHub / 码云等平台。
- Source:
ready/订单导出→ Target:master。 - 填写说明、关联需求,确认 diff 只有一条业务提交对应的变更。
- 等 CI / 评审通过后,选择团队允许的合并方式完成合入(Merge / Squash merge 等以规范为准;本地已压平则普通 Merge 即可)。
# 仅作核对:相对 master 应通常只有 1 条提交
git fetch origin
git log --oneline origin/master..origin/ready/订单导出
到这里,master 上看到的是经 MR 合入的干净变更,而不是十几条「再改一下」。
3. 冲突处理(IDEA)
3.1 原则
- 冲突尽量发生在步骤一(功能分支合 master),而不是发生在 MR 合
master的瞬间。 - 冲突解决完再做 Mixed reset;未解决完不要 reset。

图 5:在功能分支执行 merge master 时处理冲突——左侧当前分支、右侧合入的 master、中间写合并结果,完成后 Mark as Resolved。这样后面的 MR 合 master 时通常不再爆主干冲突。
3.2 IDEA 操作摘要
Git → Merge…选择origin/master(或在 Terminal 执行上文git merge)。- 冲突文件出现在 Conflicts / Local Changes。
- 打开合并窗口:左侧多为「当前分支」、右侧多为「合入方」,中间为结果。
- 解决后 Mark as Resolved,再 Commit 完成合并提交。
- 继续「新建待合入分支 → Mixed reset → 一次提交 → 提 MR」。
3.3 命令行补完冲突
# 查看还有哪些未解决
git status
# 解决文件后
git add path/to/file
git commit # 完成 merge commit
中途想放弃本次 merge:
git merge --abort
4. 验收清单
按顺序自检,全部通过再点 MR 合并:
| 检查项 | 命令或方法 | 期望 |
|---|---|---|
| 功能分支已含最新主干 | 在功能分支:git merge-base HEAD origin/master 应等于 origin/master |
已对齐 |
| 待合入只有一次业务提交 | git log --oneline origin/master..ready/订单导出 |
通常 1 条 |
| diff 纯净 | git diff origin/master...ready/订单导出 |
仅业务改动,无垃圾文件 |
| MR 目标正确 | Source = 待合入分支,Target = master |
评审批准 + CI 绿 |
| 主干合入后 | master 上可 git revert 该次合入 |
回滚路径清晰 |
git fetch origin
git log --oneline origin/master..ready/订单导出
5. 生产注意与常见误区
-
误区:直接在
master上解决一堆冲突
正确做法是冲突在功能分支消化;主干只经 MR 收「已对齐」结果。 -
误区:不压平,把调试历史一并合入
评审成本高、bisect/revert更痛;待合入分支存在的意义就是压成一次提交。 -
误区:对
master使用reset/ force push
Mixed reset、force-with-lease 只用于个人的待合入分支;公共主干走 MR。 -
误区:点成 Hard
Hard 会丢工作区改动。压平请用 Mixed(文件不变、变化不 staged),再自己add/commit。 -
误区:Mixed 后忘记 add 就 commit
Mixed 清空了暂存区,若不git add,很容易交出空提交或漏文件。 -
多人同改一个功能分支
reset + force 会改写历史,需先对齐团队;更稳是每人短分支,由负责人在待合入分支上统一压平再提 MR。
6. 一张纸记住全流程
# ① 功能分支对齐 master
git checkout feat/xxx && git merge origin/master # 解冲突、提交、推送
# ② 从 master 拉待合入分支,并合入功能分支
git checkout master && git pull
git checkout -b ready/xxx && git push -u origin ready/xxx
git merge feat/xxx
# ③ Mixed reset(文件不变,变化不 staged)
git reset --mixed origin/ready/xxx
# ④ 压成 1 次提交并推送
git add -A
git commit -m "feat: 清晰的业务说明"
git push --force-with-lease origin ready/xxx
# ⑤ 平台上创建 MR:ready/xxx → master,评审通过后合并
总结:
- 正确合到
master,核心不是「会不会点 Merge」,而是:冲突前置、Mixed reset 压平、一次提交、用 MR 合主干。按本文走完一遍,主干日志会短,回滚也有明确的一刀。
整理完毕,完结撒花~🌻
更多推荐



所有评论(0)