断电 Gitea 导致分支error: cannot lock ref 损坏修复解决措施
今天上午公司忽然断电了,除了生产机器上了 UPS,其他服务器均重启了,启动起来之后发现私服 gitea 某个仓库的某个分支无法推送,界面上能看到,点击后显示 404,断电前刚好有成员提交了代码,尝试本地强制推送直接被拒绝,初步推断是断电数据在内存来不及写导致的。
首先尝试了在 gitea 后台界面执行了健康检查仓库,修复等一些系列操作没有作用,因为部署的是很老的版本了,并且还是 windows 上面。
本地尝试推送到远程提示报错如下:
remote: warning: ignoring broken ref refs/heads/test
remote: error: cannot lock ref 'refs/heads/test': unable to resolve reference 'refs/heads/test': reference broken 然后让ds分析了一波让运维在服务器上执行查看是否有损坏。
git fsck --full根据仓库大小等待时间有所不同,此项工作运维操作的,后面会告知哪些分支损坏受到了影响,可以找到最新一条未损坏的 commitId 进行恢复。
由于我们本地有最新的完整 test 分支,直接执行了删除损坏的提交和 test 分支,本地直接重新推代码上去最终修复。
忽然断电确实容易出现各种问题,只要本地有备份就还好,防范于未然,数据无价。
还有 gitea 官方有 gitea doctor 命令进行工具,也可以先尝试这个能不能搞定。
下面步骤可参考:
第一步:诊断损坏范围
进入 Gitea 存放该仓库的裸库目录(通常路径形如 gitea-repositories/<用户或组织>/<仓库名>.git),执行:
bash
git fsck --full
观察输出中与 refs/heads/test 相关的错误。同时直接查看损坏的文件内容:
bash
cat refs/heads/test
如果看到的是空、null 字节或全零(如 0000000000000000000000000000000000000000),即可确认该引用文件已损坏。
第二步:尝试安全删除损坏引用(推荐首选)
Git 提供了专门用于删除损坏引用的底层命令,它能同时处理松散引用和 packed-refs 中的条目:
bash
git update-ref -d refs/heads/test
即使引用已损坏,git update-ref -d 通常也能正常工作,比直接手动删除文件更安全。如果该命令成功执行且无报错,可直接跳至第四步。
第三步:手动清理残留文件(若上一步失败)
如果 git update-ref -d 因引用损坏过于严重而拒绝操作,则需要手动删除相关文件,并检查是否有打包引用和日志残留:
bash
# 删除损坏的松散引用文件
rm -f refs/heads/test
# 检查 packed-refs 中是否还有残留条目
grep "refs/heads/test" packed-refs
# 如有残留,编辑 packed-refs 删除对应行
# 删除对应的 reflog(日志)文件
rm -f logs/refs/heads/test
Gitea 的 Issue 中也有类似案例,断电后需要同时清理 refs/heads/ 下的损坏文件、logs/ 下的对应日志,以及 Gitea 数据库中可能残留的引用记录。如果后续 Gitea 页面仍显示异常,可检查数据库 repository 或 branch 相关表中是否有指向 test 的脏数据。 The End
商业转载请联系作者获得授权,非商业转载请注明本文出处及文章链接