Uploading Lfs Objects: 0% (0/1)

为什么选择使用 Git LFS?

Git LFS 为了解决大文件托管的效率问题,提供了五大特性,抽象看来为:

  • 更大:支持GB级别的大文件版本控制。

  • 更小:让Git仓库空间占用减小。

  • 更快:仓库的克隆和拉取更快。

  • 透明:Git使用上对用户完全透明。

  • 兼容:权限控制上完全兼容(兼容Codeup权限控制)。

下载和安装 Git LFS

  • 下载:

    • Linux Debian 和 RPM packages:https://packagecloud.io/github/git-lfs/install

    • Mac: brew install git-lfs

    • Windows:目前lfs已经集成在了Git for Windows中,直接下载和使用最新版本的Windows Git即可。

    • 直接下载二进制包:https://github.com/git-lfs/git-lfs/releases

    • 依据源码构建:https://github.com/git-lfs/git-lfs

  • 安装:

    • 如果你选择使用二进制包下载后安装,直接执行解压后的./install.sh脚本即可,这个脚本会做两个事情:

      • $PATH中安装Git LFS的二进制可执行文件

      • 执行git lfs install命令,让当前环境支持全局的LFS配置

让本地已有仓库支持Git LFS

  • 下载一个 Git LFS 仓库

当 clone 一个已经使用的Git LFS仓库时,git-lfs会自动替换仓库中相关hook,进而让 Git LFS 生效。

            # 样例仓库,如尝试,可替换为你的实际仓库地址 $ git clone git@codeup.aliyun.com:你的企业分组/dyrone.git Cloning into 'dyrone'... remote: Counting objects: 41, done. remote: Total 41 (delta 0), reused 0 (delta 0) Receiving objects: 100% (41/41), 2.98 MiB | five.01 MiB/due south, done. Filtering content: 100% (three/3), 5.01 MiB | three.83 MiB/due south, washed. # Filtering content表示正在将下载下来的LFS文件smudge为实际工作区的文件 $ cd dyrone $ tree .git/hooks .git/hooks ├── applypatch-msg.sample ├── commit-msg.sample ├── execute-commands.sample ├── fsmonitor-watchman.sample ├── post-checkout ├── post-commit ├── mail service-merge ├── post-update.sample ├── pre-applypatch.sample ├── pre-commit.sample ├── pre-merge-commit.sample ├── pre-push ├── pre-button.sample ├── pre-rebase.sample ├── pre-receive.sample ├── gear up-commit-msg.sample └── update.sample  0 directories, 17 files          

可以看到,例如pre-push等Git LFS需要用到的相关Hook已经被替换(从sample替换为实际钩子),进而支持Git Menstruation,对用户Git操作保持兼容和透明。

将历史仓库的大文件迁移至Git LFS

参见Git LFS使用注意事项 - 「将历史提交中的大文件迁移至Git LFS」章节。

注意

  1. 不建议一次性迁移仓库的全部对象变更为Git LFS,可能会存在超时等未知情况,给出的建议为:按照指定分支的方式迁移,参数--include-ref

  2. 强烈建议,在迁移Git LFS前在本地备份你的Git仓库,就算迁移失败也可以回退到最初仓库状态,万无一失

  3. 如果不是历史记录非常重要的仓库,建议建一个新仓库推送,比迁移更方便

  4. 更多git-lfs-drift的使用方式可以查看:git-lfs-migrate迁移工具说明文档

让本地新仓库支持 Git LFS

            # 初始化一个仓库 $ mkdir big-repo $ cd big-repo  $ git init Initialized empty Git repository in /Users/dyrone/big-repo/.git/ # 让仓库支持LFS $ git lfs install Updated pre-push claw. Git LFS initialized. # install成功后,仓库的pre-push钩子将被替换和生效          

第一次使用Git LFS

为了让大家可以尽快的上手 Git LFS,我将对一些通用的场景进行实际的演示和说明(环境为Linux/MacOS)。

在Codeup上创建一个新的Git空仓库

  • 第一: 我们先尝试在Codeup上创建一个Empty仓库

  • 第二: 我们尝试下载该仓库到本地

            # 尝试时,替换你实际的企业分组名称 $git clone https://codeup.aliyun.com/你的企业分组/git-lfs.git Cloning into 'git-lfs'... alert: Y'all appear to take cloned an empty repository. $cd git-lfs $tree .git/hooks/ .git/hooks/ ├── applypatch-msg.sample ├── commit-msg.sample ├── execute-commands.sample ├── mail service-receive.sample ├── post-update.sample ├── pre-applypatch.sample ├── pre-commit.sample ├── prepare-commit-msg.sample ├── pre-push.sample ├── pre-rebase.sample ├── pre-receive.sample └── update.sample  0 directories, 12 files # 此时Git LFS相关的Hook还未替换          

