在日常的开发工作中我们不可避免地要进行 PR,几乎每天我们都会看到这些选项,那这些是什么意思呢?

image.png

合并的代码的姿势

git merge

marge 特点:自动创建一个新的commit,如果合并的时候遇到冲突,仅需要修改后重新commit。

  • 优点:记录了真实的commit情况,包括每个分支的详情
  • 缺点:因为每次merge会自动产生一个merge commit,所以在使用一些git 的GUI tools,特别是commit比较频繁时,看到分支很杂乱。


git merge 的多种姿势 - 图2

git rebase

git rebase 一般被翻译为 变基,这个名字很灵性。他会找共同的父亲,然后将 commit 插入到 commit 列表中。

git merge 的多种姿势 - 图3

rebase 将所有 master 的 commit 移动到你的 feature 的顶端。问题是:其他人还在 original master上开发,由于你使用了 rebase 移动了 master ,git 会认为你的主分支的历史与其他人的有分歧,会产生冲突。

如果不是只有一个人使用,切记不要使用rebase。

rebase 特点:会合并之前的 commit 历史,很有可能会造成冲突。

  • 优点:得到更简洁的项目历史,去掉了merge commit。
  • 缺点:如果合并出现代码问题不容易定位,因为重写了历史。

我们要解决什么问题?

rebase 有非常严重的缺点,不适合多人协作,但是 merge 又会污染我们的commit,而且让每个人都写成完美的commit 有些不太现实。以下是 antd 的 merge 提交。

image.png

提交本质上是不可逆的,虽然我们有办法修改历史,但是在一个多人协作的库里面这样做肯定会翻车。但是写好commit 又非常重要,一个好的 commit 可以帮助我们快速定位问题。如果写的不好我们很难定位到问题所在。

小例子,这个 pr 改动了什么?

git merge 的多种姿势 - 图5

git squash merge 的优势

我们如果想要一个优秀的提交历史,又不想使用 reabse,那么 squash merge 将会是首选。

squash merge 可以让我们把多次的 commit 合并为一个提交。尤其是在 PR 中的时候更加好用。虽然写好commit 很难,但是写好一个 pr 标题其实没那么困难。

  1. C - D - E bugfix
  2. /
  3. A - B - F - G master

squash merge 之后

  1. A - B - F - G - CDE

正常 merge

  1. A - B - F - G - C - D - E - merge_commit

以 morse 项目为例,使用 squash merge 之后能得到如下的 commit:

image.png

image.png

祥细的 commit 信息 和 PR 的id 可以让我们在寻找问题中快速定位代码变更。

在 vscode 中的显示效果:

image.png

在 code 中使用

code 中也是支持 squash 的

image.png

如果觉得每次设置麻烦可以在 设置 中只启用 squash merge

image.png

Q & A

打开了 squash 之后,不推荐写好的 commit 信息?

commit 信息在任何时候都推荐好好写,但是如果你写了错别字或者因为一时偷懒,会导致整个主分支的commit 都杂乱无章充斥着莫名其妙的信息。这里推荐增加 git 的钩子来解决问题

  1. "gitHooks": {
  2. "pre-commit": "pretty-quick --staged",
  3. "commit-msg": "node ./node_modules/@umijs/fabric/dist/verifyCommit.js"
  4. },

任何时候都不要使用 rebase 吗?

如果项目中只有你一个人,或者这个分支只有你的时候使用rebase 是很推荐的。git pull -r 也是我们个人最常用的命令之一。但是一旦有多个人或者冲突太厉害的时候。建议还是 merge 保平安。

  1. git rebase --abo
  2. git merge --abo

这两个命令可以让你退出复杂的冲突,然后徐徐图之。

我可不可以一个 commit 一个分支?

理论上这个是最完美的方案,但是世事总是不尽如人意。很多时候你不会想因为一个 commit 就走一个 PR 流程的。但是人一多冲突会天天发生,因为别人不可能每时每刻去 merge 迭代分支。所以只推荐 依赖更新这样干。