git标签与git分支有什么不同?

我试图了解何时应该使用标签vs分支来pipe理我的代码库。

标签代表特定分支的版本。 一个分支代表一个独立的开发线程,可以在同一个代码库上与其他开发工作同时运行。 对分支的更改可能最终会合并到另一个分支中以统一它们。

通常你会标记一个特定的版本,以便你可以重新创build它,例如,这是我们运送给XYZ公司的版本。一个分支更多的是提供正在进行的特定版本的代码更新的策略,同时继续做它的发展。 您将创build交付版本的分支,继续在主线上进行开发,但是对代表交付版本的分支进行错误修复。 最终,您会将这些错误修复合并回主线。 通常你会同时使用分支和标记。 您将拥有各种标签,这些标签既可以应用于主线,也可以应用于每个分支的标记特定版本(例如,交付给客户的分支)的分支 – 您可能需要重新创build这些分支 – 用于交付,错误诊断等。

这实际上比这更复杂 – 或者像你想要的那样复杂 – 但是这些例子应该给你一个差异的概念。

理论上来看:

  • 标签是给定修订的符号名称。 他们总是指向相同的对象(通常:对同一修订版); 他们不会改变。
  • 分行发展线的象征性名称。 新的提交被创build在分支之上。 分支指针自然前进,指向较新和较新的提交。

技术angular度来看:

  • 标签驻留在refs/tags/ namespace中,并且可以指向标签对象 (带注释和可选的GPG签名标签)或直接提交对象 (less用本地名称的轻量级标签),甚至在极less数情况下甚至可以指向树对象Blob对象 (如GPG签名)。
  • 分支驻留在refs/heads/ namespace中,只能指向提交对象HEAD指针必须引用一个分支(符号引用)或直接指向一个提交(分离的HEAD或未命名的分支)。
  • 远程跟踪分支位于refs/remotes/<remote>/ namespace中,并遵循远程仓库<remote>普通分支。

另请参阅gitglossary手册页:

一个“分支”是一个积极的发展路线。 分支上最近的提交被称为该分支的提示。 分支的顶端由分支头引用,随着分支上的额外开发,分支头向前移动。 一个git仓库可以跟踪任意数量的分支,但是你的工作树只与其中的一个(“当前”或“签出”分支)相关联,并且HEAD指向该分支。

标签

指向标签或提交对象的引用。 与头部相比,标签不会被提交改变。 标签(而不是标签对象)存储在$GIT_DIR/refs/tags/ 。 […]。 标签通常用于标记提交祖先链中的特定点。

标签对象

包含ref的对象指向另一个对象,它可以像提交对象一样包含消息。 它也可以包含一个(PGP)签名,在这种情况下,它被称为“签名标签对象”。

如果您认为您的存储库是一本记载项目进度的书籍…

分行

你可以把分支想象成那些粘滞的书签之一

在这里输入图像描述

一个全新的仓库只有一个(称为master ),它会自动移动到你写的最新的页面(认为提交 )。 但是,您可以自由创build和使用更多书签,以便标记本书中的其他兴趣点,以便快速返回到其中。

另外,您可以随时将特定的书签移动到本书的其他页面(例如使用git-reset )。 兴趣点通常随时间变化。

标签

您可以将标签视为章节标题

书签

它可能包含标题(认为注释标签 )或不包含。 标签与分支相似但不同,因为它标志着书中的历史兴趣点。 为了保持它的历史方面,一旦你共享了一个标签(即推到一个共享的远程), 你不应该把它移到书中的其他地方。

你需要从CVS来实现,就是你在build立分支时不再创build目录
没有更多的“粘性标签”(只能应用于一个文件)或“分支标签”。
分支和标签是Git中的两个不同的对象,它们总是适用于所有的回购。

你将不再(使用SVN这个时候)必须明确地构build你的仓库:

 branches myFirstBranch myProject mySubDirs mySecondBranch ... tags myFirstTag myProject mySubDirs mySecondTag ... 

这个结构来自于CVS是一个修订系统而不是一个版本系统(请参阅源代码pipe理与版本控制? )。
这意味着通过CVS的标签,SVN的目录副本来模拟分支。

如果您习惯于签收标签,并且开始使用标签,那么您的问题就会变得敏锐。
你不应该;)
一个标签应该代表一个不可变的内容,只用来访问它,并保证每次都得到相同的内容。

在Git中,修订的历史是一系列的提交,形成一个图表。
分支是该图的一个path

 x--x--x--x--x # one branch \ --y----y # another branch 1.1 ^ | # a tag pointing to a commit 
  • 如果你签出一个标签,你将需要创build一个分支来开始工作。
  • 如果您签出分支,您将直接看到该分支的最新提交(“HEAD”)。

请参阅JakubNarębski对所有技巧的回答 ,但坦率地说,在这一点上,你不需要(但是)所有的细节;)

重点是:标签是一个简单的提交指针,你永远不能修改它的内容。 你需要一个分支。


在你的情况下,每个开发人员在一个特定的function:

  • 应该在各自的仓库中创build自己的分支
  • 跟踪他们的同事的存储库中的分支(一个工作在同一个function的分支)
  • 拉/推,以便与同行分享您的工作。

不要直接跟踪你的同事的分支,你可以只跟踪一个“官方”中央仓库的分支,每个人都推动他/她的工作,以整合和分享每个人对这个特定function的工作。

树枝由木头制成,从树干长出来。 标签由纸张(木头的衍生物)制成,像圣诞饰品一样悬挂在树上的各个地方。

您的项目是树,并且将添加到项目中的function将在分支上增长。 答案是分支。

看起来最好的解释方式是标签作为只读分支。 您可以使用分支作为标签,但是您可能会不经意地使用新的提交进行更新。 只要标签存在,标签保证指向相同的提交。

Git Parable解释了一个典型的DVCS如何被创build,以及为什么他们的创build者做了他们所做的事情。 另外,你可能想看一下Git for Computer Scientist ; 它解释了Git中每种对象的types,包括分支和标签。

标签可以是有符号的或无符号的 ; 分支从不签名。

签名标签永远不会移动,因为它们被密码绑定(具有签名)到特定的提交。 未签名的标签没有被绑定,可以移动它们(但移动的标签不是正常的用例)。

分支机构不仅可以进行不同的提交,而且可以这样做。 你应该为你的本地开发项目使用一个分支。 将工作交给Git存储库“在标签上”是没有意义的。

标记用于标记版本,更具体地说,它引用分支上的时间点。 分支通常用于向项目添加特征。

树干 :将成为发展的主体,从项目的开始直到现在。

分支 :将是从中继线中的某个点派生的代码的副本,用于对代码进行重大更改,同时保留中继线中代码的完整性。 如果主要变化按计划进行,通常会重新合并到主干中。

标签 :将是一个时间点上的树干或分支,你想保存。 保留的两个主要原因是,无论是alpha版,beta版,RC版还是RTM版,这都是该软件的主要版本,或者是在应用主干版本之前软件最稳定的一点。

简单:

预计标签始终指向一个项目的同一版本,而标签预计会随着开发的进展而提前。

Git用户手册