配置Git LFS

如果希望新的.bigfile后缀结尾的文件使用Git LFS存储功能,需要执行track命令进行追踪:

            $git lfs track "*.bigfile" Tracking "*.bigfile"          

注意

: 使用lfs track命令时,"*.bigfile"的双引号非常重要,否则将影响pattern的文件匹配功能关于更多的文件pattern信息可以查阅:

我们也可以执行git lfs track(不带任何参数),来查看当前tracking的Git LFS File Patterns:

            $git lfs runway Listing tracked patterns     *.bigfile (.gitattributes) Listing excluded patterns          

track实际上是修改了仓库中的.gitattributes文件,我们可以查看相关变动:

            $git add .gitattributes  $$git diff --cached  diff --git a/.gitattributes b/.gitattributes  new file manner 100644  index 0000000..c441ad2  --- /dev/zilch  +++ b/.gitattributes  @@ -0,0 +ane @@  +*.bigfile filter=lfs diff=lfs merge=lfs -text          

让Git LFS配置生效

为了让"*.bigfile"的LFS配置生效,我们需要将.gitattributes文件中的配置改动进行提交:

            $git commit -m "Add together \"*.bigfile\" LFS config " [master (root-commit) d052478] Add together "*.bigfile" LFS config  ane file changed, i insertion(+)  create manner 100644 .gitattributes $git log --oneline d052478 (HEAD -> master) Add "*.bigfile" LFS config          

新建一个大文件在Git仓库中进行测试

接下来,我们尝试在工作空间创造一个名为 dyrone.bigfile 的文件,大小为1GB:

            # mac环境可以使用mkfile命令替换dd命令  $dd if=/dev/zero of=dyrone.bigfile bs=1G count=1 one+0 records in 1+0 records out 1073741824 bytes (1.one GB) copied, 2.41392 s, 445 MB/due south $du -sh dyrone.bigfile  one.1G    dyrone.bigfile          

下一步,将 dyrone.bigfile 添加到暂存区:

            $git add dyrone.bigfile          

dyrone.bigfile 命中了我们刚才在.gitattributes中设置的"*.bigfile"的文件pattern,所以将做为Git LFS文件进行处理。

Git LFS并不会将完整的文件属性和内容进行计算写入INDEX(暂存区的实际文件),而是会生成一个Git LFS Pointer文件,该文件指向了真正的LFS存储对象名称。

我们可以通过执行git diff --cached命令查看仓库IndexHead之间的差异,也就是 dyrone.bigfile 对应的 Arrow 文件的内容:

            $git diff --buried diff --git a/dyrone.bigfile b/dyrone.bigfile new file mode 100644 index 0000000..9d7c19f --- /dev/zip +++ b/dyrone.bigfile @@ -0,0 +1,iii @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49bc20df15e412a64472421e13fe86ff1c5165e18b2afccf160d4dc19fe68a14 +size 1073741824          

Git LFS Pointer

我们来看一下 Pointer 文件内容所表达的含义:

  • version https://git-lfs.github.com/spec/v1 代表git-lfs协议的版本

    • version...v1: 代表当前git-lfs服务端遵从的协议版本

    • git-lfs.github.com: 此域名地址为git-lfs开源项目的官方地址

  • oid sha256:49bc20df15e412a64472421e13fe86ff1c5165e18b2afccf160d4dc19fe68a14

    • oid: 代表 Git LFS object id

    • sha256: 64位16进制,其代表真实文件的名称,名称通过sha256生成,唯一值

  • size: 代表文件实际大小,单位: byte

本地的Git LFS文件是如何存储的?

Arrow 文件被添加到暂存区的同时,真正的1GB的大文件 dyrone.bigfile 被存储在仓库的LFS缓存目录下,名称被修改为 Pointer文件 中所指向的oid字符串名称:

            $tree .git/lfs .git/lfs ├── objects │    └── 49 │         └── bc │             └── 49bc20df15e412a64472421e13fe86ff1c5165e18b2afccf160d4dc19fe68a14 └── tmp 4 directories, 1 file          

正如我们看到的这样,在本地仓库中,Git LFS就是按照这种方式来进行大文件实际存储,原本的 dyrone.bigfile 被表示成了两个文件, Pointer文件 的blob是对应Commit真正引用的对象,而实际LFS文件被缓存在.git/lfs目录。

而这一切用户其实都无需关注,因为工作区中的文件没有发生任何变化。

推送Git LFS提交到远端

接下来,我们尝试将第一个Git LFS相关的提交,也就是将 dyrone.bigfile 的变更推送到远端

            $git status On branch master Your branch is up-to-date with 'origin/master'.  Changes to be committed:   (use "git reset Head <file>..." to unstage)          new file:   dyrone.bigfile  $git commit -m "Add a actually big file" [master 8032589] Add a really large file  one file changed, iii insertions(+)  create style 100644 dyrone.bigfile          

