Mac 命令行下Git LFS的使用
Git FLS(Large File Storage,大文件存储)是Git出的一个用于解决大文件存储的插件,目前主流的代码托管工具如Github、GitLab等都支持,它把需要跟踪的大文件与原来Git文件分开存储,从而达到精简仓储体积、提高Git性能的目的。在之前,Git管理代码,将所有文件存储在一个仓库里,其中包括一些二进制大文件,这些大文件每次改动一点点,Git仓库都会积累可观的代码量,因此导致原Git仓库体积巨大、克隆变慢,Git FLS的出现就是为了解决大文件存储而出现的。
Mac下有两种安装方式,一是下载https://github.com/github/git-lfs/releases
插件,然后解压缩安装,即命令行下执行:
tar xf git-lfs-*.tar.gz
cd git-lfs-*
sudo ./install.sh
另一种是使用mac的包管理工具homebrew来安装,安装homebrew后,只需要在命令行执行: brew install git-lfs即可安装成功.可在命令行下输入git lfs version验证是否安装成功。
终端可以看到本地已经上传成功了,我们去打开浏览器看下远程文件是都上传了。
可以看到,远程已经有libssl.a文件了,我们继续点击进去查看下里面的文件:
发现内容中有个版本、希尔值、大小,说明Git服务端已经将我们上传的静态库文件存储到了另一个仓库中,而只是在当前的Git仓库存储相应文件的哈希“指针”值。至于服务端会将静态文件存储在哪里这是由Git服务来决定的,我们查看不到,只是知道被标记为“大文件”的静态文件被存储到了除Git以外的地方,但是在本地,我们是可以查看到的,事实上本地被跟踪的文件存储在.git下lfs中,最终存储的也是文件哈希值,而原来的文件则被存到objects中,同样也是存储的哈希值,如图:
在上传文件时会依次上传objects和lfs下的文件到远端.
这里分为两种情况来看,一是克隆一个工程文件到本地,二是更新远端到本地。
对于克隆一个全新的文件到本地,我们执行git clone
[email protected]:carowner-app/spec_repo.git默认是会将该工程里fls管理对象全部下载下来的,也就是全部下载,但是也可以通过设置一些参数来只下载仓库文件,而不下载fls管理的大文件.即clone时在前面加上一句: GIT_LFS_SKIP_SMUDGE=1 git clone [email protected]:carowner-app/spec_repo.git即可,克隆到本地后,会发现例如被跟踪的libssl.a文件,实际大小只有130多字节,而实际上它有11.1M大小,libssl.a在本地也是哈希值显示。
我们压缩这个工程,同时也压缩之前的工程,两个工程比较下大小:
执行GIT_LFS_SKIP_SMUDGE=1的工程压缩大小为12M,没有执行的为18M,可能当前的.a包也不够大,所以看起来只有6M的差距,效果似乎并不是很大.但是对于大比较打的文件比较多的文件时,效果可能会很明显。
对于以只下载仓库文件的方式克隆下来的工程,如果后面又需要使用fls中的文件时,可以通过配置后,即git config lfs.fetchinclude ‘xxxx’,然后执行git lfs pull即可,这样配置的xxx文件就会被下载下来,打开文件插卡,相应的文件内容不再是哈希值,而是数据文本了,而且大小也改变了。这里可以有许多配置,可以正向配置lfs.fechinlude,也可以反向配置lfs.fetchexclude等,还可以配置黑白名单,前面我们仅以lfs.fetchinclude为例子,其它的可以见附件参考资料,实验表明确实可以按“需”下载相应静态文件.
四. 遇到问题。
Q1:本地如何将静态文件上传到远端?
A1: 对于初次使用LFS的工程,首先要执行git fls install,初始化,然后执行git lfs track ‘xxxx’添加追踪文件,上传静态文件时这里就需要将静态文件的名字或类型添加到追踪(这样上传到Git服务后,Git服务就会把该静态文件处理为“大文件”进行存储),然后将静态文件添加到工程中,执行git add .将其加到仓库中,最后git push origin master,这样就将静态文件上传到了远端。
Q2:其它用户如何更新静态库?
A2:其它用户更新静态库分两种理解,一种是尚未克隆工程,这是默认是将全部FLS管理的文件下载下来的,用户可以通过设置,从而只下载仓库有关的代码,LFS可以放到后面按“需”再下载。另一种是用户已经下载了FLS管理的工程,这时用户只需要执行git fls pull即可更新,默认也是将LFS管理的物理文件都更新,不过可以在执行pull之前通过git config lfs.fetchinclude “xxx”或者git config lfs.fetchexclude “xxx”等来实现要不要更新某个被LFS管理的文件的物理数据到本地来。
Q3:通过LFS是否提升了clone的速度?
A3:理论上只要不下载LFS管理的文件克隆的速度会很快,而本次学习中这却是非常疑虑的地方,虽然对于LFS管理的文件确实可以实现只下载其哈希文件指针,而暂时不下载其物理数据到本地来减少本地工程的大小,但是即使设置了GIT_LFS_SKIP_DEMUGE=1,克隆时还是会很慢,可能是哪里的还不懂,网上一些资料也没看到有这类问题的分析,因此,本次学习中我感觉还是把整个工程克隆下来似的,有点慢(虽然我也认为即使大工程一一排除哪些文件需要克隆有点繁琐而且各个库之间可能存在相互引用因而也不现实,当然理论上是可以单独按“需”下载自己需要的静态库文件)。或许Git Fls只是致力于Git服务端的分布式存储,或许网络真的慢,当然最大可能是我尚未了解到这个问题的本质。
Q4: 全部下载下来后工程有多大?
A4: 以本次实验为例,我增加了一个大小为11.1M的libssl.a文件,设置GIT_FLS_SKIP_SMUDEGE=1的方式只克隆仓库文件,最后发现下载下来的libssl.a文件内容是哈希值,大小为133 字节,初看确实是满足我的实验期望的,压缩工程文件后只有35KB大小,而之前的是6M大小(以最里层的工程文件夹为压缩根目录,这里是cd到第二个spec_repo文件夹下,见附件),这样一看本地还确实是省下不小空间了。(实验采用控制变量法,为简便起见,原工程是新创的一个空白工程,往里面拖了一个libssl.a文件得到现工程)
附:
参考链接:https://zzz.buzz/zh/2016/04/19/the-guide-to-git-lfs/
https://www.jianshu.com/p/493b81544f80