我需要 Git LFS 用于本地回购吗?

Do I need Git LFS for local repos?

我创建了一个 Git 存储库,专门存储在本地,我问自己,我是否真的需要 Git LFS 来处理二进制文件?据我所知,.gitattributes 已正确配置为:

*.psd binary

是的,文件位于 .git/objects/...,但它们是压缩的并且占用的空间不大 space。综上所述,如果我从不 push/pull from/to 远程仓库,那么在本地仓库中使用 Git LFS 有什么好处?

谢谢!

虽然 Git 提交是存储库内容的完整“快照”,但它实际上并没有再次存储文件。 Git 将文件内容存储为由内容校验和标识的“blob 对象”;只有内容、文件名和权限存储在树对象中。如果您提交对文件的更改,Git 将整个文件再次(压缩)存储为一个新的 blob;任何未更改的文件都将重用现有的 blob。如果您有两个内容相同的文件,它们将共享同一个 blob。

如果没有 git-lfs,每次您提交对二进制文件的更改时,整个文件(压缩的)都必须再次存储在一个新的 blob 中。由于 Git 存储库是项目的完整历史,一段时间后这可能会占用大量磁盘 space。如果 space 很紧,那对你来说可能很重要。

幸运的是,您不必现在就做出这个决定。如果存储库变得太大,您可以随时 retroactively apply git-lfs later using the BFG Repo Cleaner.

添加@Schwern 已经提供的出色答案并解决 OP 的评论。

这是来自 atlassian 的 link LFS 文档的 link - 支持此扩展的公司。

想法是二进制文件是从“远程”存储库懒惰地下载的,即在结帐过程中而不是在克隆或获取过程中。

从技术上讲 git lfs 存储“懒惰地”评估的指向二进制文件的指针。

这很有意义,因为 git 有一个“承诺”,能够在每次提交后为您提供访问 code-base 状态的权限,因此出现以下情况可能:

  1. 提交 A:添加了大型二进制文件 a.bin(可以说 a.bin 在版本 1 中)
  2. 推送更改
  3. 提交 B:对二进制文件进行了更改 a.bin(a.bin 现在是版本 2)
  4. 推送更改
  5. 现在检查提交 A 的 SHA1 - git 必须在版本 1 中为您提供 a.bin。

即使您决定删除 a.bin 并提交它,这也是正确的,在“提交 A”之后应该仍然有可能访问 file-system 状态。 因此,如果您明确不需要,至少在本地没有必要存储版本 1。

另外注意,直接解决问题并澄清:是的,您必须在本地启用 git lfs 支持,但此外,您还必须在远程仓库上启用 git lfs 支持(我用 bit bucket 做过一次,我相信它的竞争对手也支持)。

这取决于您的工作流程和您可以使用的设施。

Git 将文件版本存储为 blob。这些 blob 是差异压缩的,因此只存储差异。因此,文件大小只会略有增加。

如果版本化文件是二进制文件或单个更改会重组整个文件的文件,情况就不同了。在这种情况下,Git 存储每个文件的副本,从而使存储库快速增长。

Git 和 Git-LFS blob 大小的比较

Git 在压缩大文件方面做得很好。我发现大文件的压缩效果非常好(大小的总变化):

type change file as git blob after git gc as git-lfs blob
Vectorworks (.vwx) added geometry 28,8 MB +26,5 MB +1,8 MB +26,5 MB
GeoPackage (.gpkg) added geometry 16,9 MB +3,7 MB +3,5 MB +16,9 MB
Affinity Photo (.afphoto) toggled layers 85,8 MB +85,6 MB +0,8 MB +85,6 MB
FormZ (.fmz) added geometry 66,3 MB +66,3 MB +66,3 MB +66,3 MB
Photoshop (.psd) toggled layers 25,8 MB +15,8 MB +15,4 MB +25,8 MB
Movie (mp4) trimmed 13,1 MB +13,2 MB +0 MB +13,1 MB
delete a file -13,1 MB +0 MB +0 MB +0 MB

如果你没有可以推送的遥控器,最好不要使用Git-LFS,因为Git-LFS版本化文件似乎根本没有添加额外的压缩(见上文)。

这里学到的另一个重要教训是 Git 的差异压缩方法不适用于像 .fmz 这样的真实二进制文件。这些将是置于 Git-LFS 版本控制下的最佳候选者。

对于其他看似非文本但其结构类似于文本(.vwx 或 .afphoto)的文件类型,diff 方法表现良好。在单个用户场景中,整体存储库大小而不是提交速度很重要,我不会将它们放在 Git-LFS 版本控制下,因为 Git blob 大小明显小于 LFS blob,因此在本地和远程保存 space。

Git-LFS 的好处

Git-LFS 通过将旧版本的大型二进制文件存储在存储库(远程)之外的某个地方并替换它来解决此问题通过一个指针文件。如果需要旧版本,则客户端从远程拉取它。因此,如果设计者从远程拉取最新状态,他只会下载最新状态和指针文件。

因此,只有当您可以访问位于支持 LFS 的服务器上的远程服务器时,才能促进 Git-LFS。如果没有服务器可以将 blob 推送到,那么 LFS 跟踪的 blob 将保留在本地存储库中,因此不会利用减少本地存储消耗的优势。

通常,远程是支持 LFS 的 git 提供程序,这对于某些项目来说可能太贵了。但是,也有一些解决方案可以在本地托管 Git-LFS 远程。

如何将 Git-LFS 集成到本地存储库

在本地,Git-LFS 只允许通过 HTTPs 传输数据。因此,您需要一个单独的 Git-LFS 服务器来存储大文件。但是,有''no official server'' implementation for local hosting. But there are some unofficial ways like Git-LFS Folderstore 可以做到这一点。

Git-LFS 文件夹存储 提供了一种在本地管理 Git-LFS 远程文件夹的方法。它可以在本地机器和网络驱动器上运行。如果您在 Mac OS X 上,那么您可以通过将 lfs-folderstore 可执行文件 lfs-folderstore 复制到 /usr/local/bin 然后进行设置:

# Creating a remote repository on a volume (attached drive or NAS)
cd path/to/remote
mkdir origin

# create a bare git repository in origin
cd origin
git init origin --bare

# Add remote to local repository
cd path/to/local/repository
git remote add origin <path/to/remote/origin>

# Enable Git-LFS in local repository
git lfs install

# Track filetype psd
git lfs track "*.psd"

# Configure lfs of the local repository
git config --add lfs.customtransfer.lfs-folder.path lfs-folderstore
git config --add lfs.standalonetransferagent lfs-folder
git config --add lfs.customtransfer.lfs-folder.args "Volumes/path/to/remote/origin"

# Commit changes
git commit -am "commit message"

# Push media to remote
`git push origin master`

如果您的远程路径包含 spaces,请使用 "'

如何清理本地存储库

您可以通过调用 Git 垃圾收集器 git gc 来压缩 git 存储库的大小。它不会碰到 Git-LFS blobs tough。

Git-LFS 只会从本地存储库中删除 blob .git/lfs/objects/ 如果它们已被推送到远程并且包含 blob 的提交早于最近(3 天)。如果您想手动执行以下命令:

# remove lfs duplicates
# https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-dedup.1.ronn
git lfs dedup

# clean old local lfs files (>3 days of commit)
# https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-prune.1.ronn
git lfs prune