我有一些困难理解如何使用标签与分支在git。
我只是将当前版本的代码从cvs移到git,现在我将针对特定的特性处理该代码的一个子集。其他一些开发人员也将致力于此,但并不是我们团队中的所有开发人员都会关心此功能。我应该创建一个分支还是一个标签?在什么情况下我应该使用其中一种而不是另一种?
我有一些困难理解如何使用标签与分支在git。
我只是将当前版本的代码从cvs移到git,现在我将针对特定的特性处理该代码的一个子集。其他一些开发人员也将致力于此,但并不是我们团队中的所有开发人员都会关心此功能。我应该创建一个分支还是一个标签?在什么情况下我应该使用其中一种而不是另一种?
标签可以是有符号的,也可以是无符号的;分支从不签名。
有签名的标记永远不能移动,因为它们以加密方式(使用签名)绑定到特定的提交。Unsigned标签是不绑定的,可以移动它们(但是移动标签不是一个正常的用例)。
分支不仅可以移动到不同的提交,而且还可以这样做。您应该为本地开发项目使用分支。“在标记上”将工作提交到Git存储库是没有意义的。
标记表示特定分支在某一时刻的版本。分支代表一个独立的开发线程,它可以与相同代码库上的其他开发工作同时运行。对一个分支的更改最终可能合并回另一个分支以统一它们。
Usually you'll tag a particular version so that you can recreate it, e.g., this is the version we shipped to XYZ Corp. A branch is more of a strategy to provide on-going updates on a particular version of the code while continuing to do development on it. You'll make a branch of the delivered version, continue development on the main line, but make bug fixes to the branch that represents the delivered version. Eventually, you'll merge these bug fixes back into the main line. Often you'll use both branching and tagging together. You'll have various tags that may apply both to the main line and its branches marking particular versions (those delivered to customers, for instance) along each branch that you may want to recreate -- for delivery, bug diagnosis, etc.
它实际上比这更复杂——或者像你想的那样复杂——但这些例子应该能让你了解其中的区别。
从理论角度看:
标签是给定修订的符号名称。它们总是指向相同的对象(通常是:指向相同的修订);它们不会改变。 分支是开发线的象征性名称。在分支的顶部创建新的提交。分支指针自然地向前移动,指向越来越新的提交。
从技术角度看:
tags reside in refs/tags/ namespace, and can point to tag objects (annotated and optionally GPG signed tags) or directly to commit object (less used lightweight tag for local names), or in very rare cases even to tree object or blob object (e.g. GPG signature). branches reside in refs/heads/ namespace, and can point only to commit objects. The HEAD pointer must refer to a branch (symbolic reference) or directly to a commit (detached HEAD or unnamed branch). remote-tracking branches reside in refs/remotes/<remote>/ namespace, and follow ordinary branches in remote repository <remote>.
参见gitglossary manpage:
branch A "branch" is an active line of development. The most recent commit on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch head, which moves forward as additional development is done on the branch. A single git repository can track an arbitrary number of branches, but your working tree is associated with just one of them (the "current" or "checked out" branch), and HEAD points to that branch. tag A ref pointing to a tag or commit object. In contrast to a head, a tag is not changed by a commit. Tags (not tag objects) are stored in $GIT_DIR/refs/tags/. [...]. A tag is most typically used to mark a particular point in the commit ancestry chain. tag object An object containing a ref pointing to another object, which can contain a message just like a commit object. It can also contain a (PGP) signature, in which case it is called a "signed tag object".
Git寓言解释了典型的DVCS是如何创建的,以及它们的创造者为什么要这样做。另外,你可能想看看Git for Computer Scientist;它解释了Git中每种类型的对象的功能,包括分支和标记。
从CVS中您需要了解的是,在设置分支时不再需要创建目录。 不再有“粘贴标签”(只能应用于一个文件),或“分支标签”。 分支和标记是Git中两个不同的对象,它们总是应用于all repo。
您将不再(使用SVN)必须显式地构造您的存储库:
branches
myFirstBranch
myProject
mySubDirs
mySecondBranch
...
tags
myFirstTag
myProject
mySubDirs
mySecondTag
...
这种结构源于CVS是一个修订系统而不是版本系统(参见源代码控制vs.修订控制?) 这意味着通过CVS的标记和SVN的目录副本模拟分支。
如果您习惯于签出标记并开始在其中工作,那么您的问题就有意义了。 你不应该这样做;) 标签应该表示一个不可变的内容,只用于访问它,并保证每次都获得相同的内容。
在Git中,修订的历史是一系列的提交,形成了一个图表。 分支是图的一条路径
x--x--x--x--x # one branch
\
--y----y # another branch
1.1
^
|
# a tag pointing to a commit
如果签出一个标记,您将需要创建一个分支来开始从它开始工作。 如果你签出一个分支,你将直接看到该分支的最新提交('HEAD')。
关于所有的技术细节,请参阅Jakub narylbski的答案,但坦率地说,在这一点上,你还不需要所有的细节;)
主要的一点是:一个标签是一个简单的指向提交的指针,你永远不能修改它的内容。你需要一个分支。
在你的例子中,每个开发人员都致力于一个特定的功能:
是否应该在各自的存储库中创建自己的分支 跟踪来自同事的存储库的分支(在同一特性上工作的那个) 拉/推是为了和同事分享你的工作。
您可以不直接跟踪同事的分支,而是只跟踪一个“官方”中央存储库的分支,每个人都将他/她的工作推送到这个存储库,以便集成和共享每个人的工作。
没有什么比喻是完美的,但是您可以将您的存储库想象成一本记录项目进展的书。
分支机构
你可以把分支想象成一个粘性书签:
全新的存储库只有其中一个(称为master main),它自动移动到您所编写的最新页面(考虑提交)。但是,你可以自由地创建和使用更多的书签,以便标记书中其他感兴趣的点,这样你就可以快速返回到它们。
此外,你总是可以将一个特定的书签移动到书的其他页面(例如,使用git-reset);兴趣点通常随时间变化。
Tags
你可以把标签看作章节标题。
它可能包含标题(考虑带注释的标签),也可能不包含。标签与分支相似但又不同,因为它标记了书中历史兴趣的点。为了保持它的历史特性,一旦你共享了一个标签(即把它推到一个共享的遥控器上),你就不应该把它移动到书中的其他地方。
树枝是木头做的,从树干上长出来。标签由纸(木材的衍生品)制成,像圣诞装饰品一样挂在树上的各个地方。
您的项目是树,您将添加到项目中的特性将在分支上生长。答案是分支。
我喜欢把分支看作你要去的地方,标签看作你去过的地方。
标记就像过去某个特定重要点的书签,比如版本发布。
而分支是项目前进的特定路径,因此分支标记会随着您一起前进。当你完成时,你合并/删除分支(即标记)。当然,在这一点上,您可以选择标记该提交。
我们使用
开发环境中的分支用于特性开发或错误修复 功能分支上测试环境的轻量级标记 release/prd的注释标记(主要分支)
在每个带注释的标签之后,所有的特征分支都从主分支中重新建立基础。
正如其他人所说,分支是一条开发线,随着更新提交的到来,头部会向前移动。这是功能开发的理想选择。
轻量级标签固定于特定的提交,这使得创建内部版本并让qa团队在开发完成后测试功能成为理想的选择。
注释标记非常适合从发布到生产,因为我们可以在将测试的特性分支合并到主分支(稳定)时添加正式的消息和其他注释。