今天来聊一聊GIT LFS存储方案
先来说明一下为什么需要自定义LFS API 机制,存储到OSS/私服类场景。 国内的阿里云/OSChina等都提供免费的代码仓库,但是针对仓库基本上都是有存储容量的限制,大文件存储提交时,经常会提示超过200MB,不允许提交等场景。通过此方案可以实现将仓库里面的代码存储到OSS,也就是代码仓库我们继续使用阿里云/OSchina, 但是大文件存储,我们单独配置,实现自定义存储机制。
基础知识
Git Large File Storage(简称 Git LFS)是一个由 GitHub 开发的 Git 扩展,用于更有效地处理大型文件。在标准的 Git 版本控制系统中,所有的文件变更都会被存储为差异(diff),这意味着即使是大型文件的微小变更也会导致整个文件被重新存储。这在处理大型文件(如视频、音频、大型二进制文件等)时会导致仓库迅速膨胀,并且使得克隆和同步仓库变得非常缓慢和低效。
使用 Git LFS,你可以更高效地管理大型文件,同时保持 Git 的灵活性和版本控制的优势。
项目中如何使用GIT LFS配置
针对项目根目录,增加配置文件 .gitattributes ,配合 Git LFS 使用,告诉 Git 使用 Git LFS 来处理大文件。
*.png filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.deb filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.msi filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.rar filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
以上是告诉GIT仓库,如何处理大文件机制, 是将png/zip/rpm/deb类文件类型,通过大文件存储来实现。
如果我们使用的是阿里云的云效代码仓库,我们针对lfs配置后,提交代码,代码仓库大文件存储,会自动生效,并将相关文件配置的后缀,自动同步到大文件存储中去。 如下所示:
Git LFS OSS/私服数据存储方案
针对Git LFS,基于HTTP协议, 我们可以实现自己的大文件存储方案到OSS存储或者私服存储解决。
也就是我们基于LFS API , 实现自己的LFS Config配置,即可基于当前仓库源,同步大文件存储仓库。
具体官方API地址 : github.com/git-lfs/git…
大概思路是: 增加HTTP 协议接口,告知GIT LFS 上传机制和下载机制。
Git LFS API接口对接
本身实现代码如下:(JAVA)
@RequestMapping("/upload/{oid}")
public void upload(
@PathVariable String oid, HttpServletRequest request, HttpServletResponse response)
throws IOException {
Map<String, String> headerMap = JakartaServletUtil.getHeaderMap(request);
Map<String, String> paramsMap = JakartaServletUtil.getParamMap(request);
try (InputStream inputStream = request.getInputStream();
ByteArrayInputStream byteArrayInputStream =
new ByteArrayInputStream(inputStream.readAllBytes())) {
Console.log("upload header:{}", JSONUtil.toJsonStr(headerMap));
Console.log("upload params:{}", JSONUtil.toJsonStr(paramsMap));
BitifulOssLib.putObject(oid, byteArrayInputStream);
response.setCharacterEncoding("utf-8");
response.setContentType(ContentType.JSON.getValue());
PrintWriter writer = response.getWriter();
writer.write("ok");
writer.flush();
writer.close();
}
}
@RequestMapping("/objects/batch")
public void objectsBatch(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Map<String, String> headerMap = JakartaServletUtil.getHeaderMap(request);
Map<String, String> paramsMap = JakartaServletUtil.getParamMap(request);
String requestBody = JakartaServletUtil.getBody(request);
// NoSuchMethodError javax.servlet.http.HttpServletMapping
// javax.servlet.http.HttpServletRequest.getHttpServletMapping()
Console.log("objects_batch header:{}", JSONUtil.toJsonStr(headerMap));
Console.log("objects_batch params:{}", JSONUtil.toJsonStr(paramsMap));
Console.log("objects_batch requestBody:{}", requestBody);
Document uploadDoc = DocuLib.parse(requestBody);
String authorization = StringLib.toStr(headerMap.get("authorization"), "");
String operation = DocuLib.getStr(uploadDoc, "operation");
List<Document> objectsList = DocuLib.getList(uploadDoc, "objects");
switch (operation) {
case "upload":
objectsList = gitLfsApiService.upload(authorization, objectsList);
break;
case "download":
objectsList = gitLfsApiService.download(authorization, objectsList);
break;
}
Document responseDoc =
new Document().append("transfer", "basic").append("objects", objectsList);
response.setCharacterEncoding("utf-8");
response.setContentType("application/vnd.git-lfs+json");
PrintWriter writer = response.getWriter();
writer.write(JSONUtil.toJsonStr(responseDoc));
writer.flush();
writer.close();
}
Git配置增加.lfsconfig 配置文件,将LFS对接调整到指定服务
操作命令如下:
git config -f .lfsconfig lfs.url "针对LFS API实现的自己的HTTP接口地址" "basic"
GIt LFS 授权/权限控制
通过自己实现的LFS接口,需做好权限控制,以上是我自己调通的部分,针对权限机制,可基于代码层自行做好控制即可。
最终呈现(个人版)
将仓库大文件存储到缤纷云,阿里云效仅存储代码,不存储大文件