加速 Git:必备性能优化技巧
通过减少克隆成本、合理使用 Git LFS、清理过时引用、忽略生成文件以及应用稀疏检出,来加速 Git。
加速 Git:必备性能优化技巧
Git 运行缓慢通常有具体原因:历史记录过多、未跟踪文件过多、大型二进制对象、昂贵的文件系统扫描或网络延迟。在责怪 Git 本身之前,请检查哪个操作缓慢以及它试图读取或下载什么。
Git 性能优化在将修复措施与症状匹配时效果最佳。缓慢的 CI 克隆与大型工作树中缓慢的 git status 需要不同的解决方案。
理解 Git 性能缓慢的原因
从常见原因开始:
- 包含大量文件和引用的长历史记录。
- 直接提交到 Git 的大型二进制文件。
- 工作树中未忽略的构建输出、依赖文件夹或日志。
- 大量过时的远程跟踪分支和标签。
- 与远程仓库之间的慢速网络链接。
- 缺少较新维护和稀疏检出改进的旧 Git 版本。
有目的地运行缓慢的命令。如果 git clone 缓慢,请检查历史记录大小和网络传输。如果 git status 缓慢,请检查工作树大小、忽略的文件和文件系统行为。如果 git fetch 缓慢,请检查远程引用、标签和更改的对象。
减少克隆和获取成本
对于 CI、部署作业和只读检查,您通常不需要完整的历史记录。
使用浅克隆:
git clone --depth <number> <repository_url>
例如,仅克隆最后 10 次提交:
git clone --depth 10 https://github.com/example/repo.git
对于仅构建当前提交的 CI 作业,--depth 1 通常就足够了。对于开发人员工作,完整克隆通常更不容易出错,因为诸如深层 git log、检出旧标签以及某些变基等命令需要更多历史记录。
如果您已有浅克隆并需要更多历史记录,请加深它:
git fetch --deepen=50 origin
或者将其转换为完整克隆:
git fetch --unshallow origin
对于部分数据需求,较新的 Git 版本还支持部分克隆过滤器,例如 --filter=blob:none,但仅在您的 Git 主机和工作流良好支持它们时使用:
git clone --filter=blob:none https://github.com/example/large-repo.git
将大型文件排除在常规 Git 历史记录之外
大型二进制文件是使 Git 变慢的最快方式之一。图像、视频、归档文件、设计文件和模型文件通常无法很好地压缩或差异比较。
对于真正属于仓库的大型资产,请使用 Git LFS:
git lfs install
git lfs track "*.psd"
git lfs track "assets/*.mp4"
git add .gitattributes
git commit -m "使用 Git LFS 跟踪大型资产"
Git LFS 会影响跟踪规则生效后的未来提交。如果有人已经将大型文件提交到常规 Git 历史记录中,仅从当前树中删除它们是不够的。您可能需要使用诸如 git lfs migrate import 或 git filter-repo 等工具进行协调的历史重写。
对于生成的构建产物,更好的答案通常不是 LFS。不要提交它们。而是将它们添加到 .gitignore 中:
node_modules/
dist/
coverage/
*.log
清理本地引用和对象
过时的远程跟踪分支会增加混乱,并可能减慢列出或检查引用的命令。在获取时修剪它们:
git fetch --prune
删除已合并且不再需要的本地分支:
git branch --merged
git branch -d old-feature-branch
让 Git 运行维护:
git maintenance run
在较旧的工作流中,git gc 仍然有用:
git gc
除非您知道需要它们的原因,否则避免使用激进的清理命令。例如,过期 reflog 可能会使从错误重置中恢复变得更加困难。
降低 git status 的成本
git status 必须检查工作树。如果您的项目目录包含数千个生成或依赖文件,状态可能会变得嘈杂且缓慢。
使用 .gitignore 来忽略 Git 不应考虑的文件。如果文件已被跟踪,.gitignore 不会阻止 Git 跟踪它;您必须首先从索引中删除它:
git rm --cached path/to/generated-file
对于非常大的仓库,如果您只需要树的一部分,稀疏检出可能会有所帮助:
git sparse-checkout init --cone
git sparse-checkout set services/api docs
这仅将选定的路径保留在您的工作树中。它在单体仓库中很有用,但您的团队应记录预期的稀疏路径,以便开发人员不会错过他们需要的文件。
分离获取与集成
git pull 会获取更改,然后根据配置通过合并或变基进行集成。当仓库很大或分支已分叉时,通常先获取会更清晰:
git fetch origin
git log --oneline HEAD..origin/main
git merge origin/main
这本身不会减少网络传输量。它让您在更改工作分支之前拥有控制权。
实用要点
对短期作业使用浅克隆,对大型资产使用 Git LFS,对生成文件使用 .gitignore,对过时引用进行修剪,对仅需子集的大型树使用稀疏检出。保持 Git 更新,但不要将诸如 git fsck 之类的完整性工具用作性能修复,除非您怀疑仓库损坏。
当 Git 感觉缓慢时,记下确切的命令以及时间花费在哪里:网络传输、对象处理或工作树扫描。这一个细节通常指向正确的优化方向。