在git中,假设我有一个分支主文件和标签0.0.1,如果我执行以下操作:
git checkout 0.0.1
git branch -b random-fix
# some changes...
git checkout master
git merge random-fix
来自tag的分支在内部创建对分支主文件中标记所标记的提交的引用,或者分支来自“标记本身”,就像标记是某种分支一样?
我问这个是因为当我签到标签时,我会处于一个“独立的头”或类似的东西,对吧?知道这让我想到了分支标记。
答案 0 :(得分:6)
标签是对提交的引用。具体来说,轻量级标签只是使用用户定义的名称指向给定提交的引用。例如:
$ 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或其他形式的revision selection.
没有区别答案 1 :(得分:4)
(这应该是一个评论,但它太大了,需要很好的格式:-) ...而且,如果你按照一些链接,我似乎是一个古怪的心情...)
理解这一点的关键 - 我认为你已经存在了,但让我们把它放在SO文章中以便向下一位读者说清楚 - 是这样的:
所有git引用最终命名(指向)单个提交。
对于标签(无论是轻量级还是注释),分支,“远程分支”,git“notes”引用,“stash”等都是如此。他们都命名一个提交,就是这样。 (好吧,好吧,不完全:从技术上讲,标签可以命名仓库中的任何对象。事实上,这就是注释标签的工作原理:有一个轻量级标签,用于命名 带注释标签的存储库对象,然后带注释的标签命名一个提交对象。这也是HEAD
的工作原理:它通常命名另一个引用,然后命名提交。所以,有时你必须从洋葱上剥下几层才能命中提交。命名blob或tree对象是可能的,但通常情况下,实际上没有这样做。)
(提交的“真实名称”当然是SHA-1值。)
使分支参考名称“特殊”的原因同样简单:
分支引用是在添加新提交时自动移动到新分支提示的名称。
具体来说,refs/heads/branchname
形式的ref指向某个提交(根据定义,因为名称指向提交)。当你在那个分支 1 上“”并执行一些添加 new 提交的git操作时,例如git commit
或git merge
或{{1 git将新提交粘贴到repo中,然后将名称重新指向新提交。这就是它必须要做的一切!
我们所认为的“分支”是通过从提示开始形成的 - 名称指向的提交 - 并使用每个提交的父级或父级向后工作。如果提交有一个父级,则它是“在分支上”的普通提交。如果它有两个或更多,它是一个“合并”,你可以跟随它的所有父母找到合并的内容。如果它根本没有父项,则它是一个root提交(就像新的repo中的初始提交一样 - 你实际上可以拥有多个root;例如git“notes”这样做)。
如果您将七个分支标签放在一个提交上,那么现在您的“分支”有七个 2 名称。如果你把它清除为1,那当然是less confusing,但是git也不会在意。 (Git只关心你是否将其归结为零名。现在分支仍然存在,但它很难找到,并且它符合garbage collection的条件。)
由于我们正在谈论这个主题,我们还要记下“remote分支”。 (我从未对“远程分支”这个名称感到满意,但我没有更好的,所以我们只需定义它。)“远程分支”是表单的本地引用git cherry-pick
,其中 rname 是遥控器的名称(例如refs/remotes/rname/bname
), bname 是遥控器上的分支名称,即origin
之后的部分,如果您登录该遥控器并查看那里的分支。您无法“启动”远程分支 - 如果您refs/heads/
,git会为您提供"detached HEAD" - 但这些分支名称 会自动更新:当您使用{{ 1}}从远程获取新的提交,你也可以选择新的分支提示。换句话说,代替你将名称移动到新的分支提示,你让别人这样做(在遥控器上),然后你一次拿起他们的最新版本,当你从它们。
1 要成为“在分支上”,git checkout origin/master
ref必须是“间接”引用,类似于git fetch
。当HEAD
改为“分离”时,它包含原始SHA-1值。你仍然可以添加提交;它们被添加到未标记的分支中。 <{1}}中的引用使它们不被垃圾收集。
2 或者更多,如果有标签。我们假设有no tags。
3 没有脚注三。