git - 如何判断提交属于哪个分支?

Posted

技术标签:

【中文标题】git - 如何判断提交属于哪个分支?【英文标题】:git - How to tell which branch a commit belongs to? 【发布时间】:2020-11-18 06:24:48 【问题描述】:

作为一个对 Git 比较陌生的人,我最近(也是终于!)了解到分支实际上只是指向特定提交的指针,有时将“提交所属的分支”改写为“从哪些分支是可到达的提交”。

例如下图来自Git官方文档:

在这张图片中,我直观地认为提交C4“属于”分支master,提交C3C5属于iss53。但是C0C2 呢?他们会属于两个分支吗?或者我必须说它们可以通过masteriss53 分支“到达”吗?

一旦我将iss53 合并到master 中,这将变得更加复杂:

由于分支iss53 被合并到master,这是否使提交C0C2 属于master “更多”而不是iss53

如果我在合并后删除分支iss53怎么办?提交C3C5 属于哪个分支?仔细考虑之后,似乎合并后,提交C4C3C5在分支历史方面是“相等的”,我无法判断它们三个属于哪个分支.这是因为删除iss53 后,除了C3C5 之外,似乎没有任何关于C4 是否属于任何历史分支的信息。

我找到了this answer,它说最好从“可以从哪些分支到达此提交”的角度来考虑这一点。但这是否意味着C4C3C5 都可以从master 分支访问???但是您如何处理图中发生的分支父系?这有关系吗?

另外,我链接到的答案指出,可能存在任何分支都无法到达提交的情况, 怎么会发生?它的含义是什么?

但我的主要问题仍然存在:如何将提交与分支关联?

附:来自这篇文章的一个边/题外问题是:一次提交可以有两个以上的父母吗?

【问题讨论】:

是的,一个提交可以有两个以上的父级。 正如所写,我很想将其称为“不清楚你在问什么”。您问了很多澄清问题,所有这些问题都与您的标题问题不同。您链接到的问题似乎准确地回答了它。我认为您遇到的困惑是,在上一张图中,所有提交都在 master 中(或者 master 可以访问)。另外,看看 octopus merge for 2 个以上的父母。 @TTT:感谢您的批评。我必须承认学习分支对我来说是一个令人困惑的过程,如果我的问题不清楚,我很抱歉。我认为我想问的是,在我在帖子中提到的无数情况下,您如何看待提交和分支之间的关系?我想更具体,但我承认这对我来说很难。如果您能提出更好的方法来做到这一点,我会全力以赴。 这是有道理的。了解 DAG 需要一些时间来适应(请参阅 torek 的回答)。请注意,您的编辑询问了孤立提交是如何可能的,正如 Greg Burghardt 所描述的那样 - 例如如果一个提交只能由一个分支访问并且该分支被删除,则该提交是孤立的,最终将被垃圾收集,除非有其他东西指向它(如标签或 reflog 条目 - 返回 torek 的答案)。 顺便说一句,要回答你的标题问题,重要的是要意识到措辞实际上应该是“如何判断提交属于哪个分支?”更多信息在这里:***.com/q/2706797/184546 【参考方案1】:

提交不属于分支。没有所有权。分支是指向提交的指针。每个提交都有一个或多个父提交。当多个分支合并在一起时,追溯一个分支的历史不仅仅涉及一条直线。您需要重新定位提交和分支的视图。

在许多分支中提交存在

提交也可以存在于根本不存在的分支中。

从概念上讲,Git 存储库只是一个大链表,其中每个节点都指向至少一个其他节点。 “分支”只是指向其中一个节点的标记。 Git 中的节点称为提交。在 Git 中删除分支只会删除指向提交的指针,但不会删除提交对象本身。你可以recover branches you accidentally deleted,因为提交的数据库被排列成一个链表,一个分支只是一个指针——一个书签,如果你愿意的话。

但这是否意味着 C4、C3 和 C5 都可以从 master 分支访问?

是的,这正是它的意思。所有这些提交都是可访问的,因为提交 C6 指向 2 个不同的提交:C5 C4

您如何处理图表中发生的分支父代?这有关系吗?

提交C6 有两个父母。这意味着两个分支合并在一起。这就是你处理“分支亲子关系”的方式。使用git mergegit pull(即git fetch 后跟git merge)创建具有多个父级的提交。

【讨论】:

【参考方案2】:

添加到Greg Burghardt's answer,可达性确实是这里的关键概念。 提交图,连同散列 ID 和箭头,是最重要的,也是最重要的。 分支名称只是为您和 Git 提供了一个简单的入口点进入图表(但请参阅下一段中的git gc)。

提交图采用有向无环图或 DAG 的形式。整个系统要求提交可以从 some 外部名称访问——一个分支名称可以,但一个标签名称也可以,甚至是一个 Git reflog 条目——保持提交“活动”。维护程序git gc 将在被询问时搜索整个提交数据库,查找无法从任何外部名称访问的提交,并将它们从图中删除。 可从名称访问的提交,或从本身可从名称访问的提交,仍保留在图中。向图中添加新提交的命令通常以运行git gc --auto 结束,它告诉git gc 稍微探查一下,猜测此时这种维护是否明智,如果是,则进行维护运行。

Git 的其他部分会在必要和适当的时候进行图形遍历。例如,git log 命令会执行一项操作,从一些给定的提交开始并使用 DAG。图遍历使用队列(与许多图遍历算法一样)并跟踪访问过的提交,以便它可以访问每个提交一次,即使有多种方法可以访问它。

【讨论】:

以上是关于git - 如何判断提交属于哪个分支?的主要内容,如果未能解决你的问题,请参考以下文章

如何提交两个分支的“git diff”?

如何判断一个标签在 Git 中指向哪个提交?

确定哪个合并提交导致特定提交合并到我的分支中

Git 中 在哪个branch 打tag有关系吗

如何找到特定提交的分支?

如何列出包含等效提交的分支