标签与 Git 中的分支有何不同?我应该在这里使用哪个?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1457103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:05:33  来源:igfitidea点击:

How is a tag different from a branch in Git? Which should I use, here?

gitversion-controlbranchgit-branchgit-tag

提问by Bialecki

I am having some difficulty understanding how to use tagsversus branchesin git.

我在理解如何在git 中使用标签分支时遇到了一些困难。

I just moved the current version of our code from cvsto git, and now I'm going to be working on a subset of that code for a particular feature. A few other developers will be working on this as well, but not all developers in our group are going to care about this feature. Should I be creating a branch or a tag? In what situations should I be using one versus the other?

我刚刚将我们代码的当前版本从cvs移到了git,现在我将针对特定功能处理该代码的子集。其他一些开发人员也将致力于此,但并非我们组中的所有开发人员都会关心此功能。我应该创建一个分支还是一个标签?在什么情况下我应该使用一种和另一种?

采纳答案by tvanfosson

A tagrepresents a version of a particular branch at a moment in time. A branchrepresents a separate thread of development that may run concurrently with other development efforts on the same code base. Changes to a branch may eventually be merged back into another branch to unify them.

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

Usually you'll taga particular version so that you can recreate it, e.g., this is the version we shipped to XYZ Corp. A branchis 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.

通常您会标记一个特定的版本,以便您可以重新创建它,例如,这是我们发送给 XYZ 公司的版本。一个分支更像是一种在特定版本的代码上提供持续更新同时继续对其进行开发的策略。您将创建已交付版本的分支,在主线上​​继续开发,但对代表已交付版本的分支进行错误修复。最终,您会将这些错误修复合并回主线。通常,您会同时使用分支和标记。您将拥有各种标记,这些标记可以应用于主线及其分支,标记沿着您可能想要重新创建的每个分支的特定版本(例如,那些交付给客户的版本)——用于交付、错误诊断等。

It's actually more complicated than this -- or as complicated as you want to make it -- but these examples should give you an idea of the differences.

它实际上比这更复杂 - 或者像您想要的那样复杂 - 但是这些示例应该让您了解差异。

回答by Jakub Nar?bski

From the theoreticalpoint of view:

理论角度:

  • tagsare symbolic names for a given revision. They always point to the same object (usually: to the same revision); they do not change.
  • branchesare symbolic names for line of development. New commits are created on top of branch. The branch pointer naturally advances, pointing to newer and newer commits.
  • 标签是给定修订的符号名称。它们总是指向同一个对象(通常:指向同一个修订版);他们不会改变。
  • 分支开发线的符号名称。新的提交是在分支之上创建的。分支指针自然前进,指向越来越新的提交。


From the technicalpoint of view:

技术角度:

  • tagsreside 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 objector blob object(e.g. GPG signature).
  • branchesreside in refs/heads/namespace, and can point only to commit objects. The HEADpointer must refer to a branch (symbolic reference) or directly to a commit (detached HEAD or unnamed branch).
  • remote-tracking branchesreside in refs/remotes/<remote>/namespace, and follow ordinary branches in remote repository <remote>.
  • 标签驻留在refs/tags/命名空间中,并且可以指向标签对象(带注释的和可选的 GPG 签名标签)或直接提交对象(本地名称较少使用的轻量级标签),或者在极少数情况下甚至指向树对象blob 对象(例如 GPG 签名) )。
  • 分支驻留在refs/heads/命名空间中,并且只能指向提交对象。该HEAD指针必须引用分支(符号引用)或直接连接到一个提交(独立HEAD或无名分支)。
  • 远程跟踪分支驻留在refs/remotes/<remote>/命名空间中,并跟随远程存储库中的普通分支<remote>


See also gitglossarymanpage:

另请参阅gitglossary联机帮助页:

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 存储库可以跟踪任意数量的分支,但您的工作树只与其中一个(“当前”或“签出”分支)相关联,并且 HEAD 指向该分支。

标签

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

标签对象

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

回答by jub0bs

If you think of your repository as a book that chronicles progress on your project...

如果您将存储库视为记录项目进度的书...

Branches

分行

You can think of a branch as one of those sticky bookmarks:

您可以将分支视为粘性书签之一

enter image description here

在此处输入图片说明

A brand new repository has only one of those (called master), which automatically moves to the latest page (think commit) you've written. However, you're free to create and use more bookmarks, in order to mark other points of interest in the book, so you can return to them quickly.

一个全新的存储库只有其中一个(称为master),它会自动移动到您编写的最新页面(想想commit)。但是,您可以自由创建和使用更多书签,以便标记书中的其他兴趣点,以便您可以快速返回到它们。

Also, you can always move a particular bookmark to some other page of the book (using git-reset, for instance); points of interest typically vary over time.

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

Tags

标签

You can think of tags as chapter headings.

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

bookmarks

书签

It may contain a title (think annotated tags) or not. A tag is similar but different to a branch, in that it marks a point of historicalinterest in the book. To maintain its historical aspect, once you've shared a tag (i.e. pushed it to a shared remote), you're not supposed tomove it to some other place in the book.

它可能包含或不包含标题(想想带注释的标签)。标签与分支相似但不同,因为它标记了书中的历史兴趣点。为了保持其历史方面,一旦您共享了标签(即,将其推送到共享遥控器),您就不应将其移动到书中的其他位置。

回答by VonC

