分支管理

在不同分支上工作并把不同分支的内容整合到一起,是团队合作的重要环节,分支的使用中应遵循如下原则:

MYOC (Merge Your Own Code)

整合不同分支的工作时需要合并操作,该原则要求,合并的作者应该是两个父提交的作者之一,这样可以确保合并的作者熟悉将要合并的内容。 定义作者与两个父提交的作者都不同的合并提交是协助合并。

由此衍生出对成员的评价。对所有由合并提交及两个父提交构成的三元组 (Merge_k, Parent_{1,k}, Parent_{2,k}) ,记作者是第 i 名成员的 Parent_{1,k}Parent_{2,k} 的数量为 H_i ,记作者是第 i 名成员且符合该原则要求的 Merge_k 的数量为 M_i ,平均而言, M_iH_i 的比应为 50\% ,定义第 i 名成员的主动提交情况为 MYOCI_i=\frac{2 \times M_i}{H_i} ,计算结果大于1时取1。

记组内共有 M 次合并, n 名成员,定义小组 MYOC 情况为 MYOC=\frac{\sum_{i=1}^{n}M_i}{M}

avatar

上图即为一个不合要求的合并。发生这种情况有时因为多名成员在两个分支上开发而执行合并的成员不是最近有提交的成员。 还可能是合并的作者上一次在相关分支上提交和这次合并之间间隔了多个提交,甚至分支上可能没有他的提交,这种情况似乎是因为一名成员想在两个分支的基础上开始自己的工作。这两种情况意味着合并作者对代码不一定熟悉,都不是我们希望的情形。

一个分支只做一件事

定义分支内的相关提交集合为子任务,其中,不与其它提交相关的提交称为孤立提交,不视为子任务。 一个分支内不应有多个子任务,定义子任务数量达到2的分支为不合理的分支。 分配的任务过于复杂时,应增加更多的分支以细化任务。

定义父提交数量不是1的提交(初始提交和合并提交)和子提交数量不是1的节点(开始分支的提交和最新的提交)为关键提交。 该原则讨论的分支是提交历史中所有两个关键提交之间没有其他关键提交的提交序列。 这样的提交序列除了首尾提交,各点父提交和子提交均有且只有一个。 限制序列的开始不包括开始分支的提交、结束不包括合并提交。 定义只包含一个提交的序列是平凡分支,也不在讨论的范围内。

对一个分支上的两个提交 A 和 B , A 发生在 B 之前,记提交 A 修改的文件集合为 S_F(A) 。 定义二者修改文件交集的文件数量和B修改文件的数量之比为两个提交的相关系数 $$ R(A, B) = \frac{card(S_F(A) \cap S_F(B))}{card(S_F(B))} $$ R(A,B) \ge 0.2 时称A和B是相关的。 则子任务为,由分支上的提交和相关关系定义的边集构成的图中提交数达到2的连通分量。

对第 i 名成员,记对子任务有贡献的分支数为 H_i ,记对子任务有贡献的不合理的分支数量为 M_i ,定义第 i 名成员的 Early Branching 情况为 PI_i=\frac{H_i-M_i}{H_i}

记组内共有 B 个分支,其中 M 个不合理,定义小组的 Early Branching 情况为 Parallel=\frac{B-M}{B} 。 一种使得分支不合理的情况是团队中的各个任务逐个完成,没有并行开发,这时可以通过 git 工具的 --no-ff 选项进行合并以保留开发过程中的分支信息。

及时合并

各分支的内容应该及时合并,以减少整合过程中可能出现的问题。每个开发周期中,各分支都应该合并到同一个分支上,作为阶段成果。

在一棵提交树上,对每个周期,落在周期内,但父提交在前一个周期或没有父节点(提交树的根节点)的提交构成初始提交集合,我们希望这些提交都能合并到一起。 对初始提交集合内的各个提交求后继合并集合,后继合并集合的交集非空则认为在这一周期内各个分支都进行了合并。 如果同一项目的各棵提交树(有子项目,或仓库内包含没有共同祖先的提交时,会出现多棵树)都符合上述条件,则认为该项目在这一周期内进行了有效的合并。

记统计窗口内共有 N 个活跃的周期,其中 H 个有有效的合并,定义及时合并情况为 MO=\frac{H}{M}

avatar

上图在中间的周期内进行了有效的合并,其中, A 分支属于小组内的一个提交树, B 、 C 、 D 分支属于小组内另一棵提交树。 若 D 分支没有合并入 B 分支,则该周期内没有有效的合并。

avatar

上图在中间的周期内没有有效的合并,因为这一周期内没有一个统一的版本整合了各分支的新工作。