【工具使用——代码版本版本管理】Gerrit

【工具使用------代码版本管理】Gerrit

一般企业内部都会使用到这个工具,我这边学习整理一下gerrit的用法,欢迎大佬们批评指正~
Gerrit 是一个基于 Git 的代码评审系统

所有代码提交必须经过 review 才能合入

使用 Change + Patch Set 管理代码修改过程

通过 refs/for/* 提交代码进入审核流程

常与 CI 系统(如 Jenkins)集成

GitHub / GitLab 的区别

工具 核心特点
GitHub / GitLab 代码托管 + PR/MR(审核是建议性的)
Gerrit 审核是必须的,不通过不能合入

Gerrit 有一个非常核心的概念:一切提交都必须被 Review

你的代码流程不是:

复制代码
git push -> main

而是:

复制代码
git push -> Gerrit -> Code Review -> 审核通过 -> 才能合入

一些概念

change

Gerrit 不叫 commit,叫 Change

一个 Change 包含:

  • 一次代码修改
  • 多次修改版本(Patch Set)

Patch Set(补丁版本)

当你被 review 提意见后:

👉 你不是新建 commit,而是:

复制代码
修改代码 → 重新提交 → 生成 Patch Set 2

👉 一个 Change 可以有:

复制代码
Patch Set 1
Patch Set 2
Patch Set 3

Code Review 标签

常见有:

  • +2:代码没问题(可以合入)
  • +1:基本OK
  • -1 / -2:不通过

还有:

  • Verified(CI自动测试)

Submit(提交)

👉 满足条件后才能合入:

  • 至少一个 +2
  • CI 通过
  • 无冲突

rebase cherrypick merge 有什么区别

👉 merge = 合并全部历史

👉 rebase = 把你的提交"挪到最新后面"

👉 cherry-pick = 只拿一个提交

假设现在:

复制代码
master:
A---B---C---D

dev:
A---B---X---Y
merge(分支合并)

功能开发完成 → 合入主分支

复制代码
git checkout dev
git merge master

结果

复制代码
A---B---X---Y-------M
         \         /
          C---D---

✔ 把 master 的 所有提交(C、D)带过来

✔ 产生一个 merge commit(M)

✔ 历史是"分叉再汇合"

rebase(同步主线)

开发过程中,同步最新代码

假设现在

复制代码
master:
A---B---C---D

dev:
A---B---X---Y

执行:

复制代码
git checkout dev
git rebase master

结果

复制代码
A---B---C---D---X'---Y'
  • ✔ 不产生 merge commit
  • ✔ 历史变成"直线"
  • ✔ 你的提交被"重放"(变成 X'、Y')

一般的用法

复制代码
git fetch origin
git rebase origin/dev
fetch做了什么
复制代码
git fetch origin

从远程下载最新的代码,比如远程:

复制代码
origin/dev:
A---B---C---D---E

更新到本低的远程分支记录

复制代码
origin/dev → 指向 E

但是不会改当前的分支

假设本地是

复制代码
dev:
A---B---C

origin/dev:
A---B---C---D---E

fetch之后

复制代码
dev(你当前分支) ❌ 没变
origin/dev        ✅ 更新了

那rebase是配合这个做什么:把我的代码,放到最新的 dev 后面

复制代码
git fetch origin
git rebase origin/dev
fetch和pull

git fetch 用于从远程仓库获取最新代码并更新本地的远程分支引用

它不会修改当前工作分支

通常需要配合 rebase 或 merge 使用,将远程更新同步到本地分支

git pull 等价于

复制代码
git fetch + git merge

自动合并

可能产生 merge commit

❗不受控(企业不喜欢)

git fetch 只同步远端的代码 不动当前的代码

cherry-pick

✔ 只复制一个 commit(D)

✔ 生成新 commit(D')

✔ 不带其他历史

复制代码
git cherry-pick D
----------------------
A---B---X---Y---D'

常用的

👉 dev → release:

复制代码
dev:新功能 + bug修复
release:只要 bug

👉 用:

复制代码
git cherry-pick bug_commit
总结

原来的:

复制代码
master:
A---B---C---D
dev:
A---B---X---Y

merge:

复制代码
git checkout dev
git merge master
A---B---X---Y-------M
         \         /
          C---D---

rebase

复制代码
git checkout dev
git rebase master          
A---B---C---D---X'---Y' 

cherry-pick

复制代码
git cherry-pick D
----------------------
A---B---X---Y---D'

👉 同步用 rebase

👉 合并用 merge

👉 精确拿用 cherry-pick

  • merge 用于合并两个分支,会保留完整历史并生成 merge commit
  • rebase 用于将当前分支的提交移动到最新主线后,使提交历史更加线性
  • cherry-pick 用于将某一个 commit 单独应用到当前分支

在实际开发中:

  • 开发过程中使用 rebase 同步主线
  • 合并分支通常由工具(如 Gerrit)自动完成
  • bug 修复同步到其他分支时使用 cherry-pick
操作 本质 带什么 是否改历史
merge 合并分支 全部提交 ❌ 不改
rebase 重排提交 你的提交 ✔ 改
cherry-pick 复制提交 单个 commit ✔ 新建

git reset

- - soft
复制代码
git reset --soft HEAD~1

👉 做了什么:

  • ✔ 回退 commit(HEAD 往回移)
  • ❌ 不动暂存区
  • ❌ 不动工作区

👉 状态:代码还在,已经 add 状态

- -mixed(默认模式)
复制代码
git reset HEAD~1

👉 做了什么:

  • ✔ 回退 commit
  • ✔ 清空暂存区(unstage)
  • ❌ 不动工作区

👉 状态:代码还在,但变成"未 add"

- - hard
复制代码
git reset --hard HEAD~1

👉 做了什么:

  • ✔ 回退 commit
  • ✔ 清空暂存区
  • ✔ 删除工作区改动

👉 状态:

❗代码直接没了(回到历史状态)

整体的框架流程

拉代码 → 新建分支 → 改代码 → commit → push到refs/for/* → review → 修改 → 合入

一些词

👉 打 patch = 用"补丁文件"把代码改动应用过去------把修改写成"修改说明文件",别人拿去应用

打 patch

把 commit 变成一个"文件",再应用到别的地方

1️⃣ 生成 patch(补丁文件)
复制代码
git format-patch -1 D

👉 会生成:

复制代码
0001-fix-bug.patch

2️⃣ 应用 patch
复制代码
git apply 0001-fix-bug.patch

或:

复制代码
git am 0001-fix-bug.patch

apply vs am

命令 特点
git apply 只改代码,不生成 commit
git am 应用 patch + 生成 commit

开发流程

🧩 第一步:克隆代码

复制代码
git clone ssh://user@gerrit.xxx.com:29418/project

🧩 第二步:开发代码

复制代码
git checkout -b feature_xxx

🧩 第三步:提交 commit(重点)

复制代码
git commit

👉 commit message 必须规范,例如:

复制代码
fix: 修复I2C驱动初始化问题

Change-Id: Ixxxxxxxxxxxx

⚠️ 注意:

👉 Change-Id 是 Gerrit 识别同一个 Change 的关键!(通常自动生成)


🧩 第四步:push 到 Gerrit(不是 main!)

复制代码
git push origin HEAD:refs/for/master

👉 这一步是关键区别:

普通 Git Gerrit
push 到 main push 到 refs/for/master

👉 含义:

  • 不直接合入

  • 进入 Review 流程

    git push <远程> <本地>:<远程目标>
    对应
    git push origin HEAD:refs/for/master

具体

部分 含义
origin 远程仓库
HEAD 当前分支最新提交,当前分支的最新 commit
refs/for/master Gerrit 的"审核入口"

refs/for/master = "我要提交到 master,但先走审核流程",把代码提交到 master 的 review 队列里

把"当前最新提交" → 推送到 Gerrit 的 master 审核队列

复制代码
你本地 commit
      ↓
git push origin HEAD:refs/for/master
      ↓
Gerrit 创建 Change
      ↓
Code Review
      ↓
通过后 → merge 到 master

还可以分组提交

复制代码
refs/for/master%topic=xxx'
批量管理 Change

🧩 第五步:Code Review

同事会:

  • 看代码
  • 留 comment
  • 打分

🧩 第六步:修改代码

复制代码
git commit --amend
git push origin HEAD:refs/for/master

👉 会变成:

  • Patch Set 2

🧩 第七步:审核通过 → 合入

👉 Gerrit 自动帮你 merge

多分支 + Gerrit + cherry-pick 实战案例

复制代码
我们假设有 3 个分支:

master   → 主线(开发主干)
dev      → 日常开发
release  → 已发布版本(稳定)

👉 你接到一个任务:修复 I2C 驱动 bug(dev 分支) 然后同步到 release 分支(但不能带其他功能)


完整实战流程

🧪 Step 0:准备环境(模拟)
复制代码
git clone ssh://xxx@gerrit.company.com:29418/project
cd project

git checkout dev

🧪 Step 1:从 dev 拉分支开发
复制代码
git checkout -b fix_i2c_bug

👉 当前结构:

复制代码
dev:
A---B---C

你的分支:
A---B---C (fix_i2c_bug)

🧪 Step 2:修改代码

假设你改了:

复制代码
// i2c_driver.c
init_i2c();   // 修复初始化问题

🧪 Step 3:提交(生成 Change)
复制代码
git add .
git commit -m "fix: 修复I2C初始化失败问题"

🧪 Step 4:提交到 Gerrit(进入 review)
复制代码
git push origin HEAD:refs/for/dev

👉 此时:

复制代码
Gerrit:
Change 1001
  └── Patch Set 1

以上总结一下:

复制代码
# 1️⃣ 新建分支(你自己的开发空间)
git checkout -b fix_i2c_bug

# 2️⃣ 写代码
vim xxx.c

# 3️⃣ 本地提交(只是记录)
git add .
git commit -m "fix: xxx"

# 4️⃣ 提交到 Gerrit(关键步骤)
git push origin HEAD:refs/for/dev
😅 Step 5:被 reviewer 打回

reviewer 说:初始化顺序有问题


🧪 Step 6:修改代码
复制代码
# 修改代码后
git commit --amend
git push origin HEAD:refs/for/dev

👉 变成:

复制代码
Change 1001
  ├── Patch Set 1
  └── Patch Set 2

🧪 Step 7:期间 dev 分支更新了(真实情况🔥)

别人提交了代码:

复制代码
dev:
A---B---C---D---E

👉 你必须同步(否则提交会被拒)


✅ 正确操作:rebase
复制代码
git fetch origin
git rebase origin/dev

👉 变成:

复制代码
A---B---C---D---E---F(你的commit)

🧪 Step 8:再次提交(更新 Patch Set)
复制代码
git push origin HEAD:refs/for/dev

👉 Gerrit:

复制代码
Change 1001
  ├── Patch Set 1
  ├── Patch Set 2
  └── Patch Set 3

🎉 Step 9:审核通过 → 自动合入

👉 dev 分支现在:

复制代码
A---B---C---D---E---F(你的修复)
同步到 release

👉 现在你要把这个 bug 修复同步到 release

❗ 当前情况:

复制代码
dev:
A---B---C---D---E---F(修复bug)

release:
A---B---C   (稳定版本,没有新功能)

❌ 错误做法:

复制代码
git checkout release
git merge dev   ❌

👉 问题:

  • D、E(新功能)也进来了 ❌

✅ 正确做法:cherry-pick


🧪 Step 10:切换到 release
复制代码
git checkout release

🧪 Step 11:找到你的 commit
复制代码
git log

找到:

复制代码
F = fix: 修复I2C初始化失败问题

🧪 Step 12:cherry-pick
复制代码
git cherry-pick F

👉 结果:

复制代码
release:
A---B---C---F'

注意

  • F' 是新的 commit(不是原来的 F)
  • 只带 bug 修复

🧪 Step 13:提交到 Gerrit(release 分支)
复制代码
git push origin HEAD:refs/for/release

👉 Gerrit:

复制代码
Change 2001
  └── Patch Set 1

🧪 Step 14:review → 合入 release

👉 最终:

复制代码
release:
A---B---C---F'

整个流程总结(非常重要)

复制代码
1. dev 分支开发 → 提交 Gerrit
2. review → amend → patch set
3. rebase 保持最新
4. 合入 dev
5. cherry-pick 到 release
6. 再走一轮 Gerrit

Gerrit Reviewer端基本命令

作为 Gerrit reviewer,主要通过 git fetch 获取 patch set,本地使用 git showgit diff 查看改动,并通过编译运行验证功能。同时我会对比不同 patch set 的差异,确保问题被正确修复。评审时重点关注代码逻辑、性能、以及潜在的并发或内存问题,最终在 Gerrit 上给出 +1 或 +2 的评审意见。

你站在 reviewer 侧,本质做 4 件事:

  1. 拉代码(fetch patch)
  2. 查看改动(diff / log)
  3. 本地验证(编译 / 运行 / 测试)
  4. 给 review(+1 / -1 / +2 / 提意见)

掌握的 Gerrit 命令

1️⃣ 获取待评审代码

Gerrit 不用 git pull,而是用 fetch

标准命令

复制代码
git fetch origin refs/changes/xx/12345/1
git checkout FETCH_HEAD

解释:

  • 12345 → change number
  • 1 → patch set(第几版)

👉 你必须理解:

一个 change = 多个 patch set(版本)


2️⃣ 查看代码改动

看提交信息

复制代码
git log -1

看改了什么

复制代码
git show

看具体 diff

复制代码
git diff HEAD~1

👉 实际中你更常用:

复制代码
git show HEAD

3️⃣ 对比不同 patch set(很关键)

比如 reviewer 常见场景:

"作者改了第二版,我只想看改了啥"

做法:

复制代码
git fetch origin refs/changes/xx/12345/1
git checkout -b ps1 FETCH_HEAD

git fetch origin refs/changes/xx/12345/2
git checkout -b ps2 FETCH_HEAD

git diff ps1 ps2

👉 这个是 reviewer 很加分的技能(很多人不会)


4️⃣ 本地测试代码

复制代码
make
./run_test

👉 Reviewer 不只是看代码:

  • 能不能编译
  • 会不会崩
  • 性能有没有问题

5️⃣ Cherry-pick 到当前分支

有时候你在自己分支验证:

复制代码
git cherry-pick <commit-id>

👉 用于:

  • 集成测试
  • 和其他代码一起跑

6️⃣ 评审后操作(在 Gerrit Web 做,但你要懂)

虽然操作在网页,但你必须理解这些:

常见 Review 分值
  • +1:基本OK
  • -1:有问题
  • +2:可以合入(通常是高级 reviewer)
Verified(CI)
  • +1:测试通过
  • -1:测试失败

Reviewer 必懂 Git 操作

这些不是 Gerrit 专属,但 reviewer 经常用:


1️⃣ rebase(看作者有没有处理冲突)
复制代码
git rebase origin/master

你要看:

  • 有没有冲突
  • 提交是否干净

2️⃣ merge 测试
复制代码
git merge origin/master

👉 用来检查:

合入主干会不会炸


3️⃣ 查看提交历史是否规范
复制代码
git log --oneline --graph

你要看:

  • 有没有乱七八糟的 commit
  • 是否 squash 过

收到一个 Gerrit review

Step 1:拉代码
复制代码
git fetch origin refs/changes/34/1234/2
git checkout FETCH_HEAD

Step 2:看改动
复制代码
git show

Step 3:跑代码
复制代码
make
./test

Step 4:检查问题

你关注:

  • 逻辑是否正确
  • 是否有 bug
  • 性能问题
  • 代码风格

Step 5:如果有问题

👉 在 Gerrit 上:

  • comment
  • -1

Step 6:作者修改(Patch Set 3)
复制代码
git fetch origin refs/changes/34/1234/3
git checkout FETCH_HEAD

👉 然后对比:

复制代码
git diff ps2 ps3

Step 7:确认没问题

👉 打:

复制代码
+2

总结(你必须掌握的最小集合)

如果只记最核心:

复制代码
# 拉 patch
git fetch origin refs/changes/.../.../...
git checkout FETCH_HEAD

# 看改动
git show

# 对比 patch
git diff ps1 ps2

# 测试
make

# cherry-pick(可选)
git cherry-pick <commit>
相关推荐
大嘴皮猴儿2 小时前
AI图片翻译技术解析:以跨马翻译为例看电商图片翻译的实际效果
大数据·数据库·人工智能·自动翻译·教育电商
mhkxbq2 小时前
AI与大数据时代:昆仑G5580、G5680 V2、G2280及泰山200服务器登场
大数据·服务器·人工智能
YangYang9YangYan2 小时前
2026年大数据专业数据分析学习指南
大数据·数据挖掘·数据分析
老陈头聊SEO2 小时前
生成引擎优化(GEO)赋能内容创作与用户体验双重提升的新趋势
其他·搜索引擎·seo优化
vx_biyesheji00013 小时前
计算机毕业设计:Python网约车订单数据可视化系统 Django框架 可视化 数据大屏 数据分析 大数据 机器学习 深度学习(建议收藏)✅
大数据·python·机器学习·信息可视化·django·汽车·课程设计
Keep Running *3 小时前
ElasticSearch_学习笔记
elasticsearch·搜索引擎
切糕师学AI3 小时前
Elasticsearch RRF(倒数排序融合)技术详解与实践
算法·elasticsearch·搜索引擎·混合搜索·rrf·归一化问题
nimadan123 小时前
豆包写小说软件2025推荐,专业写作助力灵感迸发
大数据·人工智能·python
武子康3 小时前
大数据-261 实时数仓-建设指南:从架构设计到业务落地 交易订单、订单产品、产品分类、商家店铺、地域组织表
大数据·hadoop·后端