What you need to realize, coming from CVS, is that you no longer create directorieswhen setting up a branch.
No more "sticky tag" (which can be applied to just one file), or "branch tag".
Branch and tags are two different objects in Git, and they always apply to the allrepo.

您需要意识到,来自 CVS,您在设置分支时不再创建目录
不再有“粘性标签”(只能应用于一个文件)或“分支标签”。
分支和标签在 Git 中是两个不同的对象,它们始终适用于所有存储库。

You would no longer (with SVN this time) have to explicitly structure your repository with:

您将不再(这次使用 SVN)必须使用以下内容显式构建您的存储库:

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

That structure comes from the fact CVS is a revision systemand not a version system (see Source control vs. Revision Control?).
That means branches are emulated through tags for CVS, directory copies for SVN.

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

Your question makes senses if you are used to checkout a tag, and start working in it.
Which you shouldn't ;)
A tag is supposed to represent an immutablecontent, used only to access it with the guarantee to get the same content every time.

如果您习惯于签出标签并开始使用它,那么您的问题很有意义。
你不应该这样做;)
标签应该代表一个不可变的内容,仅用于访问它并保证每次都获得相同的内容。

In Git, the history of revisions is a series of commits, forming a graph.
A branch is one path of that graph

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

x--x--x--x--x # one branch
    \ 
     --y----y # another branch
       1.1
        ^
        |
        # a tag pointing to a commit
  • If you checkout a tag, you will need to create a branch to start working from it.
  • If you checkout a branch, you will directly see the latest commit it('HEAD') of that branch.
  • 如果你签出一个标签,你将需要创建一个分支来开始工作。
  • 如果您签出一个分支,您将直接看到该分支的最新提交('HEAD')。

See Jakub Nar?bski's answerfor all the technicalities, but frankly, at this point, you do not need (yet) all the details ;)

有关所有技术细节,请参阅Jakub Nar?bski 的回答,但坦率地说,此时,您(还)不需要所有细节;)

The main point is: a tag being a simple pointer to a commit, you will never be able to modify its content. You need a branch.

要点是:标签是指向提交的简单指针,您将永远无法修改其内容。你需要一个分支。



In your case, each developer working on a specific feature:

在您的情况下,每个开发人员都在研究特定功能:

  • should create their own branch in their respective repository
  • track branches from their colleague's repositories (the one working on the same feature)
  • pulling/pushing in order to share your work with your peers.
  • 应该在各自的存储库中创建自己的分支
  • 从同事的存储库中跟踪分支(处理相同功能的那个)
  • 拉/推以便与您的同龄人分享您的工作。

Instead of tracking directly the branches of your colleagues, you could track only the branch of one "official" central repository to which everyone pushes his/her work in order to integrate and share everyone's work for this particular feature.

您可以只跟踪一个“官方”中央存储库的分支,而不是直接跟踪您同事的分支,每个人都将他/她的工作推送到该分支,以便集成和共享每个人针对此特定功能的工作。

回答by Jason

Branches are made of wood and grow from the trunk of the tree. Tags are made of paper (derivative of wood) and hang like Christmas Ornaments from various places in the tree.

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

Your project is the tree, and your feature that will be added to the project will grow on a branch. The answer is branch.

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

回答by Vassili Gorshkov

It looks like the best way to explain is that tags act as read only branches. You can use a branch as a tag, but you may inadvertently update it with new commits. Tags are guaranteed to point to the same commit as long as they exist.

看起来最好的解释方式是标签充当只读分支。你可以使用一个分支作为标签,但你可能会不经意地用新的提交更新它。只要标签存在,就保证它们指向同一个提交。

回答by Greg Hewgill

Tags can be either signed or unsigned; branches are never signed.

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

Signed tags can never move because they are cryptographically bound (with a signature) to a particular commit. Unsigned tags are not bound and it is possible to move them (but moving tags is not a normal use case).

签名标签永远不会移动,因为它们以加密方式绑定(带有签名)到特定提交。未签名的标签不受约束,可以移动它们(但移动标签不是正常用例)。

Branches can not only move to a different commit but are expectedto do so. You should use a branch for your local development project. It doesn't quite make sense to commit work to a Git repository "on a tag".

分支不仅可以移动到不同的提交,而且预计会这样做。您应该为本地开发项目使用分支。将工作提交到“在标签上”的 Git 存储库并没有多大意义。

回答by Gazzer

I like to think of branchesas where you're going, tagsas where you've been.

我喜欢将分支机构视为您要去的地方,将标签视为您去过的地方

A tag feels like a bookmark of a particular important point in the past, such as a version release.

标签感觉就像过去某个特定重要点的书签,例如版本发布。

Whereas a branch is a particular path the project is going down, and thus the branch marker advances with you. When you're done you merge/delete the branch (i.e. the marker). Of course, at that point you could choose to tag that commit.

而分支是项目向下的特定路径,因此分支标记会与您一起前进。完成后合并/删除分支(即标记)。当然,此时您可以选择标记该提交。

回答by Bombe

The Git Parableexplains how a typical DVCS gets created and why their creators did what they did. Also, you might want to take a look at Git for Computer Scientist; it explains what each type of object in Git does, including branches and tags.

Git的比喻解释了如何一个典型的DVCS被创建,为什么它们的创造者做他们做了什么。另外,您可能想看看计算机科学家的 Git;它解释了 Git 中每种类型的对象的作用,包括分支和标签。

回答by Number45

A tag is used to mark a version, more specifically it references a point in time on a branch. A branch is typically used to add features to a project.

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