其中,"1 file inverse, 3 insertions(+)" 表示 Pointer文件 已经commit,我们可以执行git show HEAD查看我们刚才的commit详情:

            $git prove Head commit 8032589f47a748171e84da94ce6440fe139e99f9 (Caput -> master) Author: dyroneteng <tenglong.tl@alibaba-inc.com> Date:   Tue Sep 15 17:25:58 2020 +0800      Add a really big file  diff --git a/dyrone.bigfile b/dyrone.bigfile new file manner 100644 index 0000000..9d7c19f --- /dev/goose egg +++ b/dyrone.bigfile @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49bc20df15e412a64472421e13fe86ff1c5165e18b2afccf160d4dc19fe68a14 +size 1073741824          

随后,我们将 commit 推送到远端 Codeup 仓库上:

            $git push button Uploading LFS objects:   0% (0/1), 3.nine MB | 0 B/s                                                                                                                                                                Uploading LFS objects:   0% (0/1), 79 MB | 30 MB/s                                                                                                                                                               Uploading LFS objects:   0% (0/ane), 207 MB | 50 MB/s                                                                                                                                                              Uploading LFS objects:   0% (0/1), 326 MB | 51 MB/s                                                                                                                                                              Uploading LFS objects:   0% (0/1), 534 MB | 56 MB/s                                                                                                                                                              Uploading LFS objects: 100% (ane/1), 1.one GB | 58 MB/s, washed.                                                                                                                                                       Counting objects: 3, done. Delta compression using up to 32 threads. Compressing objects: 100% (3/iii), done. Writing objects: 100% (3/3), 410 bytes | 410.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://codeup.aliyun.com/xxxxx/git-lfs.git    d052478..8032589  master -> master          

如果存在LFS文件需要上传,在推送过程中将会显示LFS上传进度,下面我们来简要解读下这一过程的标准输出:

  • 如果推送的文件中,包含Git LFS文件,那么实际上push将被分为两个部分

    • 第一部分: Git LFS oid文件上传

    • 第二部分: 当LFS oid文件上传结束后,继续使用git协议上传Pointer文件的相关对象

  • 第一部分 "Uploading LFS objects: 100% (i/1), 1.1 GB | 58 MB/s, done." , 会显示Git LFS oid文件上传过程中的进度信息,如总上传个数、当前上传、oid文件大小和上传速度等

  • 第二部分 "Writing objects: 100% (3/3), 410 bytes | 410.00 KiB/s, done." ,我们的例子中共三个对象:blob(1)、tree(1)、commit(1)

  • 两个部分,任一部分失败,则整个推送将失败

除了过程的标注输出增多的变化以外,也侧面体现了Git LFS是如何进行推送的: 在推送时,Git LFS文件被单独上传到LFS Server上,而Pointer文件保持不变推送到Git server上,我们可以观察仓库目录大小来验证这一点。

可以发现,本地仓库大小仅仅为188K(排除lfs缓存目录),这也基本是远端git仓库的大小,也达到了Git LFS瘦身仓库的目的。

            $du -sh --exclude=lfs .git  188K    .git  $du -sh .git 1.1G    .git          

Git LFS是如何工作的?

在上面的一些举例之后,相信大家会有对Git LFS有一点体感,那么我们从原理的角度解释下刚才的过程。

Git 场景

Git 1

首先,我们看下普通的场景, 普通场景不论是针对小型的代码文本文件、还是比较大型的图片文件,在相关变更从本地提交到远端仓库时,所有的相关文件资源

都会完整的存储在git server。就图片中的例子而言,如果图片文件越来越多,改动频次越来越大,仓库的体积将极速膨胀起来。

Git LFS场景

Git 2

接下来,我们来看下Git LFS的场景,如图片所示,我们可以针对jpg图片使用Git LFS的存储能力,在push过程中将其上传至大文件存储服务。同时,大文件对应的指针文件将连同其他的普通的代码文件推送到远端Git仓库中。

Git LFS处理流程介绍

Git 3

Git LFS 存在的一些限制

  • Window平台,单个文件不支持超过4Gissues 2434

  • Window用户必须保证已经安装Git Credential Director,否则可能导致操作被无限挂起,bug 1763

  • 不同于Gitlab硬编码的LFS下载token超时时间(30分钟),Codeup会根据将要下载的文件列表动态计算token超时时间,但是如果位于网络环境不好的环境,仍旧可能导致token超时的情况。如果需要根据需求调整,可以联系Codeup系统管理员处理。

cantrellperep1987.blogspot.com

Source: https://help.aliyun.com/document_detail/206889.html

0 Response to "Uploading Lfs Objects: 0% (0/1)"

Publicar un comentario

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel