【问题标题】:Difference between tag and commit message标签和提交消息之间的区别
【发布时间】:2018-08-31 00:55:20
【问题描述】:

我知道提交更改总是需要一条消息,但我何时以及为什么还需要标记提交?假设我做了一些更改并提交使用

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

现在

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

问题是什么时候才有意义。

【问题讨论】:

标签: git git-commit git-tag


【解决方案1】:

在发布您正在生产的软件版本时指定一个标签是有意义的。

你可以这样做:

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

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

git tag v1.0

希望这会有所帮助。

【讨论】:

    【解决方案2】:

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

    定义提交

    commit 是 Git 存储库中的 object。 Git 存储库对象大多是永久的且完全只读的,并且经过一致性检查,因此它们不会被破坏。有四种对象:提交(我们稍后会详细介绍)、treesblob带注释的标记对象 .所有四种类型都由哈希 ID 标识。

    blob 非常粗略地是 Git 存储文件内容的位置:如果您的 README 文件显示为 I am a readme file,则字符串 I am a readme file 将存储为 blob时间>。 tree 对象有点过于简单,它存储文件的 name 以及文件内容的 blob 哈希 ID。因此,为了让提交 1234567... 存储您的 README 文件,Git 有一棵树,上面写着“文件 README 的内容来自 blob c3c2a8983de728ffcf8f0ccaad014349925f23e6”。1

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

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

    提交表单链,这是历史

    因为每个提交都记录了它之前的提交,所以这组提交形成了一个可以向后读取的链:

    A  <-B  <-C   <--master
    

    Git 可以以 name 开头,例如分支名称master,以获取提交C 的哈希ID(无论它的真实哈希ID 可能是:我在这里使用C作为速记而不是实际的哈希)。这个哈希 ID 对于提交 C 是唯一的:没有任何其他提交具有相同的哈希 ID。4 提交 C 本身存储提交 B 的哈希 ID,所以从 C 我们可以找到BB 存储了提交A 的哈希ID,所以从B 我们可以找到A

    这个特定的存储库只有三个提交:Aroot 提交,这是我们做过的第一个提交,所以它没有父级,这让我们可以停止跟踪历史。

    分支和标签名称查找提交

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

    除了名称空间的问题,6主要区别在于 Git 将允许我们使用 git checkout 来“打开”一个分支名称。一旦我们在这样一个分支上,创建一个 new 提交就会产生副作用:它会更改与分支名称相关联的哈希 ID。如果我们检查master 并进行新提交,则存储在新提交中的父ID 是C 的ID。无论 new 提交的哈希 ID 是什么,根据 Git 的计算,新的哈希 ID 都会进入名称 master,因此我们现在有了:

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

    名称master 现在指向新提交D,它又指向C,又指向B,以此类推。分支已经增长,并且 分支名称 指向 latest 提交。每个提交都指向前一个提交。

    你不能“打开”这样的标签。 标签名称 v1.0,一旦它被设置为指向提交C,就会一直指向提交C。所以这是 Git 中分支名称和标签名称之间的主要区别:分支名称会随着时间而变化,甚至在您进行提交时也会自动发生变化。标记名称不应7更改。


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

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

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

    2更准确地说,它是保存的 index,又名 暂存区 又名 cache,由git write-tree.

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

    4哈希 ID 可以不同存储库中重复,但前提是这两个存储库永远不会放在一起。为了确保提交哈希 ID 是唯一的,Git 包含了这些时间戳。这可以确保即使您使用相同的树、相同的父级和相同的日志消息进行了 same 提交,如果您在不同的 时间 提交,它也是一个不同的提交。 (如果你在同时时间做,那真的是一模一样,又何必在意你是做一次还是做两次?5

    5有一个潜在的关注理由,但它非常模糊且几乎无关紧要。

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

    7嗯,几乎没有。有些人真的想要一个“浮动标签”。你可以在 Git 中做到这一点,如果你小心并且知道你在做什么。但是,这并没有什么意义:如果您想要一个移动的名称,请使用分支名称。他们就是这样做的。如果您想要一个不会移动的名称,请使用标签名称。这就是他们所做的。

    【讨论】:

      猜你喜欢
      • 2021-08-27
      • 2013-01-10
      • 2020-09-28
      • 2012-03-05
      • 2010-09-24
      • 2017-02-20
      • 2013-05-30
      • 2011-07-19
      • 2011-08-07
      相关资源
      最近更新 更多