Git大文件存储背后的存储机制是什么?

时间:2015-04-09 05:07:15

标签: git github

Github最近向git引入了extension以便以不同的方式存储大文件。它们究竟是什么意思 扩展用Git中的文本指针替换大文件

1 个答案:

答案 0 :(得分:9)

您可以在git-lfs sources中看到如何"text pointer" is defined

type Pointer struct {
    Version string
    Oid     string
    Size    int64
    OidType string
} 

smudgeclean来源意味着git-lfs可以使用 content filter driver 以便:

  • 在结帐时下载实际文件
  • 在提交时将它们存储在外部源中。

请参阅the pointer specs

  

核心Git LFS的想法是而不是将大blob写入Git存储库,只编写指针文件

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345
(ending \n)
  

Git LFS需要一个URL端点与远程服务器通信   Git存储库可以为不同的远程控制器提供不同的Git LFS端点。

实际文件上传到服务器或从尊重Git-LFS API的服务器下载。

git-lfs man page证实了这一点,提到:

  

实际文件会被推送到 Git LFS API

您需要一个实现该API的Git服务器,以支持上传和下载二进制内容。


关于内容过滤器驱动程序(它存在于Git中很长一段时间,远在lfs之前,并且在这里被lfs用来添加这个"大文件管理"功能),这是大部分工作发生了:

  

涂抹过滤器在从Git存储库检出文件到工作目录时运行。
  Git将Git blob的内容作为STDIN发送,并期望内容以STDOUT的形式写入工作目录。

     

读取100个字节。

     
      
  • 如果内容是ASCII并且与指针文件格式匹配:
      在.git / lfs / objects / {OID}中查找该文件。

  •   
  • 如果不存在,请从服务器下载   将其内容读入STDOUT

  •   
  • 否则,只需将STDIN通过STDOUT传递出去。

  •   
     

清理过滤器在文件添加到存储库时运行   Git将要添加的文件的内容发送为STDIN,并期望内容以GD的形式写入STDOUT。

     
      
  • 将二进制内容从STDIN流式传输到临时文件,同时计算其SHA-256签名。
  •   
  • 检查.git/lfs/objects/{OID}
  • 上的文件   
  • 如果不存在:      
        
    • 将OID排队上传。
    •   
    • 将临时文件移至.git/lfs/objects/{OID}
    •   
  •   
  • 删除临时文件。
  •   
  • 将指针文件写入STDOUT。
  •   

Git 2.11(2016年11月)有一份详细说明如何运作的提交:commit edcc858,由Martin-Louis Bright帮助并签署:Lars Schneider。

  

convert:添加filter.<driver>.process选项

     

Git的清洁/涂抹机制调用外部过滤器进程   每个受过滤器影响的blob。如果Git过滤了很多   然后blobs可以成为外部过滤器进程的启动时间   整个Git执行时间的重要部分。

     

在初步的性能测试中,这位开发人员使用了干净/涂抹   用golang编写的过滤器来过滤12,000个文件。这个过程需要364s   使用现有的过滤机制和5s的新机制。看到   详情请见git-lfs/git-lfs#1382

     

此修补程序添加filter.<driver>.process字符串选项,如果   used,保持外部过滤器进程运行并处理所有blob   基于数据包格式(pkt-line)的协议超过标准输入和   标准输出
  The full protocol is explained in detail in Documentation/gitattributes.txt

     

一些关键决定:

     
      
  • 长时间运行的过滤器过程称为过滤器协议   版本2因为现有的单镜头过滤器调用是   考虑版本1。
  •   
  • Git发送一条欢迎信息,并希望在发布后立即收到回复   外部过滤器流程已经开始。这确保了Git不会   如果版本1过滤器与错误一起使用,则挂起   版本2过滤器的filter.<driver>.process选项。此外,   Git可以检测到这种错误并警告用户。
  •   
  • 设置过滤操作的状态(例如&#34;成功&#34;或&#34;错误)   在实际响应之前(如有必要!)重新设置之后   响应。这两步状态响应的优点是if   过滤器会提前检测到错误,然后过滤器可以进行通信   这和Git甚至不需要创建结构来阅读   响应。
  •   
  • 所有状态响应都是使用刷新终止的pkt-line列表   包。这允许我们发送具有相同的其他状态字段   未来的协议。
  •   

这导致Git 2.12(2017年第一季度)中的警告设置

commit 7eeda8b(2016年12月18日)和commit c6b0831(2016年12月3日)Lars Schneider (larsxschneider)Junio C Hamano -- gitster --于2016年12月27日commit 08721a0合并)

  

docs:警告可能&#39; =&#39;在清洁/涂抹过滤器过程值

     

清洁/涂抹过滤器流程中的路径名值&#34; key=value&#34;对可以   包含&#39; =&#39;字符(在edcc858中介绍)   让用户在文档中了解此问题,添加相应的测试用例,并在contrib中的示例实现的过滤器过程值解析器中修复该问题。