← Research

GIT WORKFLOW

PR 就是“我改好了,合吗?”

你改代码,先改在一条只属于你的岔路(分支)上,改完不直接塞进主干,而是发起一个 Pull Request——一张“请把我这条岔路并回主干”的申请单。等人看过、测试跑绿、点了同意,这张单子被合并(merge),你的改动才真正进入主干。一句话:PR 是“问”,合并是“答应”。

什么叫 PR,什么叫合并 PR 读时~15 min
路线图

从“开岔路”一路走到“合进去”

你说 PR 这事儿,光看缩写看不出名堂,得顺着它发生的顺序走一遍就懂了。四站:先搞明白为什么不能直接改主干(于是有了分支),再看 PR 到底是张什么单子,接着看这张单子上大家在忙啥,最后那一下“合并”到底干了什么。前两站回答“什么叫 PR”,最后一站回答“什么叫合并 PR”。

01 开岔路 别碰主干 02 发申请 PR 是问 03 看一看 审查+测试 04 合进去 merge 是答
Roadmap. 横轴是顺序:从开一条岔路,到把它合回主干。中间那张“申请单”就是 PR。

主干为什么碰不得

要懂 PR,得先懂它在替你挡什么麻烦。一个项目的代码,通常有一条“正式版”那条线,一般叫 main(主干)。所有人都在用它、线上跑的也是它。你要改东西,直接往这条线上改,行不行?

能改,但很容易出事。你改一半还没改完,别人拉下去用,拿到的是半成品;两个人同时往同一个地方塞改动,撞车了谁也说不清;真出了 bug,想退回去都找不到是哪一下弄坏的。4

所以大家的做法是:不直接动主干,而是先开一条岔路——专业说法叫“分支”(branch)。这条岔路从主干上某一点分出来,只属于你。你在上面随便改、改坏了也不连累别人,主干那条线始终保持干净、随时能用。4 改完了,你再想办法把这条岔路合回主干——而“合回去”这件事,正是 PR 要登场的地方。

main(主干) 你的岔路(feature 分支) 合并 ↑
Fig 1. 主干一直保持干净;你在自己的岔路上改了两下,改完再把它合回主干。橙色那条,就是只属于你的分支。
先想一下

假设没有分支这回事,三个人同一个下午都直接往主干上塞自己改了一半的代码。会出什么状况?先在脑子里想一下,再看下面。

试着先答

主干随时是个半成品大杂烩:谁的改动都没改完,互相还会覆盖、冲突。这时候任何人想拿主干去发布、去演示,拿到的都是坏的。更要命的是出了 bug 根本查不出是谁哪一下弄的——三个人的半成品搅在一起了。分支就是把每个人的“在改中”隔开,各改各的,改好了再一个一个合进来。

分支的全部意义,就是给你一块“改坏了也不连累别人”的地方;主干那条线,要始终保持随时能用。

PR 到底是什么

你在岔路上改完了,想合回主干。你不会自己偷偷合——你发起一个 Pull Request,简称 PR(中文有时叫“合并请求”;GitLab 干脆就叫 Merge Request,一回事)。

说白了,PR 就是一张申请单:“我这条岔路改好了,内容是这些,请把它并到主干去。”7 它不是一段代码,是一个“请求 + 一块讨论区”。一张 PR 单子上一般有这么几样东西:1

  • 标题 + 描述——你这次改了啥、为啥改,一句话说清。
  • Diff(改动对照)——红一块绿一块,清清楚楚列出你删了哪几行、加了哪几行。这是审的人最常盯的地方。
  • 讨论区(Conversation)——别人可以在具体某一行下面留言、提意见,你也可以回。
  • 检查(Checks)——自动测试、自动构建跑得过不过,绿勾还是红叉,挂在这儿。

这个词的来头也有意思。早年间 Git 里就有个 git request-pull 命令,作用是生成一段“我这边有改动,请你拉过去”的说明;GitHub 在 2008 年把它做成了网页上点点点的功能,“Pull Request”这个叫法就这么定下来了。6 所以它字面意思其实是“请求你来拉一下(我的改动)”。

常见错答

你以为 PR 就是“把代码传上去”“把代码存到网上”。不是。把改动传到远端那一步叫 push(推送),push 完代码就已经在 GitHub 上了。PR 是 push 之后另起的一张单子——“传是传了,现在请你看一眼,行就给我并进主干”。push 是搬代码,PR 是请求合并。两件事。

PR 不是代码本身,是一张“请把我这条岔路并进主干”的申请单,外加一块能逐行讨论的区域。

“你看看”——PR 上发生的事

单子发出去了,接下来就是“我改好了,你看看”里的“看看”。这一段也正是 PR 存在的核心理由:让改动在进主干之前,先被看一眼、被测一遍。1

两件事在这儿同时发生:

一是人来审(Review)

别人(同事、维护者,你一个人的项目里也可以是过两天的你自己)看你的 diff,在具体行上留言:“这儿会不会有问题?”“这个命名换一下吧。”看完他可以点“同意”(approve),也可以点“请改一下”(request changes)。5

二是机器来测(Checks / CI)

你一推改动,事先配好的自动测试、自动构建就会跑起来,跑完在 PR 上亮个结果:绿勾=过了,红叉=有问题。1 很多团队规矩是:红叉不许合。

举个具体的

你开了个 PR,改了登录页的一段逻辑。过一会儿:同事在 diff 第 12 行留言“这里没处理密码为空的情况”;与此同时 CI 那边亮了个红叉——有个老测试被你改挂了。

