0%

Git-LFS 使用和迁移

一次 Git-LFS 的迁移记录。

网上说了一大堆 Git-LFS 的作用和好处,我觉得都是把官方文档零零碎碎翻译一下。在我看来,对于普通开发者而言,Git-LFS 的作用很简单,就是让你 pull 代码的时候不用每次都把一大堆大文件一块 pull 下来,而且我个人使用体验还有切换分支之类的操作都变快了。

Git-LFS 安装

sudo apt/yum install git-lfs 即可,然后 git lfs install

Git-LFS 使用

追踪和推送

在一个已经初始化后的 Git 仓库中使用 Git-LFS 来追踪大文件,命令如下:

git lfs track <filepattern>

track 会产生一个 .gitattributes 文件,和 .gitignore 类似,也是 git 自己的文件,用于描述 Git-LFS 的文件名匹配模板。一般而言,文件中的每一行类似这种:

*.pbtxt filter=lfs diff=lfs merge=lfs -text

-text 就是表示这个文件不是文本文件。其余的就是告诉 Git 在处理 filter、diff、merge 时将 pbtxt 文件通过 LFS 的方式处理,打开 .gitconfig 可以看到相关命令的替换。

用 Git-LFS track 追踪档案之后,就可以添加、提交和推送到远端目录上,你在首次推上去的时候,会要一些时间将大型档案传输到远端。这里是很多教程很模糊的地方,事实上,Git-LFS 并不是什么魔法,仍然要将文件同步到远端。有的 git 仓库页面会显示 Git-LFS 的标记,gitlab 就可以,好评,tx 自用的工蜂,呵呵。

拉取

其他用户使用这个仓库的时候,使用 git clone 会拉取普通的文件,但是 LFS 追踪的文件不会被拉下来。如果这些文件本地没有,则需要使用 git lfs pull 从远程仓库拉取。

现在的 git 貌似是直接能够拉取所有文件,包括 lfs 文件,如果不想拉取 lfs 文件,可以使用 GIT_LFS_SKIP_SMUDGE=1 git clone

总结来看,Git-LFS 唯一的目的就是于其他 clone 使用者来说,他们若不需要异动大型档案,就不需要进行git lfs pull 的动作,于是那个原本的大型档案会变成一个130 bytes 的文字档。即使他clone 整个master,也是很小的储存库。Git-LFS 的使用无关档案大小,唯一的重点在于某些档案你想放在 master 内,或是说必须放在master 内,而其他人又不需要同步这个档案的话,就可以使用 Git-LFS 的方式来管理此档案。

Git-LFS 迁移

这个才是比较实用的,因为很多仓库是用着用着才想着用 lfs…

对于一个已经用了一段时间的 Git 仓库,直接执行 git lfs migrate import --include="*.bin" --everything ,可以将所有本地分支上的匹配文件的提交历史版本都转换为 lfs,这个时候无论你切换到哪个分支,都会出现 .gitattributes 文件,且内容都是一样的。

如果只想更新某个分支的话,可以使用 git lfs migrate import --include="*.bin" --include-ref=refs/heads/master

可以通过 git lfs ls-files 查看哪些文件被转换成 lfs 了。

切换成功后,就需要把切换之后的本地分支提交到远程仓库了,需要手动 push 更新远程仓库中的各个分支。这里有个极大需要注意的地方,就是转换会更改所有提交的 hash,因此 push 的时候需要使用 force 选项,而当其他人员再次使用 pull 去远程拉取的时候会失败。这里当然可以使用 pull --allow-unrelated-histories 来把远程仓库被修改的历史与本地仓库历史做合并,但是最好是重新拉取

切换成功后,git 仓库的大小可能并没有变化,主要是之前的提交还在,因此需要做一些清理工作:

1
2
git reflog expire --expire-unreachable=now --all
git gc --prune=now

但是,如果不是历史记录非常重要的仓库,建议不要像上述这么做,而是重新建立一个新的仓库。个人经验,迁移可以使用,但并没那么美好

附一个迁移相关的基础教程

Git-LFS 需要多次输入密码的问题

解决 Git-LFS 使用导致 push 需要输入多次用户名和密码。

Linux:

1
2
3
4
5
# Set git to use the credential memory cache
git config --global credential.helper cache

# Set the cache to timeout after 1 hour (setting is in seconds)
git config --global credential.helper 'cache --timeout=3600'

其他平台可以参考:Caching your GitHub password in Git