合并请求是代码托管平台中的一类正式申请:把某个分支的改动并入目标分支,并在合入前完成检查与评审。它把代码差异、讨论记录、评审结论和合入动作收在同一个对象里。本文说明合并请求的定义、组成、从创建到合入的流程,以及它与分支、提交、代码评审等概念的区别。
要点总览(TL;DR)
- 合并请求(Merge Request,简称 MR)是代码托管平台中把某个分支的改动并入目标分支的正式申请,与 GitHub 的 Pull Request(PR)指同一类机制。
- 它承载三类核心信息:改动内容(差异与提交记录)、评审意见(批准、修改要求与讨论)、合入动作(是否合并、以何种方式合并)。
- 一次合并请求通常按创建、自动化检查、评审、追加修改、合入推进,未合入时以关闭结束,关闭记录仍保留可查。
- 合并请求与分支、提交、代码评审、工单职责不同:分支是改动的容器,提交是单次变更记录,评审是一种活动,工单描述要做什么。
- 合入通过表示既定检查与评审已完成,不构成代码无缺陷的保证;后续问题仍需通过新的改动和新的合并请求修复。
合并请求的直接定义
合并请求(Merge Request,简称 MR)是代码托管平台中发起的一次“把某个分支的改动并入目标分支”的正式申请。发起方指定源分支和目标分支,平台据此计算两者之间的差异,评审者在同一个对象里查看改动、发表意见并给出结论,满足条件后执行合入。GitLab 等平台使用 Merge Request 这一名称;GitHub 等平台使用 Pull Request(简称 PR),两者指同一类机制,只是命名不同。阅读文档或跨团队沟通时,看到 MR 与 PR 可以按同一概念理解。
合并请求承载的核心信息包括三类:改动内容,即源分支相对目标分支的代码差异与提交记录;评审意见,即评审者的批准、修改要求和讨论过程;合入动作,即最终是否合并、以何种方式合并、何时合入。这三类信息共同构成一次可追溯的合入决策记录,事后排查“这段代码为什么这样改、谁批准过”时,合并请求就是主要依据。
合并请求包括什么、不包括什么
合并请求覆盖的范围是“一次合入申请的全过程记录”。它记录改了什么、谁看过、结论如何、是否合入,但不负责产生好的代码,也不衡量团队整体的研发效率。把这两类内容分开,有助于在讨论中准确使用这个概念。
| 类别 | 内容 | 说明 |
|---|---|---|
| 属于合并请求 | 分支差异 | 源分支与目标分支之间的代码变更,是评审者实际查看的对象 |
| 属于合并请求 | 提交记录 | 构成这次改动的若干次提交,随追加提交而更新 |
| 属于合并请求 | 评审与讨论 | 逐行评论、整体意见、批准或要求修改的结论 |
| 属于合并请求 | 合入状态 | 待评审、已批准、已合入、已关闭等状态及其时间记录 |
| 不属于合并请求 | 代码优化方法 | 如何写出更好的代码属于工程实践,合并请求只承载检查与决策 |
| 不属于合并请求 | 算法设计 | 方案层面的设计讨论可能发生在合并请求之外,或仅作为背景说明 |
| 不属于合并请求 | 评审等待时长等流动效率指标 | 这类指标由平台统计或研发效能工具计算,合并请求本身不定义这些指标 |
合并请求是代码托管平台提供的一类对象,依附于平台存在,离开托管平台就没有独立的“合并请求工具”。它也不替代代码质量本身:合并请求提供检查与评审的载体,代码是否正确、设计是否合理,仍取决于提交内容和评审者的判断。合入通过表示既定检查与评审已完成,不表示代码不存在缺陷。
合并请求由哪些部分组成
把合并请求拆开看,它由若干相对固定的要素组成,每个要素在评审与合入中承担不同作用。理解这些要素,有助于在创建时把信息填完整,在评审时知道该看哪里。
| 组成要素 | 作用 |
|---|---|
| 源分支与目标分支 | 源分支是改动的起点,目标分支是改动的落点;两者确定后,平台才能计算差异 |
| 代码差异(diff) | 评审者实际查看的内容,按文件与行展示新增、删除和修改 |
| 标题与描述 | 说明改动目的、影响范围和验证方式,帮助评审者快速建立上下文 |
| 评审者与评审结论 | 指定谁来看,并记录批准、要求修改或拒绝的结论 |
| 讨论与评论 | 逐行或整体意见的沉淀位置,修改过程与理由留在这里 |
| 合入方式与合入状态 | 记录以何种方式合并,以及待评审、已批准、已合入、已关闭等状态 |
这些要素中,标题与描述常被低估。一个只写“修复问题”的标题,会让评审者花额外时间从差异里反推意图;写明背景、改动范围和验证方式的描述,则让评审集中在判断改动是否正确,而不是猜测改动目的。评审者与评审结论则需要与团队的评审规则配合,例如要求至少一名指定评审者批准后才能合入。
合并请求如何走完一次评审与合入
一次合并请求通常按创建、检查、评审、修改、合入的顺序推进,未合入时以关闭结束。每个阶段都伴随状态变化,状态是判断“现在该谁动作”的直接依据。
- 创建。从源分支向目标分支发起申请,填写标题与描述,指定评审者。此时合并请求进入待评审状态,差异已经可以查看。
- 检查。平台按配置运行自动化检查,例如构建、单元测试、静态扫描。检查结果附在合并请求上,未通过时通常阻止合入。
- 评审。评审者查看差异,逐行或整体发表意见,给出批准、要求修改或拒绝的结论。状态随结论变化。
- 修改。作者根据意见在源分支追加提交,合并请求自动更新差异与提交记录,已有讨论保留,评审者可针对新改动继续评审。
- 合入。满足检查通过、评审批准等条件后执行合并,改动进入目标分支,合并请求标记为已合入,记录保留可查。
- 关闭。方案调整、需求取消或改由其他方式处理时,未合入即关闭。关闭的合并请求仍保留差异与讨论,作为决策记录供后续查阅。
在团队协作中,合并请求往往对应一个具体任务。以 ONES 为例,研发任务可以在工作项中管理,代码提交与合并请求通过提交信息中的工作项标识与任务关联,评审与合入的状态变化回写到工作项,任务负责人和项目经理在同一处看到“代码是否已合入、任务是否可以流转”。这条链路的价值在于把代码层面的合入决策与任务层面的交付状态对齐,减少靠口头同步确认进度的情况。是否采用这种关联方式,取决于团队是否已经在工作项中管理研发任务;仅使用代码托管平台自带看板的团队,也可以只在平台内完成评审与合入。
合并请求与相邻概念的区别
合并请求容易与分支、提交、代码评审、工单混用,原因在于它们经常同时出现。区分的关键是看每个概念回答什么问题:分支回答“改动放在哪里”,提交回答“改了哪一次”,代码评审回答“谁来判断改得对不对”,工单回答“要做什么”,合并请求回答“这次改动能否并入目标分支”。
| 概念 | 核心含义 | 与合并请求的区别 |
|---|---|---|
| 分支 | 承载一系列改动的容器,有独立的提交历史 | 分支是改动的存放位置;合并请求是分支之间的一次合入申请,同一对分支可以先后产生多个合并请求 |
| 提交 | 一次代码变更记录,包含作者、时间和变更内容 | 一个合并请求通常包含多个提交;提交本身不包含评审结论,合并请求才承载评审与合入决策 |
| 代码评审 | 一种活动,由人查看代码并给出判断 | 评审是活动,合并请求是承载该活动的对象;评审也可以在合并请求之外以其他形式进行 |
| 工单或任务 | 描述要做什么、由谁负责、何时完成 | 工单描述需求与任务,合并请求描述改了什么、能否合入;两者通过标识关联,职责不同 |
这组区分在实际沟通中很有用。例如“这个分支还没评审”与“这个合并请求还没评审”含义不同:前者可能指分支上还没有发起申请,后者指申请已存在但结论未出。准确使用概念,能减少协作中的歧义。
一个具体例子与常见误解
下面用一个演示情景说明合并请求的完整生命周期。某系统出现登录超时问题,开发人员从主分支拉出功能分支,修复会话过期时间的判断逻辑,并向主分支发起合并请求。描述中写明问题现象、修改的文件范围和本地验证方式,指定一名熟悉认证模块的评审者。
评审者查看差异后提出两点意见:超时阈值应改为可配置项,避免硬编码;需要补充覆盖过期边界的测试用例。作者在功能分支追加两次提交,合并请求的差异与提交记录随之更新,讨论保留在原处。评审者复查新增改动,确认意见已处理,给出批准结论。自动化检查此前已通过,合并请求满足合入条件,执行合并后改动进入主分支,状态变为已合入。整个过程留下的差异、讨论和结论,就是这次修复的可追溯记录。
围绕合并请求,有三条常见误解值得澄清:
- 合并请求等于代码评审。评审只是合并请求生命周期中的一环。合并请求还包含差异展示、自动化检查结果、合入方式与状态记录;评审之外,创建时的描述质量和合入条件的配置同样影响合入质量。
- 合入即代表代码无问题。合入表示既定检查已通过、评审者已批准,是对“当前改动可以进入目标分支”的决策,不构成对代码正确性的绝对保证。后续发现问题时,仍需要通过新的改动修复,并在新的合并请求中记录。
- 合并请求只在开源项目中使用。合并请求是代码托管平台的通用机制,内部研发团队同样用它完成评审、留痕和权限控制。闭源项目中使用合并请求,还能让合入记录只在团队内部可见,兼顾评审规范与代码保密。
理解这三点后,合并请求的定位就清楚了:它是一次合入申请的载体,把改动、意见和决策收在一处,让合入有据可查;代码质量本身,仍由提交内容、评审判断和团队工程规范共同决定。
常见问题
合并请求和 Pull Request 是同一个东西吗?
是同一类机制的不同命名。GitLab 等平台称 Merge Request(MR),GitHub 等平台称 Pull Request(PR),两者都指“把某个分支的改动并入目标分支的正式申请”,承载差异展示、评审讨论、检查结果与合入状态。跨团队沟通或阅读不同平台文档时,可以按同一概念理解,不必因名称不同而重新建立认知。
合并请求合入后发现问题,应该怎么处理?
合入表示既定检查已通过、评审者已批准,是对“当前改动可以进入目标分支”的决策。合入后发现缺陷,通常的做法是从目标分支拉出新的修复分支,发起新的合并请求,在描述中说明问题现象、影响范围和验证方式,评审通过后再合入。原合并请求保留为历史记录,用于追溯当时改了什么、谁批准过;修复过程则记录在新的合并请求中,两者共同构成完整的变更链条。
团队规模较小,是否也需要强制要求评审后才能合入?
是否强制评审取决于改动的影响范围和团队的风险承受能力。改动涉及认证、支付、数据迁移等关键路径时,要求至少一名评审者批准能降低误合入的概率;改动范围小、可快速回滚的场景,可以简化流程。无论是否强制,合并请求本身仍会记录差异与合入状态,保留可追溯性。建议把规则写进平台的合入条件配置,让“是否需要评审”由分支或改动类型决定,减少逐次口头确认。
合并请求的描述应该写到什么程度?
描述的目标是让评审者不必从差异里反推意图。通常需要写清三件事:改动要解决的问题或背景、改动涉及的范围(哪些模块或文件)、如何验证(本地测试、自动化检查或手工验证步骤)。描述过长会稀释重点,过短则增加评审者的理解成本。对于小改动,一两句话说明背景与验证方式即可;对于涉及多个模块的改动,可以分点列出影响范围,便于评审者判断是否需要邀请其他模块的负责人参与。
关闭的合并请求还有保留价值吗?
有。关闭的合并请求仍保留差异、讨论和关闭原因,是“这个方案为什么没有合入”的决策记录。后续有人提出类似改动时,可以查阅此前的讨论,避免重复评估同一方案;排查历史问题时,也能确认某段代码是否曾经尝试修改但未合入。因此关闭时建议在讨论中写明原因,例如方案调整、需求取消或改由其他方式处理,让记录具备可读性。
