git lfs migrate 有什么作用?

What does git lfs migrate do?

我认为 git lfs migrate 重写了 repo 的历史,以便将指定的大文件保存在 LFS 中。这意味着 repo 应该变小,因为它不直接包含大文件的所有版本。然而,当我 运行

git lfs migrate import --include="test-data/**" --include-ref=refs/heads/master

test-data/ 目录中的所有文件都替换为如下所示的文件:

version https://git-lfs.github.com/spec/v1
oid sha256:5853b5a2a95eaca53865df996aee1d911866f754e6089c2fe68875459f44dc55
size 19993296

并且 .git 文件夹变得两倍大(400MB 到 800MB)。我很迷惑。 git lfs migrate doing 是什么?

编辑:我做了 clean after migration

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

在运行宁du之前。之后,大部分 space 被这些文件夹使用:

414M .git/objects 398M .git/lfs

I thought that git lfs migrate rewrote the history of a repo so that specified large files were kept in LFS.

完全正确。

This means that the repo should get smaller, because it doesn't directly contain all versions of large files.

不完全正确。 git lfs 的承诺并不是你的 repo 会更小,而是当你克隆时,你不必下载所有 git 对象,因此克隆会更小更快。因为对于 git-lfs 管理的文件,在 git checkout.

期间只会下载应该出现在您的工作目录中的文件

All of the files in the test-data/ directory are replaced with files that look like this:

这就是 git-lfs 的工作原理。它不是在存储库中提交文件,而是提交一个包含对象 ID 的 this "pointer" 文件。该文件的内容存储在 .git/lfs/objects 文件夹中。这些对象将在您 git push.

时上传到服务器

And the .git folder becomes twice as large (400MB to 800MB). I am confused.

因为 git lfs 管理的所有文件都存储在这个文件夹中,所以它可能会变得很大。 我还认为它会使存储库的大小增加一倍,因为目前对象存储了两次。在 .git/objects 直到你放弃旧的历史(通过 purging the reflog and doing a git gc。但是一旦你确定你的 lfs 迁移成功就这样做)并且在 .git/lfs/objects 因为你做了 git lfs转换。

我认为(但我不确定).git/lfs/objects 用作缓存文件夹,因此一旦您推送了所有新的历史记录并且它上传了由 lfs 管理的文件,您可以删除它以减少您的存储库的大小。 但如果我是你,我不会那样做!

要查看 git lfs 在您的本地存储库上的真实效果,一旦您 --force 推送了新的历史记录(并且旧的历史记录不再存在于远程存储库中),我将做一个新的克隆。现在,您的本地存储库应该更小了。

但是以后每次下载这些文件的新版本时,文件夹 .git/lfs/objects 仍会增长(但它应该总是比不使用 git lfs 时小) .

我希望你能更好地理解它是如何工作的...

PS:

All of the files in the test-data/ directory are replaced with files that look like this:

希望你说的有一部分是假的。您在 test-data/ 中的文件仍然包含好的内容,但您报告的是 git 命令向您显示的... 你能证实吗?或者您有问题...这可以通过未安装 git lfs 来解释。

唯一的问题是二进制文件的原始 git 对象仍在 .git 文件夹中,因为您没有对它们进行垃圾回收。

你应该按照 git lfs migration tutorial 解释:

The above successfully converts pre-existing git objects to lfs objects. However, the regular objects still persist in the .git directory. These will be cleaned up eventually by git, but to clean them up right away, run:

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

在 运行 之后你的 .git 应该是相同的大小,但是如果你进入它你应该看到 objects 现在应该比之前小得多迁移,lfs 保留其余部分。

更好的消息是,现在当其他 developers/applications 克隆存储库时,他们只需下载 objects 目录,然后 他们检查的"large-files",而不是整个历史记录。

奇怪的文件看起来像 git lfs 指针并替换了工作副本中的文件(在您的情况下是 test-data/ 中的文件)如果您迁移

  • git lfs track 命令之后。此命令更改工作副本上所有跟踪的“大文件”。
  • 没有提交通过 git lfs track 命令对您的工作副本所做的所有更改。 如果您遵循教程并只是提交 .gitattributes 但不是所有“大文件”,则可能会发生这种情况。