你不用关掉重开。你就在同一条岔路上接着改:补上空密码的处理,把测试修好,再 push 一次。PR 会自动更新——新的改动、新的对话、CI 重新跑出的绿勾,都接着挂在这张单子上。等同事看完点了 approve、绿勾也亮齐了,这张 PR 就具备“可以合”的条件了。

PR 把“一堆改动”变成了“一个能被讨论、被测试、被同意的东西”——这就是它存在的全部意义。

“合吗”的那个“合”——merge 干了啥

审也审了,测也绿了,最后那一下就是合并 PR(merge)。在 GitHub 上,它就是 PR 页面底下那个绿色的 “Merge pull request” 按钮——点下去,你岔路上的改动正式并进目标分支(通常就是 main),这张 PR 关闭,任务完成。1

“合并 PR”就是这么个动作:把申请批准并落地。问的是 PR,答应的是 merge。

点下去之前,GitHub 还会问你一句:想怎么合?有三种选法。改动反正都会进主干,差别就差在主干那本“账”记成什么样。23

合并方式它干的事主干历史长啥样啥时候用
Merge commit(默认)岔路上的 commit 原样并进来,再加一条“合并”记录全保留,看得到分支的来龙去脉想留完整记录、多人协作
Squash and merge把岔路上一堆零碎 commit 揉成一个,再并进来干净:一个 PR = 主干上一个 commit个人项目、PR 里 commit 很碎
Rebase and merge岔路的 commit 一个个接到主干末尾,不加合并记录一条直线,没有分叉想要笔直历史、又想留每个 commit

一开始记不住没关系,默认那个(merge commit)永远是安全选择。下面这题练一下手感就行。

你来补

你这个 PR 里攒了 8 个乱七八糟的 commit:“改个错字”“又改回来”“再调一下”……你不想让这些来回折腾污染主干,只想让主干上干干净净多出一条记录。三种合并方式,你该选 ?

对答案

Squash and merge。它把这 8 个 commit 揉成 1 个再并进主干——主干上只多一条干净的记录,你那些反复横跳的过程不会留在主干历史里。(要是反过来,你保留这 8 个各自的记录、又不想要分叉,那才选 rebase and merge。)

合并(merge)就是那一下“同意”:改动从你的岔路真正汇进主干,PR 的使命到此结束。

综合判断

两个词,串成一件事

把这俩词串起来看就全通了。你要改代码,先开一条只属于你的岔路(分支),在上面改、提交。改完,你发起一个 PR——等于举手说一句:“我这条岔路改好了,改的就是这些,请看一眼,行就并进主干。”然后别人(或者你自己,或者让 Claude Code 替你)看 diff、留意见、等 CI 把测试跑绿。都没问题了,点那个绿色的合并按钮——这一下就是合并 PR(merge):你的改动正式进入主干,PR 关闭。一句话收尾:PR 是把改动拿出来“问一句能不能合”,merge 是“答应,合”。

你作为不写底层代码、主要看效果的人,实际要操心的其实就两步:看一眼 diff(到底改了啥),然后点合并。开分支、开 PR、跑测试这些活儿,GitHub 和 Claude Code 大多能替你做掉,你做的是那个“看过、同意”的决定。

那什么时候这一整套是多余的?你一个人的小玩具项目,没人需要审、也没测试要跑,直接往主干上改,谁也不拦你。PR 这套规矩,是为“改动得被人看一眼、被机器测一遍,或者好几个人一起动同一份代码”准备的。人一多、东西一正式,它就从“多此一举”变成“救命的护栏”。

自测

读完盖住,试着答这几题

  1. 用一句话说:把代码 push 上去,和发一个 PR,差在哪?

    试着先答

    push 是把你岔路上的改动搬到远端(GitHub);PR 是搬完之后另起的一张“请把我这条岔路并进主干”的申请单,外加讨论区。push 是搬代码,PR 是请求合并。

  2. “合并 PR(merge)”那一下,具体发生了什么?

    试着先答

    你岔路上的改动被正式并进目标分支(通常是 main),这张 PR 关闭。本质就是这张申请单被“同意”并落地了。

  3. 应用题:团队要求主干历史保持一条直线、不要额外的合并记录,但又想保留你这个 PR 里每个 commit 各自的记录。三种合并方式选哪个?

    试着先答

    Rebase and merge。它把你的 commit 一个个接到主干末尾,既是直线、又不加合并记录、还保留了每个 commit。(如果团队不在乎保留这些 commit、宁可揉成一个,那就 Squash。)

  4. 应用题:你开了 PR,CI 那边亮了个红叉。这意味着啥?你该干嘛?

    试着先答

    意味着自动测试或构建没过(比如有测试被改挂了)。别带着红叉硬合——在你同一条岔路上把问题修好,再 push 一个新 commit,CI 会重新跑;等绿勾亮了再合。

把这几题截图,过两三天再凭记忆答一遍 —— 记得住才算真学会。

引用

Sources

  1. About pull requests — GitHub Docs — https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests
  2. About pull request merges — GitHub Docs — https://docs.github.com/articles/about-pull-request-merges
  3. About merge methods on GitHub — GitHub Docs — https://docs.github.com/articles/about-merge-methods-on-github
  4. Git Feature Branch Workflow — Atlassian Git Tutorial — https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow
  5. GitHub flow — GitHub Docs — https://docs.github.com/en/get-started/using-github/github-flow
  6. A Brief History of the Pull Request — rdnlsmith — https://rdnlsmith.com/posts/2023/004/pull-request-origins/
  7. What Is a Pull Request? — Atlassian Git Tutorial — https://www.atlassian.com/git/tutorials/making-a-pull-request