我们所说的“分支”到底是啥意思?
Posted
技术标签:
【中文标题】我们所说的“分支”到底是啥意思?【英文标题】:What exactly do we mean by "branch"?我们所说的“分支”到底是什么意思? 【发布时间】:2014-09-23 23:12:57 【问题描述】:长话短说……
据我所知,术语“分支”(在 Git 用语中)可能指相关但不同的事物:
-
指向提交的非符号引用/指针,
此类引用的名称(例如“master”),
存储库提交 DAG 的子图,由此类引用指向的提交可到达的所有提交组成。
但是,我已经看到该术语显然用于指代这三种可能用法之外的其他内容(更多详细信息见下文)。在 Git 上下文中,我上面的列表中缺少“分支”一词的其他有效且明确的用法吗?
更多详情
在使用 Git 大约一年后,我正在为 CS 学生准备一个简短的教程。我真的很想确定 Git 术语,以免造成任何混淆。
当然,我使用 Git 分支已经有一段时间了;我很乐意使用它们,并且发现 Git 分支模型很棒。但是,我仍然觉得“分支”这个词有问题且模棱两可,因为它似乎至少指代两种不同的事物,具体取决于使用它的上下文……有时甚至在同一个教程/手册中。
用法 1:分支 = 指向提交的指针/引用
Pro Git 书(3.1 - What a branch is),展示下图后,
继续定义一个分支为
只是一个指向这些提交之一的轻量级可移动指针。
据我所知,这也是 Git 手册页中“分支”的含义。
我对这个定义非常满意。我认为分支只是指向 DAG 中特定提交的引用,分支的“提示提交”是该引用指向的提交。到目前为止,一切都很好。但是等等……
用法 2:分支 = DAG 的子图
Atlassian Git tutorial 引入分支如下:
一个分支代表一个独立的发展路线。
我猜他们的意思是一串提交。让我完善一下这个想法……对我来说唯一有意义的解释是,术语“分支”也可以指代存储库提交 DAG 的 子图,该子图由所考虑的提示提交可到达的所有提交组成强>。
但是,例如,Pro Git 书也包含下图(参见3.4 - Branching workflows),
这似乎与我的解释相矛盾,因为它似乎暗示只有提交 C2
-C5
(不是 C1
)属于 develop
分支,并且只提交 C6
-C7
(不是C1
-C5
)属于topic
分支。
我发现这种用法含糊不清,因为如果我要在那个阶段绘制 DAG,不知道分支引用过去指向的位置,并且不假设三个分支之间存在任何层次结构,那么我所做的一切都是会得到是
我还发现其他 Git 学习资源中的一些图表令人困惑。尤其考虑以下一个(取自Lynda.com - Git Essential Training的介绍视频):
这里,master
的尖端实际上 534de
(而HEAD
指向master
),但是图中“master”标签的位置非常容易误导.在这种情况下,该标签应该描述什么我不清楚......
编辑:我已经找到了这个excellent post on Marc's blog; Branches 部分与我上面的评论相呼应。
【问题讨论】:
这是我读过的关于 git 的最有用的问题。我什至在阅读答案之前就学到了一些东西。干得好。 术语“branch”定义为“存储库提交 DAG 的子图,由考虑的提示提交可到达的所有提交组成” 是有问题的,当一个人在可达提交链中遇到合并提交时。突然之间,当我们回顾历史时,我们会称一个分支为可以分裂成几个分支的东西——这可能不是本意。 【参考方案1】:在第二种情况下,我们的意思是“来自分支指向的提交的reachable 的提交”。
在 Pro Git 示例中,假设 topic
分支指向提交 C7
,该分支包含提交 C7
、C6
、C5
、C4
、C3
、C2
、和C1
。在 Git 中,没有其他关于提交“在”分支上的概念,而且您可以线性重绘 DAG 是正确的。
Lynda.com 的图表非常不清楚,我怀疑你是对的,它具有误导性。
【讨论】:
非常感谢您提供指向“像 Git 一样思考”教程的链接 — 迄今为止我所见过的最有用的 git 参考资料,以及网站的参考资料部分。 @Wildcard,很高兴您发现它对您有所帮助。它也是我最喜欢的 Git 参考资料之一。【参考方案2】:你是对的。
我们可以通过分隔“本地”和“远程”分支标签来进一步拆分您的项目 1:本地分支(本地标签)是以refs/heads/
开头的名称(在内部——许多前端命令隐藏它),而“远程分支”——也称为“远程跟踪分支”——以refs/remotes/
开头,然后在命名分支的部分之前再添加一个路径组件来命名特定的远程。 (编辑,2018 年 4 月:我不喜欢“远程分支”或“远程跟踪分支”这个短语;我认为最好只调用这些远程跟踪名称。但是有很多现有的文档使用其他两个短语,因此我们需要注意这种用法。)
例如,您无疑对refs/remotes/origin/master
很熟悉,但如果您有一个名为bob
的遥控器,您可能还拥有一个跟踪Bob 的hacks/feep
的refs/remotes/bob/hacks/feep
。
本地分支名称refs/heads/<em>branch</em>
的显着特点是git checkout
默认情况下会将您“置于”该分支,通过将该名称写入特殊的HEAD
引用;一旦以这种方式设置,新提交(由git commit
、git merge
、git cherry-pick
等创建)会导致新提交的 SHA-1 写入分支文件。 (新提交的父级或其父级之一是旧的分支尖端。)
我尝试使用诸如“分支提示”之类的术语来专门表示分支名称(如refs/heads/master
)指向的提交,“分支名称”或“本地分支名称”来指代名称本身(无论前缀是否为refs/heads/
或不),而且——我认为这是最不成功的——“分支结构”来指代 DAG 子集。但是,给定一个具有这样的分叉合并的 DAG:
o--o
/ \
...-o--o o--o-...
\ /
o--o
我有时也想把这个苯环状小物体的一个或另一半称为“分支”,但我对此没有很好的称呼。
(顺便说一句,如果您是拓扑学家,Atlassian 图也可以线性绘制这一事实不会打扰您。但是,正如老笑话所说,拓扑学家一直试图从他们的甜甜圈中喝水并吃掉他们的咖啡杯因为每个都只是一个圆环。)
【讨论】:
我应该在我的问题中提到本地和远程分支之间的区别;感谢您添加。我也对术语“分支”(或“分支结构”)指代 DAG 子集感到不舒服。严格从图论的角度来看,术语“分支”仅在所考虑的图是树的情况下才有效;但是,Git 提交 DAG 不一定是树。 虽然我也不喜欢“分支结构”,但我向您努力区分“分支尖端”、“分支名称”和“分支结构”表示敬意。我想我也会在我的教程中做出区分。 “Branch ancestry”可能不那么含糊,但似乎并不普遍(在撰写本文时,Google 仅报告了 1300 次左右的“git 'branch ancestry'”点击)。跨度> 它具有技术优势,因为我们正在查看提交节点的祖先/后代关系。尽管“DAGlet”具有说起来容易且有趣的可疑优势。我想知道是否可以将其描述为“分支祖先”,指向父/子关系,然后开始使用“DAGlet”:-) @jub0bs:我现在更喜欢remote-tracking name,即完全去掉“branch”这个词。我希望有一个“分支名称”的短语根本不使用“分支”这个词:-)以上是关于我们所说的“分支”到底是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章