标签是否包含先前提交的所有更改?

时间:2019-09-05 02:03:22

标签: git

我正在尝试了解标签。

如果标记是指向提交的指针。提交由分阶段的更改组成。

标签是否包含以前的提交? (我知道是因为我做了实验)。但是怎么了?

3 个答案:

答案 0 :(得分:2)

  

如果我使用特定提交创建标签。这个标签将包含特定提交之前的所有提交(更改)吗?

标签是引用提交的标签。

  • lightweight tag只是对提交SHA1的直接引用(应该保留在本地,而不是被推送)
  • annotated tag是常规的Git对象(带有作者和日期:可以推送),并且是对提交的引用。

请参见“ Why should I care about lightweight vs. annotated tags?

我在2011年的“ How does git store files?”中提到,提交是快照:标签是在存储库中引用所有内容的便捷方法。
参见Simon Denier的文章“ Demystifying Git: 3 Concepts to Understand the Git Model

https://sogilis.com/wp-content/uploads/2015/05/changeset.png

答案 1 :(得分:1)

重复使用您的单词:不需要标签(或分支)即可拥有提交的历史记录:单独的提交“包含”其历史记录。

一种可视化此方法:

  • 首先查看您的master分支的历史记录,您将看到一个提交列表,其中列出了每个提交的sha1:

    # --oneline allows to have a shorter description of each commit :
    $ git log --oneline master
    eacf32b (HEAD, master) newest commit
    dd2a663 previous commit
    28c9910 yet annother commit
    ...
    
  • 现在您有了sha1的列表,您可以使用其sha1查看任何提交的历史记录:

    $ git log --oneline dd2a663
    dd2a663 previous commit
    28c9910 yet annother commit
    ...
    

如您所见:命名提交足以查看其所有历史记录。


标签只是命名提交的一种方式;它包含其历史记录的事实不是标记的功能,而是提交的功能。

答案 2 :(得分:0)

您从一个不好的地方开始,这会误导您:

  

如果...提交由分阶段的更改组成...

承诺没有改变;提交就是快照。

从某种意义上说,它并不重要:

  • 运行git checkout commit可以获取快照,无论它们在内部如何存储。
  • 运行,例如git diff commit1 commit2会向您显示一个更改集,而不管这两个提交在内部如何存储。运行git show commit只会使Git运行git diff parent-of-commit commit,从而显示更改集。

因此Git将根据需要来回转换。但是底层存储实际上是 快照。 1

标记名,例如v1.2,可以直接指向提交,也可以指向内部标记对象,而内部对象又指向提交。无论哪种情况,标签都会结束选择该提交的操作,该提交代表应提取状态的所有文件的完整快照,您可以运行:

git checkout v1.2

并将这些文件放入您的工作树中。您将它们作为“分离的HEAD”而不是放在分支上,但是文件在那里。


1 深入到对象模型级别的以下,对象被压缩为 pack文件,在文件包文件中,它们可以是delta-压缩。此时,文件结束时可以表示为“从对象A提取一些字节,然后从对象B提取一些字节,删除某些字节,然后插入其他替换内容”或重建文件所需的一切。但是,这些增量链并不是真正可见的:Git的可见存储仅下降到对象级别。您可以这样做:

git rev-parse a123456:lib/foo.py

并找到名称为a123456的提交lib/foo.py中存储的文件的对象哈希ID,然后可以使用以下命令提取该对象的字节:

git cat-file -p <hash>

无论拥有该哈希ID的对象是否在压缩文件中进行了delta压缩,还是完整存储为“松散”对象,您都将获得完整的完整文件。