标记和提交消息之间的区别

时间:2018-03-21 18:38:02

标签: git git-commit git-tag

我理解一个人总是需要一条消息来提交更改但是我何时以及为什么还需要标记提交?让我们说我做了一些更改,然后我使用

git add -A
git commit -m "add feature 1"

现在

git tag -a -m "includes feature 1" v0.1

问题是这何时有意义。

2 个答案:

答案 0 :(得分:5)

当您发布您正在制作的软件版本时指定标签是有意义的。

然后你可以这样做:

git tag -a v1.0 -m "Release Version 1.0"

就像我提到的评论一样,您不必在每次提交后进行标记,就像您在帖子中提到的那样,如果您不想包含消息,也可以创建轻量级标记。这看起来像是:

git tag v1.0

希望这有帮助。

答案 1 :(得分:3)

首先,让我们定义提交分支名称标记名称之间的区别。然后,我将其余部分外包给现有问题和What is the difference between an annotated and unannotated tag?的优秀答案。请注意,轻量级标记(未注释)不会收到消息;只有带注释的标记会收到消息。

定义提交

commit 是Git存储库中的对象。 Git存储库对象大部分是永久性的,完全是只读的,并且是一致性检查的,因此它们是不腐败的。有四种对象:提交(我们将在稍后详细描述), blob 带注释的标记对象。所有四种都由哈希ID标识。

blob 非常粗略地说是Git存储您文件的内容:如果您的README文件显示I am a readme file,则字符串I am a readme file存储为 blob tree 对象稍微过于简单,存储文件的名称以及文件内容的blob哈希ID。因此,为了让提交1234567...存储您的README文件,Git有一个树,上面写着"文件README包含来自blob c3c2a8983de728ffcf8f0ccaad014349925f23e6"的内容。 1

在任何情况下,每个提交都会存储一个哈希ID,这是您提交时源文件 2 的保存快照。它还存储此提交的提交的哈希ID,以便Git可以在历史记录中向后工作以查找所有提交。它存储您的姓名和电子邮件地址以及时间戳,作为提交者以及何时提交。 3

在这些必需的项目 - 树,父,作者和提交者-Git之后添加日志消息,就Git本身而言,这完全是任意的。你根本不需要提供任何日志消息,如果你提供了一个日志消息,它就没有意义。但是,当他们探索存储在存储库中的历史记录时,它将显示给您和其他人。

提交表单链,这是历史

因为每个提交都记录了它早期的提交,所以提交集形成了一个可以向后读的链:

A  <-B  <-C   <--master

Git可以以名称开头,就像分支名称master一样,以获取提交C的哈希ID(无论其真正的哈希ID是什么:我使用C这里是速记而不是实际哈希)。此哈希ID对于提交C是唯一的:任何其他提交都没有相同的哈希ID。 4 提交C本身存储提交B的哈希ID,所以从C我们可以找到BB存储提交A的哈希ID,因此从B我们可以找到A

此特定存储库只有三个提交:A root 提交,是我们创建的第一个提交,因此它没有父级,这让我们可以停止跟踪历史记录。 / p>

分支和标签名称查找提交

但是这也告诉我们分支名称是什么和做什么: 分支名称是一个通过提交的哈希ID来标识提交的名称。一个标签名称做同样的事情。所以现在我们可能想知道:差异是什么?我们何时应该使用分支名称,何时应该使用标记名称?

除了名称空间的问题, 6 之外,主要的不同之处在于Git会让我们得到&#34; on&#34;分支名称,使用git checkout。一旦我们进入这样的分支,创建 new 提交就会产生副作用:更改与分支名称相关联的哈希ID 。如果我们签出master并进行新提交,则新提交中存储的父ID是C的ID。无论 new 提交的哈希ID是由Git计算的,新的哈希ID都会进入名称master,因此我们现在拥有:

A--B--C--D   <-- master

名称master现在指向新提交D,其指向C,其指向B,因此上。分支已增长,分支名称指向最新提交。每个提交都指向前一个提交。

你不能得到&#34; on&#34;像这样的标签。 标记名称 v1.0一旦设置为指向提交C,就会永远指向提交C。因此,这是Git中分支名称和标记名称之间的主要区别:分支名称随时间变化,甚至在您提交时自动执行此操作。标签名称永远不应 7 更改。

1 c3c2a8983de728ffcf8f0ccaad014349925f23e6是读取I am a readme file的内容的哈希ID。您可以通过运行以下shell命令找到它:

$ echo 'I am a readme file' | git hash-object -t blob --stdin
c3c2a8983de728ffcf8f0ccaad014349925f23e6

请注意,如果拥有此内容,Universe中任何Git存储库中任何位置的任何blob对象都具有此哈希ID!内容必须只包含那19个字节,包括终止换行符(没有回车符)。

2 更准确地说,它是保存的索引,又名临时区域又名缓存,由git write-tree写出来。

3 Git将这些存储两次,一次作为提交的作者,再次作为提交者。如果您是两个,例如,将他们通过电子邮件发送给您的其他人提交,并将其插入存储库,则两者会变得不同:那么 author 就是向您发送提交的人,但是你是提交者。在其他情况下,两者变得不同。在大多数情况下,没有人关心,但运行git log --pretty=fuller来看两者。

4 哈希ID 可以不同的存储库中重复,但前提是这两个存储库永远不会放在一起。为了确保提交哈希ID是唯一的,Git包含那些时间戳。即使您使用相同的树和相同的父级和相同的日志消息进行相同的提交,如果您在不同的时间进行,它也可以确保&# 39;不同的提交。 (如果你在相同的时间进行,那么它真的完全相同,你为什么要关心你做一次还是做两次? 5

5 有一个潜在的理由需要关心,但它很晦涩,而且大多不相关。

6 从技术上讲,分支名称是以refs/heads/开头的引用,例如,refs/heads/master是{{1}的完整拼写分支。标记名称是以master开头的引用,例如refs/tags/。这些是参考名称空间,其中包括refs/tags/v1.0refs/remotes/refs/notes/refs/replace/

7 好吧,几乎没有。有些人真的想要一个&#34;浮动标签&#34;。如果你小心并且知道自己在做什么,那么可以在Git中执行此操作。但是,没有真正的意义:如果你想要一个移动的名字,请使用分支名称。这就是他们的所作所为。如果您想要一个不移动的名称,请使用标记名称。这就是他们所做的事情。