如何在Bitbucket Server本地仓库中移除历史中的大文件
问题背景
我们的自托管Bitbucket Server仓库被推送了大文件,删除文件后仍需清理历史以减小克隆体积。本地克隆用git-filter-repo成功完成清理,但直接在Bitbucket服务器仓库目录($BITBUCKET_HOME/shared/data/repositories/<id>)执行时触发报错:
Parsed 2203 commits
Required environment variable STASH_HOOK_ADDRESS is missing
Required environment variable STASH_HOOK_ADDRESS is missing
fatal: ref updates aborted by hook
fast-import: dumping crash report to fast_import_crash_22581
Error: fast-import failed; see above.
停止Bitbucket服务后重试仍报错,还导致服务无法启动,已通过快照回滚恢复。我们希望清理历史的同时保留仓库设置、PR历史,若无法兼顾则优先解决体积问题。
报错原因
Bitbucket Server的仓库目录内置了钩子脚本,这些钩子依赖Bitbucket运行时的环境变量(比如STASH_HOOK_ADDRESS),即使停止服务,钩子依然会拦截git-filter-repo的修改操作,导致执行失败。
方案一:保留仓库配置与PR历史的安全清理步骤
这是优先方案,无需删除原仓库,可完整保留所有设置、PR历史:
- 停止Bitbucket服务:确保服务完全停止,避免操作时出现冲突
- 备份原仓库目录:复制
$BITBUCKET_HOME/shared/data/repositories/<id>到安全位置,防止操作失误 - 临时禁用仓库钩子:进入目标仓库目录,重命名钩子目录:
mv hooks hooks_backup mv info/hooks info/hooks_backup - 执行git-filter-repo清理:在仓库目录下运行清理命令(替换为你的目标文件/路径):
git filter-repo --path bigfile.zip --invert-paths - 恢复钩子目录:清理完成后,把钩子目录恢复:
mv hooks_backup hooks mv info/hooks_backup info/hooks - 修复仓库权限:确保仓库目录的权限和原目录一致(通常是Bitbucket运行用户,比如
atlbitbucket):chown -R atlbitbucket:atlbitbucket $BITBUCKET_HOME/shared/data/repositories/<id> - 启动Bitbucket服务:启动后检查仓库状态,确认历史已清理且PR、配置正常
- 通知用户强制同步:所有仓库用户需要执行强制拉取,覆盖本地历史:
git fetch origin git reset --hard origin/<branch-name>
方案二:替代方案(放弃配置/PR历史,优先解决体积)
如果方案一执行遇到问题,可采用镜像克隆后重建仓库的方式:
- 镜像克隆原仓库:
git clone --mirror <原仓库URL> - 进入镜像仓库执行清理:
cd <仓库名>.git git filter-repo --path bigfile.zip --invert-paths - 删除Bitbucket上的原仓库:在Bitbucket后台删除目标仓库(务必提前备份)
- 创建同名空仓库:在Bitbucket后台创建和原仓库同名的空仓库,配置好必要权限
- 推送清理后的镜像到新仓库:
git push --mirror <新仓库URL> - 通知用户重新克隆:所有用户需要删除本地克隆,重新克隆新仓库
内容的提问来源于stack exchange,提问作者Adam

