代码不是你想合,想合就能合——聊聊Git合并请求(Merge Request)

代码不是你想合,想合就能合——聊聊Git合并请求(Merge Request)
主分支就像大坝的闸门,不能谁想开就开。合入之前,得有人帮你把把关。

你有没有经历过这样的“惨案”——

早上刚到公司,同事大喊:“谁把代码合进master了?项目跑不起来了!”
你战战兢兢地一看,果然是自己昨晚迷迷糊糊提交的那段代码出了问题。

或者,你写了一个新功能,自我感觉良好,结果上线后才发现,有个隐藏bug把生产环境搞崩了。

如果你有过这些经历,说明你们的团队缺少一个环节:代码评审

今天就来聊聊Git工作流中最重要的一个规范——合并请求(Merge Request)


一、为什么需要合并请求?

先问一个问题:master主分支应该是什么状态?

答案是:永远稳定,随时可部署。

master分支里的代码,应该经过测试、经过评审,没有任何未完成的功能,没有任何已知的bug。任何时候,你都可以基于master发布一个新版本。

但如果没有约束,每个人都直接往master提交代码,会发生什么?

  • A写到一半的代码合进去了,项目编译不过
  • B改了一个功能,但没考虑边界情况,线上出bug
  • C和D改了同一个文件,互相覆盖

混乱,是必然的。

所以,我们需要一个机制:代码不能直接合入master,必须经过其他人的评审,评审通过后才能合并。

这就是合并请求(Merge Request)存在的意义。


二、合并请求是什么?(GitLab叫MR,GitHub叫PR)

不同平台叫法不同:

  • GitLab里叫Merge Request(合并请求,简称MR)
  • GitHub里叫Pull Request(拉取请求,简称PR)

核心逻辑完全一样:你请求项目维护者把你的分支代码“拉”进主分支,在拉进去之前,大家先看看代码写得怎么样。


三、什么时候需要代码评审?

不是所有修改都需要评审,但以下几种场景,强烈建议走评审流程:

1. 大功能开发,代码量很大

改动越多,越容易出问题。让其他开发者帮你过一遍,能发现很多你自己发现不了的bug。

2. 初级开发者提交代码

新人刚接触项目,对代码规范、业务逻辑可能不够熟悉。资深开发者评审一下,既能保证代码质量,也能帮新人快速成长。

3. 跨领域修改

比如一个后端工程师修改了前端代码。让前端专家看一眼,能避免写出不符合前端规范的代码。

代码评审不只是在“挑错”,更是一次学习和交流的机会。 评审者可以告诉开发者:“这个地方可以用更好的写法”“这个逻辑有边界漏洞”“这里有个隐藏坑”。


四、合并请求的完整流程

第一步:开发者完成功能开发

你在自己的功能分支(比如feature/用户登录)上完成了开发,本地测试通过,觉得可以合入master了。

第二步:把分支推送到远程

git push --set-upstream origin feature/用户登录

第三步:在代码平台上创建合并请求

进入GitLab/GitHub,找到你的分支,点击“创建合并请求”。

