来自标签的 Git 分支 - 内部



在 git 中,假设我有一个分支主节点和一个标签 0.0.1,如果我执行以下操作:

git checkout 0.0.1
git branch -b random-fix
# some changes...
git checkout master
git merge random-fix
标签的分支

在内部创建对分支主节点中标签标记的提交的引用,或者分支来自"标签本身",就好像标签是某种分支一样?

我问这个是因为当我结帐到标签时,我会处于"分离的头"或类似的东西中,对吧?知道这一点让我想到了分支标签。

标签 引用提交

标记是对提交的引用。具体来说,轻量级标记只是使用用户定义的名称指向给定提交的引用。例如:

$ git log
commit e0e92bc337b246696aec5c214507321c7526c1e9
Author: John Doe <john.doe@example.com>
Date:   Thu Sep 26 14:38:36 2013 -0400
    Empty initial commit.
$ git tag v0.0.1
$ cat .git/refs/tags/v0.0.1 
e0e92bc337b246696aec5c214507321c7526c1e9

在这两种情况下,实际的 SHA-1 是相同的。换句话说,标签只是指向提交的指针。

使用标记作为提交标识符

您可以从标签分支,其方式与从提交标识符分支的方式完全相同。例如,以下两个命令实际上是同一件事:

  • git checkout -b new_branch v0.0.1
  • git checkout -b new_branch e0e92bc337b246696aec5c214507321c7526c1e9

对于 Git 来说,新分支的起点是作为标记、SHA-1 还是某种其他形式的修订选择列出没有区别。

(这也许应该是一个评论,但它太大了,需要很好的格式:-(...另外,如果你关注一些链接,我似乎心情古怪......

理解这一点的关键——我想你已经在那里了,但让我们把它放在 SO 文章中,让下一个读者明白——是这样的:

所有 git 引用最终都会命名(指向(单个提交。

对于标签(无论是轻量级的还是注释的(、分支、"远程分支"、git "notes"引用、"stash"等都是如此。 他们都说出一个提交,仅此而已。 (好吧,好吧,不完全是:从技术上讲,标签可以命名存储库中的任何对象。 事实上,这就是带注释的标签的工作方式:有一个轻量级标签,用于命名作为注释标签存储库对象,然后带注释的标签命名一个提交对象。 这也是HEAD的工作方式:它通常命名另一个 ref,然后命名提交。 因此,有时您必须从洋葱上剥下几层才能击中提交。 可以命名 Blob 或树对象,但通常实际上没有任何内容执行此操作。

(提交的"真实名称"当然是 SHA-1 值。

使分支引用名称"特殊"的原因同样简单:

分支

引用是在添加新提交时自动移动到新分支提示的名称。

具体来说,形式 refs/heads/branchname 的引用指向某个提交(根据定义,因为名称指向提交(。 当您"在"该分支1 上并执行一些添加新提交的 git 操作时,例如 git commitgit mergegit cherry-pick ,git 会将新提交粘贴到存储库中,然后将名称重新指向新提交。 这就是它所要做的!

我们认为的"分支"是通过从提示(名称指向的提交(开始并反向工作而形成的,使用每个提交的父级或父级。 如果提交有一个父级,则它是"在分支上"的普通提交。 如果它有两个或更多,则为"合并",您可以跟踪其所有父级以查找合并的内容。 如果它根本没有父级,那就是根提交(就像新存储库中的初始提交一样——你实际上可以有多个根;例如,git "notes"就是这样做的(。

如果将七个

分支标签放在一个提交上,则现在"分支"有七个2 个名称。 当然,如果你把它清除到一个,它就不会那么令人困惑,但 git 不会在乎这两种方式。 (Git 只关心你是否将其减少到零名称。 现在分支仍然存在,但真的很难找到,它符合垃圾回收的条件。

既然我们谈到了这个话题,让我们也记下"远程分支"。 (我对"远程分支"这个名字一直不太满意,但我没有更好的名称,所以让我们定义它。 "远程分支"是 refs/remotes/rname/bname 形式的本地引用,其中 rname 是远程的名称(例如 origin(,bname 是远程上的分支名称,即,如果您登录该远程并查看那里的分支,则refs/heads/后面的部分。 你不能"上"远程分支——如果你git checkout origin/master,git 会给你一个"分离的 HEAD"——但这些分支名称自动更新的:当你使用 git fetch 从远程获取新的提交时,你也会选择新的分支提示。 换句话说,您不是将名称移动到新的分支提示,而是让其他人(在远程上(执行此操作,然后当您从他们那里获取时,一次获取他们的最新版本。


1要"在分支上",HEAD ref 必须是"间接"引用,类似于 ref: refs/heads/master 。 当HEAD改为"分离"时,它包含一个原始的 SHA-1 值。 您仍然可以添加提交;它们将添加到未标记的分支中。 HEAD中的引用使它们不被垃圾收集。

2或更多(如果有标签(。 假设没有标签。

3没有脚注三。

最新更新