benjycui.github.io icon indicating copy to clipboard operation
benjycui.github.io copied to clipboard

叉子的使用姿势

Open benjycui opened this issue 5 years ago • 1 comments

fork [fɔ:k] n. 叉子

Fork 是开源社区每一个参与者的基本权利。为了充分运用这一权利,我们需要了解该权利有哪些使用场景,以及该如何使用,可以先参考 GitHub 官方文档

但其实,除了 GitHub 文档里提到的两种情况,我们还有其他必须 fork 的场景:

  1. 某一依赖发布频率较低,而业务系统中的 bug 需要尽快修复。
  2. 某些改动(bugfix、优化)对我们项目而言很有价值,但该仓库的 maintainer 不接受相应 PR。

这两种情况,都不能只是简单的 fork,还需要考虑原仓库与 fork 仓库之间代码同步的问题。所以,我们需要一个具体的 fork 工作流以规范原仓库与 fork 仓库之间的代码同步行为。

示例

为了方便读者理解,先假设有一个名为 incredible 的仓库,同时 npm 上也有一个同名的包。

现在,我们业务系统中碰到了一个 bug。经排查,问题来自 incredible,然后还找到了修复办法。但问题是,这个 bugfix 需要立刻上线,而 incredible 的 maintaner 并不会立刻合并我们的 PR 并发版本。

这个时候我们就需要 fork incredible 并发布自己的 npm 包。

Fork

下图中,upstream/master 是原仓库最新代码,origin/master 是在 GitHub 上 fork 后自动生成的分支,代码与 upstream/master 同步。然后我们在 origin/master 的基础上再 fork 一个 bugfix 分支 origin/bugfix,并在上面提交了 D 以修复问题。

image

为了尽快的把 bugfix 上线,需要先把 origin/bugfix 的代码发到 npm。这里需要使用一个新的包名,如 @benjycui/incredible。然后在项目中安装 @benjycui/incredible,并通过 webpack 的 resolve.alias 把对 incredible 的引用指向 @benjycui/incredible 即可。

出于开源精神,我们还要把这个 bugfix PR 到 upstream/master 上。如果 maintainer 愿意合并这个 PR,那么只需在 maintainer 发布新版后,安装新版 incredible 并移除 resolve.alias 配置即可。

一切顺利的话,时序图如下:

image

事实上,不可能每件事都称心如意,这个 PR 被拒绝了。现在,我们需要自行维护 @benjycui/incredible。

Merge

在我们把 bugfix D 上线后,incredible 本身也提交了新的 commit E,所以需要把这些新的提交也同步过来,并发布新版 @benjycui/incredible。

image

为了分支名更加明确,把 origin/bugfix 重命名为 origin/incredible。

接上文的时序图,在 PR 被拒绝后,新的时序图如下:

image

Develop

在项目持续迭代的过程中,又碰到了 incredible 的 bug。我们需要先在 origin/incredible 上修复该 bug,新的 bugfix commit 为 F,并发布新版 @benjycui/incredible。

image

虽然 incredible 的 maintainer 之前拒绝了我们的 PR,但我们毕竟是有开源精神的人,所以这次的 bugfix 还会继续 PR 回 incredible。为此我们需要基于 origin/master fork 一个 bugfix 分支 origin/bugfix,并把 F pick 过去。

image

然后继续走普通的 PR 流程把 origin/bugfix PR 到 upstream/master 即可。

本示例完整流程图如下:

image

benjycui avatar Jul 20 '18 08:07 benjycui

经典!

peterlevel1 avatar Oct 23 '18 06:10 peterlevel1