我知道git add只保存特定文件的新快照.但我对"快照"一词感到有点困惑.正如我理解git(例如通过那个或那个)源,快照实际上只是与上次提交的差异.
引自2:
它基本上会显示当时所有文件的外观,并存储对该快照的引用.为了提高效率,如果文件没有改变,Git不会再次存储文件,只是指向它已存储的上一个相同文件的链接.
这对我来说听起来与基于文件差异的系统描述完全一样 - .-
编辑:
更具体一点:
我理解,如果未修改blob,则不会更改散列,因此会在进一步提交中使用.对我来说也是有意义的,git可以检测blob之间的相似性,从而消除冗余.
=>如果我将例如vimdiff(仅用于说明概念)称为blob并将输出保存在新的blob中,它会等同吗?
=>如果改变的blob看起来与其他blob有什么共同之处?
简答:不,Git总是记录整个文件.
更长的答案:好的,那不是真的.从逻辑上讲,Git总是记录整个文件.但是,在存储后端,Git对来自所有修订版的所有文件执行增量压缩,因此它甚至可以检测不同文件之间以及所有分支的整个历史记录中的相同内容,而不仅仅是父提交.而且,由于网络协议和存储后端共享相同的格式("包文件"),你会得到相同的效率和.pushfetch
但是,请务必记住这是存储后端的内部实现细节.它不是对象模型的一部分.对象模型是每个提交包含整个树.
这是Git的对象模型:
blob:字节流.基本上是一个文件,但只有它的内容.它没有名字.通过这种方式,Git的工作方式类似于Unix文件系统,文件没有名称,而是将名称与文件关联起来.
树:(mode, name, {tree|blob})三元组的平面(!!!)列表.这相当于Unix目录.它将名称和模式(主要是可执行的或不可执行的)与blob或树相关联.即树可以递归.
commit:指向树的指针和指向零,一个或多个父提交的指针.还包含一个日期戳和两个名称字符串(作者和提交者),最重要的是提交消息.
(本地标记):从技术上讲,不是Git对象.只是一个指向提交的本地文件.
带注释的标记:包含指向提交,名称和注释消息的指针.
signed tag:包含一个带注释的标签(???)和一个数字签名[不确定这个标签,是建在注释标签之上还是重复它?]
note:一段可以附加到任何Git对象的文本.这可以用于向任何Git对象添加任意用户定义的元数据,例如CI服务器可以将代码覆盖结果附加到提交,或者bug跟踪器可以附加到修复错误的提交的票证的链接,Web服务器可以附加MIME类型对于blob,发布管理系统可以将go/no-go投票附加到带注释的标签,......
请注意,只有 blob实际上包含文件数据.其余的只是指针.并且blob没有名称,这意味着只要blob具有相同的内容,它就是相同的blob,因此只在对象库中存在一次.事实上,它甚至只存在于整个Git宇宙中一次!例如,FSF的GPL COPYING文件,只要你保持不变,就会是完全相同的blob,即使在完全不相关的存储库中也是如此!
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |