Git fetch报upload-pack:not our ref错误的排查与解决咨询
Git子模块Fetch报错:
upload-pack: not our ref 排查与解决 一、定位提交引用的来源
提交19b662dd是子模块PR squash合并后被移除的悬空提交,本地残留的引用导致fetch报错,按以下顺序排查:
- 子模块reflog记录:Git会保留分支操作历史,哪怕分支已移动,reflog可能留存引用
git -C <子模块路径> reflog show --all | grep 19b662dd - 子模块stash记录:未清理的stash可能包含该提交
git -C <子模块路径> stash list -p | grep 19b662dd - 本地标签/隐藏分支:检查未推送的标签、孤儿分支或临时分支
git -C <子模块路径> for-each-ref --format='%(objectname) %(refname)' | grep 19b662dd - 主仓库的子模块引用:主仓库的旧提交可能曾引用该子模块提交
git log --all --pretty=format:'%H' | xargs -I {} git ls-tree {} <子模块路径> | grep 19b662dd - Git底层引用文件:直接扫描子模块的packed-refs和loose refs文件
grep 19b662dd <子模块路径>/.git/packed-refs find <子模块路径>/.git/refs -type f -exec grep 19b662dd {} \;
二、本地Git数据库扫描方法
用以下命令全面扫描本地Git库,确认提交的关联对象:
- 扫描所有可访问对象,找关联的引用:
git -C <子模块路径> rev-list --all --objects | grep 19b662dd - 检查悬空对象及引用链:
git -C <子模块路径> fsck --full --no-reflog | grep 19b662dd - 查看提交详情,确认父提交、作者信息等:
git -C <子模块路径> cat-file -p 19b662dd
三、排查与解决步骤
- 清理本地引用
- 若来自reflog:清理过期reflog并回收垃圾对象
git -C <子模块路径> reflog expire --expire=now --all git -C <子模块路径> gc --prune=now - 若来自stash:删除对应stash记录
git -C <子模块路径> stash drop <stash编号> - 若来自本地标签/分支:直接删除
git -C <子模块路径> tag -d <关联标签名> git -C <子模块路径> branch -D <关联分支名>
- 若来自reflog:清理过期reflog并回收垃圾对象
- 主仓库与子模块全局清理
- 清理所有子模块的垃圾对象:
git submodule foreach --recursive git gc --prune=now - 检查主仓库是否有旧分支引用该子模块提交,若无需保留则删除对应分支
- 清理所有子模块的垃圾对象:
- 流水线环境修复
- 临时规避:先更新子模块再执行主仓库fetch
git submodule update --init --remote git fetch --tags --all --prune - 彻底修复:在流水线环境重新克隆仓库,避免旧缓存残留
- 临时规避:先更新子模块再执行主仓库fetch
- 验证
本地执行git fetch --tags --all --prune --dry-run多次,确认无报错后触发流水线测试
内容的提问来源于stack exchange,提问作者Andreas Maier
相关产品推荐
相关产品推荐

