Git不是这么用
潘忠显 / 2021-12-27
本文罗列了 8 个常见的 Git 和工蜂的不恰当使用的案例,给出了简单描述、影响以及规避方法,涉及开发及分支管理。文末给出了几条使用 Git 的建议。常见的 Git 进阶使用示例,可以查看《Git 常用指令》。
文章中如有不妥之处欢迎大家评论指出,也欢迎补充你遇到的常见的不太合理的操作。
[TOC]
1. 直接推到 master 发起 Review
【描述】
【影响】
直接影响主分支,无法控制主分支质量
【规避方法】
- 需要理解自己使用的是何种开发流,为何使用这种开发流,如何使用这种开发流
- Settings > Branches(protection) > Protected branch rules 增加的,详见“分支保护”
- 分支能够被保护的前提是确实划分好项目中不同人员的角色
2. commit 信息无意义
【描述】
【影响】
- 影响问题复盘时的快速排查
- 不能反应项目的完成度
【规避方法】
commit 合理划分,尽量让每次 commit 的信息反应增删修改的内容。
3. 简单修改反复commit
【描述】
下边这个 MR 在两个位置共修改了 17 行,但是却进行了 6 次 commit
【影响】
影响代码 review。如果 change 太多的,reviewer 可能选择分 commit 进行 review。这用情况下,会造成反复修改的点给 reviewer 带来困惑和重复的工作量。
【规避方法】
尝试使用操作,调整合并commit:
git commit --amend
git cherry-pick
git reset --soft
git merge --squash
4. 收录构建结果
【描述】
要理解 Git 是一种“分布式版本管理”系统(DVCS),工蜂或者 Github 上的所有版本控制信息,在本地都会存一份。
将构建结果直接加入到版本管理中,导致仓库迅速增大。
下图就是为了说明,即使你在后来的 commit 中删除了大文件,其实在本地、远端依然存在着他之前的副本:
【影响】
- 影响新用户的 clone 速度,占用硬盘空间
- 影响配置为全量拉取的流水线,进而影响每次构建时间
【规避方法】
- 清楚自己要提交什么,避免直接 git add 目录
- 使用 .gitignore
- 使用 precommit hook,提交前检查文件文件类型
- 【慎用】使用
git filter-branch
指令删掉历史中的提交,这会改变文件之后的所有 commit
5. 提 MR 之前 Pull/Merge 待合入分支
下边这个例子是实际中的一个场景:
- 绿色分支的产生,是从一次从红色分支叉出去,merge 进去了一个 commit,之后再没有 pull 或者 rebase 主分支
- 绿色分支 merge 之前的两次 commit 都已经被合并进了红色分支
- 红色分支中图合并了一些其他 commit
- 绿色分支 commit 一个 “优化”
这样绿色分支要合并到红色的分支 dev4.0
并提交 MR 时,会有两次 commit 要进行 Review:
- 绿色分支第一次 commit “Merge branch ……”
- 绿色分支第二次 commit “优化”
【影响】
多出额外的 N 次 commit,进而影响:
- 增加 review 工作量
- 增加了一次 log commit
- 无法 squash
【规避方法】
- 使用
git rebase
,可以直接在git fetch
之后通过git rebase origin/dev4.0
从远端分支变基 - 对于上边这个已经提交了的分支,可以做如下处理,最后提交 MR 时就只需要 Review 一次 “优化” 的 commit 即可:
6. 分支管理者只使用 Merge
【描述】
不少分支管理的同学,在 Review 通过之后的 Merge 环节会直接点 Merge,这样会造成分支中大量的 Merge 信息、细粒度 commit 信息。
【影响】
多次 commit 既可以方便开发,也可以方便 review。但是,在合并到主干分支的时候:
- 相对于 Squash and merge,直接 Merge 则会造成主分支中 commit 巨细靡遗
- 相对于 Rebase and merge,直接 Merge 则可能会将 MR 中的 commit 分散在主干中
- 以上两点,都会造成后期版本发布、问题复盘时,不能够更快速的找到对应的修改
【规避方法】
- 主干 commit 能尽可能跟 MR、ISSUE、Feature 等关联,不需要展示整个开发过程
- 使用 “Rebase and merge” 进行变基,将 MR 中的 commit 追加到当前分支最后
- 使用 “Squash and merge” 将多次 commit 进行合并,比如下边这个例子,PR 有三个commit,在 PR 通过之后,使用 Squash 合并成了一个 commit 合入到主分支
7. 单次 MR 内容太多
【描述】
一次 MR 提交太多内容,甚至涉及独立的多方面的修改。
有两种情况会造成这种现象:
- 没有遵循持续集成的原则,进行小批量、高频率的提交合并
- 已经通过某分支创建 MR 后,持续的往该分支上 push 新的内容
【影响】
一次 MR 涉及的内容太多,不利于进行 Code Review:
- Change 涉及多个功能,直接查看难以理解
- 部分代码不通过会阻塞住所有功能的合并
【规避方法】
- 不同的功能使用不同的分支进行推送并发起 MR
- 已经在一个分支中的,可以使用
git cherry-pick
功能将拆成多个分支 - 发起 MR 时使用新的分支,选择创建新的分支,在 MR 之后可以删除掉:
8. 每有更新关闭并新开 MR
9. 本地复制多个目录开发
【描述】
担心修改错误,将一个仓库的目录拷贝多份,XXX、XXX.bak、XXX.20211225 等等,在不同的目录中做修改。
【影响】
- 让自己的开发变得混乱
- 浪费硬盘空间,有些目录可能永远也再不会进去
- 这种拷贝的方式本身就是一种版本控制的手段,通过 git 是完全可以替代的
【规避方法】
-
习惯使用 Git 进行日常开发管理
-
通过
git checkout -b
创建多个分支进行管理 -
通过
git stash
push 贮藏和 pop 恢复临时状态文件,是个栈,可以保存个状态 -
通过
git remote add
添加多个 remote。比如这里有个项目使用了4个remote-
dop251
是最根源的 JavaScript 引擎项目仓库 -
debugger
是 fork 自dop251
的调试器项目 -
origin
是我个人fork的debugger
做调试器的一些修改,并会合并到debugger
源的仓库 -
woa
是在origin
基础上做了一些个性化开发,用于内部构件的仓库
-
0. 几点建议
- 理解 Git 是【分布式】【版本控制】系统,理解 Git 的工作原理
- 本地开发也要习惯使用多个分支,开发分支和待推送分支也可以分开
- 多参加代码 Review,多参与开源项目,纸上得来终觉浅,绝知此事要躬行
- 敢于尝试使用 Git 更复杂的指令、工蜂/Github的复杂功能