You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Git checkout耗时超2小时求助:自建GitLab分支切换异常排查

问题:Git切换分支耗时超2小时(含LFS对象的仓库)

我正在测试自建的GitLab实例,已经把本地Git仓库推送到了这个实例上。GitLab上的仓库占用14GB空间,包含多个LFS对象。

用命令$ git clone http://[ip:port]/repo/bavoo.git克隆主分支只需要1-2分钟,克隆日志如下:

$ git clone http://[ip:port]/repo/bavoo.git
Cloning into 'bavoo'...
remote: Enumerating objects: 773299, done.
remote: Total 773299 (delta 0), reused 0 (delta 0), pack-reused 773299
Receiving objects: 100% (773299/773299), 541.07 MiB | 2.44 MiB/s, done.
Resolving deltas: 100% (633879/633879), done.

但执行$ git checkout bavoo_test切换分支时耗时超过2小时(我中途终止了操作),完全不清楚Git在后台做什么。请问该怎么排查这个分支切换耗时过长的问题?

补充环境信息

  • macOS版本:10.15.3 (19D76)
  • Git版本:git version 2.24.1
  • Git LFS版本:git-lfs/2.8.0 (GitHub; darwin amd64; go 1.12.7)

编辑补充:git lfs env输出

Endpoint=http://[ip:port]/repo/bavoo.git/info/lfs (auth=basic)
LocalWorkingDir=/Users/daniel/Desktop/bavoo
LocalGitDir=/Users/daniel/Desktop/bavoo/.git
LocalGitStorageDir=/Users/daniel/Desktop/bavoo/.git
LocalMediaDir=/Users/daniel/Desktop/bavoo/.git/lfs/objects
LocalReferenceDirs=
TempDir=/Users/daniel/Desktop/bavoo/.git/lfs/tmp
ConcurrentTransfers=3
TusTransfers=false
BasicTransfersOnly=false
SkipDownloadErrors=false
FetchRecentAlways=false
FetchRecentRefsDays=7
FetchRecentCommitsDays=0
FetchRecentRefsIncludeRemotes=true
PruneOffsetDays=3
PruneVerifyRemoteAlways=false
PruneRemoteName=origin
LfsStorageDir=/Users/daniel/Desktop/bavoo/.git/lfs
AccessDownload=basic
AccessUpload=basic
DownloadTransfers=basic
UploadTransfers=basic
GIT_EXEC_PATH=/usr/local/Cellar/git/2.24.1/libexec/git-core

排查思路和解决方案

先别着急,咱们一步步拆解问题——克隆快但切换分支慢,大概率和LFS对象的拉取、Git的文件系统操作或者分支间的差异有关。下面是具体的排查步骤:

1. 先看Git切换时到底在做什么:开启调试日志

Git和Git LFS都有详细的调试日志,能帮你精准定位卡在哪一步。重新执行checkout时加上调试参数:

# 开启Git全局调试,看所有操作细节
GIT_TRACE=1 GIT_CURL_VERBOSE=1 git checkout bavoo_test
# 或者单独追踪LFS的操作日志
GIT_LFS_TRACE=1 git checkout bavoo_test

执行后会输出每一步的操作细节,比如是在拉取LFS对象、校验文件还是处理Git对象,你可以根据日志判断是卡在LFS下载阶段,还是Git本身的文件更新环节。

2. 检查分支间的LFS对象差异

切换分支时,Git LFS需要把工作区里的LFS指针替换成实际文件,如果bavoo_test分支和当前分支有大量不同的LFS对象,就会触发大量下载和文件替换操作。你可以先对比两个分支的LFS对象差异:

# 查看两个分支间差异的文件(筛选你仓库里的LFS后缀)
git diff --name-only --diff-filter=d HEAD bavoo_test | grep -E '\.(png|jpg|zip|你的LFS文件后缀)$'
# 统计差异的LFS对象数量
git diff HEAD bavoo_test | grep 'oid sha256:' | wc -l

如果差异数量特别多,那就是LFS下载的问题——可以检查你的GitLab LFS服务的带宽,或者本地和GitLab实例的网络连接速度。另外,你的Git LFS版本是2.8.0,比较老旧,建议升级到最新稳定版(比如v3.x+),新版本优化了并发下载和文件处理逻辑,能显著提升速度。

3. 检查本地磁盘性能

macOS 10.15的磁盘IO如果有问题(比如用的是机械硬盘、磁盘空间不足、APFS容器异常),也会导致大量文件替换时变慢。你可以:

  • 检查磁盘剩余空间:df -h /Users/daniel/Desktop/bavoo,确保有足够空间(至少是仓库大小的1.5倍)
  • diskutil verifyVolume /检查磁盘是否有错误(需要关闭SIP或在恢复模式下执行)
  • 临时把仓库移到SSD上测试,如果速度变快,说明就是磁盘性能拖了后腿

4. 优化Git配置提升效率

老版本的Git在处理大仓库时可能没开启一些关键优化,你可以试试开启这些配置:

# 开启文件系统缓存,减少文件状态检查时间
git config core.fscache true
# 调整LFS并发下载数(默认是3,你可以调到5-10试试)
git config lfs.concurrenttransfers 8
# 如果只需要分支里的部分文件,开启稀疏 checkout 减少文件处理量
git config core.sparseCheckout true

另外,你可以先执行git fetch origin bavoo_test拉取目标分支的所有对象,再执行checkout——有时候checkout时同时拉取对象会导致阻塞,分开操作可能更快。

5. 检查GitLab实例的LFS服务状态

虽然克隆正常,但切换分支时LFS的请求路径可能不同。你可以在GitLab后台查看LFS日志(一般路径是/var/log/gitlab/gitlab-rails/lfs.log),看是否有请求超时、权限错误或者带宽限制的情况。同时确认GitLab的LFS存储是否在高性能磁盘上,有没有IO瓶颈。

6. 临时跳过LFS验证做测试

如果怀疑是LFS导致的问题,可以临时关闭LFS自动下载,看看切换分支的速度:

git config lfs.skipdownload true
git checkout bavoo_test

如果这时候速度正常,那就坐实了是LFS的下载或文件处理问题,再回到步骤2和3针对性解决。

最后别忘了升级你的Git和Git LFS版本——2.24.1的Git是2019年的版本,很多大仓库的优化都是后续版本加上的,升级后大概率能解决一些隐性问题。


内容的提问来源于stack exchange,提问作者Daniel Stephens

火山引擎 最新活动