我正在尝试了解标签。
如果标记是指向提交的指针。提交由分阶段的更改组成。
标签是否包含以前的提交? (我知道是因为我做了实验)。但是怎么了?
答案 0 :(得分:2)
如果我使用特定提交创建标签。这个标签将包含特定提交之前的所有提交(更改)吗?
标签是引用提交的标签。
请参见“ 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”
答案 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压缩,还是完整存储为“松散”对象,您都将获得完整的完整文件。