git checkout 0.0.1
git branch -b random-fix
# some changes...
git checkout master
git merge random-fix
从标签创建的分支,在内部会创建一个对于主分支或者标签所标记的提交的引用,就像标签本身是某种分支一样?
我之所以问这个问题,是因为当我切换到标签时,我会处于“分离头指针”状态,对吧?知道这一点让我想到了从标签创建分支。
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
(这可能应该是一个注释,但太太太大了,需要很好的格式化 :-) ...另外,如果你跟随一些链接,我似乎处于古怪的心情...)
理解这一点的关键 - 我认为你已经明白了,但让我们把它放在SO文章中,以便清楚地告诉下一个读者 - 就是这样:
所有git refs最终都会命名(指向)单个提交。
这适用于标签(无论是轻量级还是注释型),分支,“远程分支”,git“笔记”引用,“stash”等。它们都命名一个提交,并且仅限于此。 (好吧,不完全如此:从技术上讲,标签可以命名存储库中的任何对象。实际上,这就是注释型标签的工作方式:有一个轻量级标签,它命名了一个存储库对象,该对象是注释标签,然后注释标签命名了一个提交对象。这也是HEAD
的工作原理:它通常命名另一个ref,然后该ref再命名提交。因此,有时您必须剥离洋葱的几层才能到达提交。命名blob或tree对象是可能的,但通常没有实际这样做。)
(提交的“真实名称”当然是SHA-1值。)
一个分支引用名称变得“特殊”的原因同样简单:既然我们在这个话题上,让我们也注意一下 "remote 分支"。 (我从来没有完全满意过“远程分支”的名称,但我没有更好的名称,所以让我们先定义它。) “远程分支”是一个形式为 refs/remotes/rname/bname
的本地引用,其中rname是远程的名称(例如origin
),bname是远程的分支名称,即,在该远程登录并查看那个分支后面的部分refs/heads/
。 你不能“进入”远程分支——如果你git checkout origin/master
,git会给你一个"分离的 HEAD" ——但这些分支名称是自动更新的:当你使用git fetch
从远程获取新提交时,你也会获取新的分支端点。 换句话说,你不需要移动名称到新的分支端点,而是让其他人(在远程上)来做这件事,然后你一次性从他们那里获取最新版本,当你从他们那里获取时。
1要处于“分支”状态,HEAD
引用必须是“间接”的引用,类似于ref: refs/heads/master
。当HEAD
变成“分离头指针”时,它包含原始的SHA-1值。您仍然可以添加提交;它们被添加到一个无标签的分支中。HEAD
中的引用会防止它们被垃圾回收。
2或者更多,如果有标签存在。假设没有标签。
3没有第三个脚注。