4

在学习 Git 时,对我来说最大的惊喜之一是修订不会永久与特定分支相关联。相反,一个分支仅仅指向一个特定的版本。一旦我完全内化了这个概念,我意识到我不明白如何正确使用这个功能。

我读过一篇关于成功的 Git 分支模型的著名文章,其中将分支描述为行,而修订则明显与一行相关联。考虑以下摘录:

                                                      在此处输入图像描述

这显示了两个功能分支(称为featureAfeatureB)和一个develop分支。而且,featureB被完全合并develop,然后又短暂地分叉,只能重新合并。

这看起来不错,整洁且易于理解,并且恰好是在此过程结束时,回购在 Mercurial 之类的东西中的字面意思。我非常了解这一点,我喜欢它,并且我想像这样开发(在 Mercurial 中我做到了)。然而,在 Git 中,最终状态并非如此。它看起来像这样:

                                        在此处输入图像描述

换句话说,我们掌握的关于这两个特性分支的唯一信息是它们现在与开发分支处于相同的修订版中。因此,我们可以推断出整棵树的最佳结果是:

                                              在此处输入图像描述

换句话说,所有关于发展历史的好信息都丢失了;它一开始就没有被记录下来。观察第一张图中,三个修订在featureB合并到 之前是如何清楚地打开的develop,但我看不出我们如何知道这三个修订在featureB合并之前是打开的。

这个对吗?以上是我在 Git 中事后可以恢复的最好方法吗?因此,这篇文章的截图是否具有误导性?还是有什么重要的我错过了?

4

3 回答 3

2

是的,这是正确的,三个分支(指针)只会引用同一个提交。

但是对于 git,它更多的是关于提交的顺序,而不是关于一个分支。
分支只是提交图中的一个指针,目的是:

  • 帮助本地开发人员快速切换到一个或将一个与另一个合并
  • 帮助将一组提交发布(推送)到上游仓库(默认情况下,您不会推送所有分支,只有想要公开的分支)。

如果您确实需要将“ featureA”存储在某处,它将在提交消息中,但这不一定表示分支:您可以随时选择提交,重新设置分支,重命名删除分支(指针)时间。
最后,提交序列所讲述的故事比提交属于或属于一个或多个分支的事实更重要。

于 2013-07-15T11:18:48.813 回答
1

你是部分正确的,但也缺少一些东西。Git 是关于提交序列和它们创建的图表的全部内容。但是您在最终图表中遗漏了三件事:

  • (次要)您的最后一次合并是章鱼合并(合并两个以上的分支)。在那种情况下你不会这样做,我也不知道为什么来自 git-flow 的图像也包含一个。
  • 合并的父级有一个命令。所以有第一个父母和第二个父母。换句话说: git 记录什么被合并 什么.
  • 合并有一个提交消息

因此,您可以轻松地重建开发分支,从它的头部开始并仅跟随第一个父 ( git log --first-parent)。

如果您想知道合并了哪个功能,可以查看合并中的提交消息。

但请注意,这仅在您以这种方式使用 git 时才成立。合并和合并featureA将产生非常相似的结果,很多人没有意识到存在差异。developdevelopfeatureA

于 2013-07-15T12:35:23.047 回答
0

正如@VonC 所指出的,在 git-land 中(与 Mercurial World 相对?:-))似乎这通常被认为是一个功能,或者至少不是一个错误。但是,如果您希望标签保留在单独的空间中,您可以在 git 中通过与--no-ff. 这将创建一个“不必要的”/“空的”合并提交,用于保持父指针分离,因此也用于保持分支分离。

于 2013-07-15T12:02:50.080 回答