IT相关 · 2026年8月18日

Gitea 每日健康检查报 fork/exec /usr/bin/git 错误的排查与修复

2026-08-18 · IT 运维 · Gitea 1.27.1

问题现象

每天 Gitea 后台都会弹出这条告警:

Failed to health check repository jiangdefu/wordpress:
fork/exec /usr/bin/git: no such file or directory

乍一看像是容器里 git 二进制缺失,第一反应是去查 git 装没装、PATH 对不对。但排查后发现,报错是个幌子,真正的根因完全不同。

排查过程

第一步:确认 git 本身没问题

进容器检查 git:

  • Git 路径:/usr/bin/git
  • 版本:git version 2.54.0
  • 文件存在且可执行
  • 容器 PATH 包含 /usr/bin

git 完全正常。说明报错不是 git 二进制缺失。

第二步:用 API 侧定位(不登服务器)

Gitea 的 SSH 端口(x.x.x.x:2222)认证通过后也不提供 shell(Gitea 标准行为,SSH 只走 git 协议),所以容器内命令得靠人执行。好在很多判断用 API 就能做:

检查项 正常仓库 问题仓库
GET /repos/{o}/{r} empty=false empty=true, size=23(空壳)
GET /repos/{o}/{r}/git/refs 200 500(关键信号)
GET /repos/{o}/{r}/commits 正常 409「Git Repository is empty」

git/refs 返回 500 是关键信号——对照正常仓库返回 200,说明这个仓库的 git 数据层有问题。再列出全部仓库,发现只有这一个坏,其他仓库全部正常 → 排除 volume 挂载、部署路径等全局问题,锁定是这个仓库自身的目录缺失。

第三步:容器内坐实

在容器内执行两条命令,结论一目了然:

$ ls -la /data/git/repositories/jiangdefu/wordpress.git/
ls: /data/git/repositories/jiangdefu/wordpress.git: No such file or directory

$ git -C /data/git/repositories/jiangdefu/wordpress.git status
fatal: cannot change to '/data/git/repositories/jiangdefu/wordpress.git': No such file or directory

坐实:数据库里有这个仓库的记录,但磁盘上的 .git 目录根本不存在。 Gitea 对该仓库执行 git 子进程时找不到目录,于是报 fork/exec /usr/bin/git(错误信息里提到的 git 其实是 Gitea 想调用的工具,不是 git 真丢了)。

根因

这是一个迁移遗留的空壳仓库:

  • 创建时间(2026-08-12)正好落在仓库迁移窗口
  • 从创建起就是空的(empty=true,无分支无 commit,size=23 字节)
  • 真正的代码都迁进了新仓库 yoer/jiangdefu
  • 迁移时先建了这个空壳,后来忘了清理,而它的磁盘目录又没真正生成

修复

确认仓库完全为空(无分支、无 commit)后,直接通过 API 删除,零数据损失:

curl -u <user:pass> -X DELETE "https://gitea.xxx.com/api/v1/repos/jiangdefu/wordpress"
# → HTTP 204

验证:

  • 删除后 GET 该仓库 → HTTP 404 not found
  • 重新列出仓库 → 已不在列表
  • 其他仓库(含真正的 yoer/jiangdefu)完好无损

删除后,每日健康检查不再对这个不存在的仓库执行 git 子进程,报错源消除。

复盘 & 避坑

  1. 报错信息可能误导:fork/exec /usr/bin/git: no such file or directory 看着像 git 丢了,实际是 Gitea 找不到仓库目录。先别急着装 git。
  2. git/refs 返回 500 是好信号:用正常仓库做对照(200 vs 500),能快速区分是仓库自身问题还是全局问题。
  3. 单仓库报错 = 仓库自身问题:如果只有某一个仓库报错、其他都正常,基本排除 volume 挂载、部署路径、CDN 等环境因素,直接查这个仓库的磁盘目录。
  4. 空壳仓库迁移后要清理:改名 / 迁移 / 建子仓库时容易留下”数据库有记录、磁盘无目录”的残骸,迁移完务必复查一次。
  5. Gitea SSH 端口 ≠ shell:认证通过也不提供交互式 shell,容器内命令要么人执行,要么走容器 exec。

排查对象:Gitea 1.27.1,遗留空仓库 jiangdefu/wordpress。