“分支”在IT技术中是什么意思?

54

长话短说...

就我所知,在Git术语中,“分支”一词可能指相关但不同的事物:

  1. 指向提交的非符号引用/指针,
  2. 此类引用的名称(例如“master”),
  3. 仓库提交DAG的子图,由指向此类引用的提交可达的所有提交组成。

然而,我看到这个术语似乎被用来指代除了这三种可能用法之外的其他东西(下面有更多细节)。在Git上下文中,是否还有其他有效和明确的“分支”术语用法,我的上述列表中没有包含?

更多细节

使用Git大约一年后,我正在为计算机科学学生准备一个简短的教程。我真的想弄清楚Git术语,以避免任何混淆。

当然,我已经使用Git分支一段时间了;我习惯使用它们,并且发现Git分支模型很棒。然而,我仍然认为“分支”这个术语存在问题和歧义,因为它似乎根据使用它的上下文而至少指代两种不同的东西... 有时甚至在同一个教程/手册中。

用法 1:分支 = 指向提交的指针/引用

在《Pro Git》书中(在3.1 - 分支是什么一节中),展示了以下图表:

enter image description here

继续定义一个分支为:

仅是一个轻量级的可移动指针,指向这些提交中的一个。

据我所知,在Git手册中,“分支”也有这个意义。

我对此定义感到非常舒适。我认为一个分支只是一个引用,指向DAG中的特定提交,“分支的尖端提交”是该引用指向的提交。到目前为止一切都好。但等等......

用法2:分支= DAG的子图

Atlassian Git教程如下介绍分支:

分支代表独立的开发线。

他们的意思是一系列提交。让我完善这个想法...唯一有意义的解释是,术语“分支”也可以指代由所有可从考虑的尖端提交到达的提交组成的存储库提交DAG的子图。

然而,例如《Pro Git》书中还包含以下图表(参见3.4 - 分支工作流程),

enter image description here

这似乎与我的解释相矛盾,因为它似乎意味着只有提交 C2-C5(而非 C1)属于 develop 分支,只有提交 C6-C7(而非 C1-C5)属于 topic 分支。
我认为这种用法含糊不清,如果我在那个阶段绘制DAG,不知道分支引用过去指向哪里,也没有任何假设三个分支之间的层次关系,我得到的只是:

enter image description here

我也发现其他Git学习资源中的一些图表令人困惑。特别是考虑以下这个(摘自Lynda.com - Git Essential Training的介绍视频):

enter image description here

这里,master 的提示实际上是 534de (而 HEAD 指向 master),但图表上的 "master" 标签位置非常误导。在这种情况下,该标签所描述的内容对我来说不清楚...编辑:我后来发现了 Marc 博客上这篇优秀的文章;其中的 分支 部分与我上面的评论相似。

19
这是我读过的关于 Git 最有帮助的问题。在阅读答案之前,我就已经学到了一些东西。干得好! - Wildcard
2
“_分支_”这个术语的另一个定义是“_由所有可从考虑的最新提交到达的提交组成的存储库提交DAG的子图_”。当在可达提交链中遇到合并提交时,这种定义方式就会出现问题。突然间,我们会称某个分支为可以分裂成多个分支的东西,当回溯历史时-这可能不是本意。 - Oliver Sieweke
2个回答

12

你是正确的。

我们可以进一步将你的项目1通过区分“本地”和“远程”分支标签进行拆分:本地分支(本地标签)是以refs/heads/开头的名称(在内部,许多前端命令都会隐藏这个),而“远程分支”——也称为“远程跟踪分支”——则以refs/remotes/开头,然后有一个以上的路径组件来命名特定的远程,然后才是命名分支的部分。(编辑,2018年4月:我不喜欢短语“远程分支”或“远程跟踪分支”,我认为最好只称呼它们为远程跟踪名称。但是有很多现有文档使用了另外两个短语,因此我们需要注意这个用法。)

例如,您无疑熟悉refs/remotes/origin/master,但如果您有一个名为bob的远程主机,则可能还会有refs/remotes/bob/hacks/feep来跟踪Bob的hacks/feep

本地分支名称refs/heads/分支的特点是,git checkout默认情况下将您放在该分支上,通过将该名称写入特殊的HEAD引用;而且一旦您这样设置了,新提交(由git commitgit mergegit cherry-pick等创建)会将新提交的SHA-1写入分支文件中。(新提交的父级或者其中一个父级是该分支的旧tip。)

我尝试使用像“分支顶部”这样的术语来特指分支名称如refs/heads/master所指向的提交,“分支名称”或“本地分支名称”来指代名称本身(无论是否带有前缀refs/heads/),而——我认为这是最不成功的——“分支结构”来指代DAG子集。但是,考虑到具有此类分叉和合并的DAG:

         o--o
        /    \
...-o--o      o--o-...
        \    /
         o--o

有时候我想把类苯环对象的其中一半称为“分支”,但我没有一个真正好的术语来描述它。

顺便说一下,如果你是一个拓扑学家,Atlassian图也可以线性绘制这个事实不会困扰你。然而,就像老笑话所说的那样,拓扑学家总是试图从他们的甜甜圈里喝咖啡和从咖啡杯里吃甜甜圈,因为每一个都只是一个环面。


1
我在问题中应该提到本地分支和远程分支之间的区别;感谢你补充了这一点。对于用"branch"(或"branch structure")来指代DAG子集,我也感到不舒服。严格从图论角度来看,只有在考虑的图是树时,"branch"这个术语才是有效的;然而,Git提交的DAG并不一定是树形结构。 - jub0bs
1
尽管我也不喜欢“分支结构”,但我对你区分“分支末端”、“分支名称”和“分支结构”的努力表示敬意。我认为我也会在我的教程中进行区分。 - jub0bs
1
“分支祖先”可能不太明确,但似乎并不是很普遍(在撰写本文时,谷歌只报告了大约1300个关于“git 'branch ancestry'”的搜索结果)。 - jub0bs
2
它具有技术优点,因为我们正在查看提交节点的祖先/后代关系。虽然"DAGlet"有一定的优势,易于发音且有趣。我想知道将其描述为“分支祖先”,指向父/子关系,然后在此之后开始使用“DAGlet”是否有效 :-) - torek
1
@jub0bs:我现在更喜欢使用remote-tracking name,也就是完全删除“branch”这个词。我希望还有一种表示“分支名称”的短语,它根本不使用“branch”这个词 :-) - torek
显示剩余4条评论

6
在第二种情况下,我们指的是“从分支所指向的提交中可访问的提交”。
在Pro Git示例中,假设topic分支指向提交C7,那么该分支包含提交C7C6C5C4C3C2C1。在Git中,没有其他关于提交“在”分支上的概念,你正确地指出可以将DAG线性重绘。
Lynda.com的图表非常不清晰,我怀疑你说得对,它是具有误导性的。

1
非常感谢您提供“像Git一样思考”的教程链接——到目前为止,这是我见过的关于Git最有帮助的参考资料,网站上的参考文献部分也同样如此。 - Wildcard
1
@Wildcard,我很高兴你觉得有帮助。这也是我最喜欢的Git参考资料之一。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接