需要确认两件事:

  • 源分支:你的功能分支(feature/用户登录
  • 目标分支:master

然后填写标题和描述,说明这次改了啥。可以指定某个同事作为评审人,也可以不指定,让团队里谁都行的人来审。

第四步:评审人审查代码

评审人打开合并请求,看到你所有的变更、所有的提交记录。

他可以做两件事:

  • 如果代码有问题:添加评论,指出问题所在,然后拒绝合并请求
  • 如果代码没问题:批准合并请求,然后执行合并操作

这里有个重要原则:评审人一般不会直接修改你的代码,而是留评论让你自己改。 这样你才能从错误中学习,下次写得更好。

第五步:开发者根据反馈修改

如果评审被拒绝,你根据评论修改代码,重新提交,再次请求合并。

第六步:合并完成

评审通过后,代码被合入master。刷新仓库页面,就能看到你的变更已经进去了。


五、合并之后:分支怎么处理?

代码合进去了,原来的功能分支怎么办?

有两种选择:

方案一:保留分支

想着“万一后面还要改呢”,先把分支留着。很多团队都这么干,结果就是——半年后,远程仓库里躺着几十个没人认识的分支,谁也不知道哪些是活的,哪些是死的。

方案二:合并后立即删除(推荐)

更好的实践是:合并完成后,立即删除这个分支。 如果后面真的需要修改,新建一个分支就行。

这样做的好处:

  • 远程仓库永远保持清爽,只有活跃的分支
  • 不会出现“这个分支到底合并了没有”的困惑

六、别忘了清理本地分支

远程分支删除了,但你本地还留着。

查看一下本地分支:

git branch

你会发现那个分支还在,甚至你可能还停留在那个分支上。

正确的清理步骤:

# 1. 先切换到master git checkout master # 2. 拉取最新代码(这时Git会告诉你,远程那个分支已经没了) git pull # 3. 删除本地分支 git branch -d feature/用户登录

这样,本地和远程都干净了。


七、一张图总结合并请求流程

开发者在功能分支完成开发 ↓ 把分支推送到远程 ↓ 创建合并请求(源=功能分支,目标=master) ↓ 评审人审查代码 ↓ 有问题? → 开发者修改 → 重新提交 ↓ 没问题 → 批准并合并 ↓ 删除远程分支 ↓ 清理本地分支


八、写在最后

合并请求(MR/PR)不只是一个技术流程,更是一个团队协作规范

它保证了:

  • master分支永远稳定、可部署
  • 代码质量有人把关
  • 团队成员可以互相学习、共同成长

刚开始做代码评审的时候,可能会觉得“好麻烦”“浪费时间”。但养成习惯后,你会发现:

省掉的,是线上出bug后通宵排查的时间;换来的,是更干净、更可靠的代码库。

下次提交代码前,记得问自己一句:我这个合并请求,有人帮我审过了吗?

Read more

C++之模版详解(进阶)

C++之模版详解(进阶)

目录 1. 非类型模板参数 2. 类模板的特化 2.1 函数模板特化 2.2 类模版特化 3. 模板的分离编译 1. 非类型模板参数 模版参数有两种,一种叫类型模版参数,一种叫做非类型模版参数。今天我们来讲讲非类型模版参数。 template <int N> 中的 int N 就是典型的非类型模板参数。这里的 int 是参数的类型,而 N 是参数名,它接收的是一个具体的常量值,而非像普通类型模板参数(如 template <typename T>)那样接收一个 “类型”。 两者核心区别就是: * 类型模板参数:传递 “类型”(如 T

By Ne0inhk
CMake征服指南:从零基础到实战,三大核心+静态库开发+自动化打包,一站式掌握现代C++工程化构建​!

CMake征服指南:从零基础到实战,三大核心+静态库开发+自动化打包,一站式掌握现代C++工程化构建​!

文章目录 * 本篇摘要 * 一.CMakeLists相关命令解释 * `cmake_minimum_required` 命令 * `project`命令 * `include`命令 * `install` 命令 * `add_executable` 命令 * 二.基于CMake组织实现静态库依赖程序运行 * 重温动静态库 * 三.cmake的三大核心:`目标 属性 API介绍` * 概念介绍 * `目标` * `属性` * `API` * ==**cmake三大核心工作流程:**== * 四.本篇小结 本篇摘要 CMake是C++项目的构建神器。本文详解其核心概念:目标、属性和API,手把手教你编写CMakeLists.txt,实现项目构建、测试和打包全流程。掌握现代CMake的最佳实践,提升工程化能力。 一.CMakeLists相关命令解释 cmake_minimum_required 命令

By Ne0inhk
【C++笔记】STL详解:vector容器的使用

【C++笔记】STL详解:vector容器的使用

前言:         本文在介绍STL框架基础上,进一步讲解了迭代器、auto关键字和范围for循环的使用方法,接下来我们将重点探讨vector类的常用接口及其应用。          一、vector容器的简介             C++ 的 vector 是标准模板库(STL)中最核心且实用的容器之一,其与固定大小的传统数组(如 int arr[10])不同,vector 克服了数组的局限性,它不需要预先确定大小,并且可以动态调整容量。          简单理解为:vector是可变的、经过封装函数功能的数组。                  核心优势:          ①动态扩容:您不需要一开始就告诉它要存多少数据。当空间不够时,它会在底层自动帮您寻找一块更大的内存,把数据搬过去。          ②内存安全:它负责自己内存的分配和释放,大大减少了手动 new 和 delete 带来的内存泄漏风险。          ③功能丰富:它自带了大量现成的工具函数,比如:获取大小、清空数据、在尾部添加数据等。

By Ne0inhk
【零基础学java】(IO流进阶)

【零基础学java】(IO流进阶)

缓冲流 缓冲流种类 字节缓冲输入流:BufferedlnputStream 字节缓冲输出流:BufferedOutputStream 字符缓冲输入流:BufferedReader 字符缓冲输出流:BufferedWriter 传统写入:   写1字节 → 系统调用 → 磁盘I/O → 返回 缓冲流写入: 写1字节 → 存入缓冲区(内存操作) → ... → 缓冲区满 → 批量写入磁盘 我们从实际数字上来体会缓冲流的作用 为什么缓冲区的大小一般是8192字节而不是越大越好 注意 对于字符流提升不明显,对于字符缓冲流而言关键点是两个特有的方法(字符流底层自带缓冲区) 字符缓冲流两个特有的方法 字符缓冲输入流BufferedReader:readLine() 字符缓冲输出流BufferedWriter:newLine() 缓冲流的分类 字节缓冲流 方法名称说明 public BufferedInputStream(InputStream is) 把基本流包装成高级流,提高读取数据的性能 public BufferedoutputStream(Outpu

By Ne0inhk