前言
利用 git 版本控制工具时, 我们通常会从主分支拉出新分支进行开发, 开发完成后创建 pr(也就是 pull request), 让其他小伙伴帮忙 review, 确定代码没有问题后再将新分支合并到主分支上. 但是, 你真的理解 pull request 中比较的两个分支到底是谁吗?
下面以一个虚拟案例进行说明: 假设主分支名为 "Master", 拉出来的新分支名为 "developBrance1".
首先看最简单的情况
上图中, 我们从主分支 Master 的 m1 提交点拉出新分支 developBranch1, 然后在 developBranch1 分支上开发 (开发过程中产生了 d1,d2,d3 共 3 个提交), 开发完成后创建 pr, 然后经过 Review 后将其合并到主分支上形成新的提交点 N. 自然而然地, 我们创建 pr 时选择的源和目标为:
src[developBranch1] -> dest[Master]
我们期望 pr 比较的是 developBranch1 和 Master 这两个分支的最新提交点, pr 实际比较的也是 developBranch1 的 d3 提交点和 Master 分支的 m1 提交点之间的差异.
增加一点复杂度
假设现在有其他小伙伴和你一同工作 (这才是工作中的场景), 另外一名小伙伴也从 Master 分支的 m1 提交点拉出分支 developBranch2 进行开发, 并产生了若干提交, 而且在我们开发完成之前已经合并到了 Master 分支上:
现在我们创建 pr 时, 源和目标自然还是:
src[developBranch1] -> dest[Master]
但此时 pr 实际比较的是 developBranch1 和 Master 这两个分支的最新提交点吗 ( developBranch1 的 d3 提交点和 Master 分支的 m2 提交点之间的差异)?
答案: 不是的. 现在 pr 比较的其实是 developBranch1 的 d3 提交点和 Master 分支的 m1 提交点, 和上面的情况完全没有差异!
其实 pr 的底层这样实现非常有道理:
我们创建 pr 时, 两个分支比较的差异只是自己开发的内容. 试想, 如果合作开发情况下比较 developBranch1 的 d3 提交点和 Master 分支的 m2 提交点之间的差异, 那我们会同时看到其他小伙伴的开发内容, 你会想, 这不是反应了 "最新工作进度" 吗? 不就是多看一个小伙伴的代码吗? 好, 再试想如果同时有很多人开发, 我们提交自己的代码时, 夹杂了许多其他小伙伴的代码, 你会不会因找不到自己开发的代码而发疯?
"最新工作进度" 的疑惑还在吧? 下面来解答.
git 是如何反映最新工作进度的?
其实, git 合并不同分支时, 会自动取它们的并集, 以保持最终工作进度. 就拿上图说, 如果 developBranch1 的 d3 提交点和 developBranch2 的 o2 提交点之间不存在冲突, 两者的开发工作最终都会在 m3 中体现 (当然, 有冲突了就需要手动解决).
现在还有一个问题, pr 比较的原理是什么?
pr 比较的是:
源分支的最近提交点和源分支和目标分支的最近公共父提交节点之间的差异. 在文中第二张图中, 可以看到源分支是 developBranch1, 目标分支是 Master, 两个分支的最近公共父提交节点是 m1; 所以最终比较的就是源分支的最近提交点 d3 和 m1.
探索欲强的读者也可以试试把不同分支分别作为 pr 的源和目标, 看看 git diff 的输出, 以加深印象.
后记
其他更为复杂的分支 pr 原理类似, 只是需要结合更为复杂的合并策略进行分析. 文中若有疏漏, 欢迎指正补充.
好了, 该去复习复习寻找两节点最近公共父节点的原理了 ^_^
来源: https://www.cnblogs.com/xiaoxi666/p/9526896.html