部分克隆
-
随着 Git 仓库规模的增长,使用它们可能会变得很麻烦。因为:
-
必须下载的大量历史记录。
-
他们需要的大量磁盘空间。
-
部分克隆是一种性能优化,它“允许 Git 在没有完整仓库副本上工作。这项工作的目标是让 Git 更好地处理非常大的仓库”。
需要 Git 2.22.0 或更高版本。
按文件大小筛选
在 12.10 版本引入。
通常不鼓励在 Git 中存储大型二进制文件,因为之后每个克隆或获取更改的人都会下载添加的文件。如果在一个低速或者不可靠的网络环境中,这将非常慢。
部分克隆可以利用文件大小筛选器来排除麻烦的大文件,从而解决这一问题。当需要时,Git 会自行下载缺失的文件。
克隆仓库时,请使用 --filter=blob:limit=<size>
参数。例如要克隆存储库(不包括大于 1 MB的文件),请执行以下操作:
git clone --filter=blob:limit=1m git@gitlab.com:gitlab-com/www-gitlab-com.git
这将产生以下输出:
Cloning into 'www-gitlab-com'...
remote: Enumerating objects: 832467, done.
remote: Counting objects: 100% (832467/832467), done.
remote: Compressing objects: 100% (207226/207226), done.
remote: Total 832467 (delta 585563), reused 826624 (delta 580099), pack-reused 0
Receiving objects: 100% (832467/832467), 2.34 GiB | 5.05 MiB/s, done.
Resolving deltas: 100% (585563/585563), done.
remote: Enumerating objects: 146, done.
remote: Counting objects: 100% (146/146), done.
remote: Compressing objects: 100% (138/138), done.
remote: Total 146 (delta 8), reused 144 (delta 8), pack-reused 0
Receiving objects: 100% (146/146), 471.45 MiB | 4.60 MiB/s, done.
Resolving deltas: 100% (8/8), done.
Updating files: 100% (13008/13008), done.
Filtering content: 100% (3/3), 131.24 MiB | 4.65 MiB/s, done.
这个输出比较长是因为 Git 需要:
- 克隆仓库,但不包括大于 1 MB的文件。
- 下载默认分支所需的任何缺失的大文件
更改分支时,Git 可能需要下载更多丢失的文件。
按对象类型筛选
在 12.10 版本引入。
对于具有数百万个文件和较长历史的仓库,您可以使用 git sparse-checkout
缩小您的工作副本。
# Clone the repo excluding all files
$ git clone --filter=blob:none --sparse git@gitlab.com:gitlab-com/www-gitlab-com.git
Cloning into 'www-gitlab-com'...
remote: Enumerating objects: 678296, done.
remote: Counting objects: 100% (678296/678296), done.
remote: Compressing objects: 100% (165915/165915), done.
remote: Total 678296 (delta 472342), reused 673292 (delta 467476), pack-reused 0
Receiving objects: 100% (678296/678296), 81.06 MiB | 5.74 MiB/s, done.
Resolving deltas: 100% (472342/472342), done.
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 28 (delta 0), reused 12 (delta 0), pack-reused 0
Receiving objects: 100% (28/28), 140.29 KiB | 341.00 KiB/s, done.
Updating files: 100% (28/28), done.
$ cd www-gitlab-com
$ git sparse-checkout init --cone
$ git sparse-checkout add data
remote: Enumerating objects: 301, done.
remote: Counting objects: 100% (301/301), done.
remote: Compressing objects: 100% (292/292), done.
remote: Total 301 (delta 16), reused 102 (delta 9), pack-reused 0
Receiving objects: 100% (301/301), 1.15 MiB | 608.00 KiB/s, done.
Resolving deltas: 100% (16/16), done.
Updating files: 100% (302/302), done.
有关更多详细信息,请参阅的 Git 文档sparse-checkout
.
按路径筛选
可以使用 --filter=sparse:oid=<blob-ish>
过滤器规范来结合使用部分克隆和稀疏检出。此过滤模式使用类似于 .gitignore
文件指定克隆和获取时要包含的文件。
sparse
过滤器的部分克隆仍处于实验阶段。它可能会缓慢而显著地增加 Gitaly 克隆和获取时的资源利用率。使用过滤所有二进制文件并使用稀疏检出,因为 git sparse-checkout
简化这种类型的部分克隆的使用并克服其局限性。有关更多详细信息,请参阅的 Git 文档 rev list options
。
-
创建一个过滤器。例如,设想一个具有许多应用程序的单片存储库,每个存放在根目录的不同子目录中。创建一个文件
Shining app/.filterspec
:# Only the paths listed in the file will be downloaded when performing a # partial clone using `--filter=sparse:oid=shiny-app/.gitfilterspec` # Explicitly include filterspec needed to configure sparse checkout with # git config --local core.sparsecheckout true # git show master:snazzy-app/.gitfilterspec >> .git/info/sparse-checkout shiny-app/.gitfilterspec # Shiny App shiny-app/ # Dependencies shimmery-app/ shared-component-a/ shared-component-b/
-
按路径克隆和筛选。使用
--filter=sparse:oid
克隆命令的支持尚未与稀疏检出完全集成。# Clone the filtered set of objects using the filterspec stored on the # server. WARNING: this step may be very slow! git clone --sparse --filter=sparse:oid=master:shiny-app/.gitfilterspec <url> # Optional: observe there are missing objects that we have not fetched git rev-list --all --quiet --objects --missing=print | wc -l
Git 与 ‘bash’,’zsh’ 等的集成,以及自动显示 Git 状态信息通常运行 ‘Git fetch’,它获取整个存储库。您需要禁用或重新配置这些整合。
删除部分克隆过滤
带有部分克隆过滤的 Git 仓库可以删除过滤。删除筛选:
-
获取过滤器排除的所有内容,以确保存储库已完成。如果使用了
git sparse-checkout
,请使用git sparse-checkout disable
禁用它。请参看disable
文档了解更多信息。然后定期执行
fetch
以确保仓库完整。要检查是否有丢失的对象要获取,然后获取它们,尤其是在不使用git sparse-checkout
时,可以使用以下命令:# Show missing objects git rev-list --objects --all --missing=print | grep -e '^\?' # Show missing objects without a '?' character before them (needs GNU grep) git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+' # Fetch missing objects git fetch origin $(git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+') # Show number of missing objects git rev-list --objects --all --missing=print | grep -e '^\?' | wc -l
-
重新打包所有东西。例如,可以使用
git-repack -a -d
来完成。应在.git/objects/pack/
中只保留三个文件:-
一个
pack-<SHA1>.pack
文件。 -
它对应的
pack-<SHA1>.idx
文件。 -
一个
pack-<SHA1>.promisor
文件。
-
-
删除
.promisor
文件。上述步骤应该只剩下一个pack-<SHA1>.promisor
文件,该文件应为空并应删除。 -
删除部分克隆配置。部分克隆相关的配置变量应该从 Git 配置文件中删除。通常只需要删除以下配置:
-
remote.origin.promisor
。-
remote.origin.partialclonefilter
。