simplegit
一个自包含(self-contained)的 git 宿主服务。提供 git smart-HTTP、SSH、Connect-RPC 三种访问入口,以及一套对仓库做读写的 RPC。
设计哲学
simplegit 的核心原则只有一条:
simplegit 拥有自己的数据库,这个数据库只跟自己通,不与任何外部服务共享或同步。
由此推出三点:
- 不依赖外部元数据服务。 simplegit 不连别人的库、不读别人的表。平台(console 等)不再同步持有 simplegit 的元数据,也不在请求路径上替 simplegit 做鉴权。
- 外部不能直接写 simplegit 的库。 元数据的唯一入口是 simplegit 自己的 API,或直接操作数据库本身。
- 可以独立运行。 没有平台、没有 console、没有消息队列,simplegit 依然是一个完整可用的 git 服务器。
设计目的:把 simplegit 和平台彻底解耦。simplegit 对自己的数据是唯一权威(single source of truth),既能作为平台的一员协同运作,也能单机裸跑。
三大部件
1. 私有数据库(Private DB)
simplegit 自带的元数据库,存放仓库注册表、用户、凭证(PAT)、权限等。
- 只对 simplegit 自身可见,不对外暴露连接。
- 不接受来自外部服务的写入。
- 变更途径只有两条:
- 走 simplegit 自己的 API(受其鉴权保护);
- 直接操作数据库本身(运维 / 紧急手段)。
2. 更新器(Updater)
simplegit 与外部世界保持同步的唯一通道。它是一个事件订阅者。
启动时可以指定(二选一,或都不选):
- 一个 URL:Updater 连接该端点订阅事件(webhook / 长轮询 / SSE 等)。
- 一个消息队列:Updater 连接该队列消费事件。
收到事件后,Updater 据此对 simplegit 自身做出更改(写私有库、触发仓库生命周期等)。
如果不订阅(既不指定 URL 也不指定队列):
- Updater 不运行 / 空转;
- simplegit 完全自行管理数据库,相当于一个孤立的 git 服务器;
- 数据库是"死的"——没有事件流去驱动它,只能通过 API 或直接改库来变更。
一句话:Updater 是 simplegit 从"孤立"走向"协同"的可插拔开关。 订阅了,它就跟着外部事件自我更新;不订阅,它就独立运转。
3. HTTP 鉴权:PAT + Basic Auth
HTTP 传输只保留这一种鉴权方式:
- 用户持 Personal Access Token(PAT);
- 走 HTTP Basic Auth:
git clone http://...时用户名随意、密码填 PAT; - simplegit 用本地私有库校验 PAT,不再依赖外部 RBAC 中心、不再校验 console 的 JWT。
HTTP 鉴权完全闭环在 simplegit 内部,符合"数据库只跟自己通"的原则。
SSH 传输仍走公钥,公钥→用户的解析同样查本地私有库,保持自包含。
运行形态
| 形态 | Updater | 数据库 | 说明 |
|---|---|---|---|
| 孤立模式 | 不订阅 | 自管 | 单机裸跑;变更只来自 API 或直改库 |
| 协同模式 | 订阅 URL 或 MQ | 由事件驱动更新 | 作为平台一员,跟随事件自我变更 |
两种形态是同一个二进制的不同启动参数,没有代码分支。
Git hooks
所有 Git hook 统一执行一个策略脚本:
hook.sh <hook-type> <owner/name> [Git hook 原始参数...]
脚本继承 hook 的 stdin 和 GIT_* 环境。daemon 默认使用工作目录或二进制旁的
hook.sh;本地开发可以直接修改默认脚本,生产环境通过
-hook-script=/path/to/production-hook.sh 替换。simplegit 不解释或转发 hook
事件,具体效果完全由该脚本负责。
仓库自带的 hook.sh 只向 <root>/hooks.log 追加 hook 类型、仓库、参数和 stdin,
不访问任何外部服务,因此 standalone simplegit 不依赖 CI。
simpleci 提供集成适配器 pkgs/simpleci/simplegit-hook.sh。联合部署让 simplegit
显式使用该脚本,并配置:
export SIMPLECI_URL=http://simpleci:8095
export SIMPLECI_HOOK_TOKEN=replace-with-a-shared-secret
export SIMPLECI_WORKFLOW=.github/workflows/deploy.yml # 可选
simplegit daemon -hook-script /path/to/simplegit-hook.sh
tag push 和分支删除不会触发构建;simpleci 不可用时通知最多等待 5 秒,且不影响 push 的成功结果。simpleci 使用相同 secret 启动:
simpleci -hook-token replace-with-a-shared-secret
SIMPLECI_HOOK_TOKEN 和 -hook-token 都为空时不启用鉴权,适合仅在受信任的
本机或内部网络开发;生产环境应从同一个 Secret 分别注入两端。
目录结构
cmd/ 入口、HTTP/SSH listener、host store
gitcmd/ git 仓库操作(tree/blob/commit/branch/merge/...)
gitrpc/ Connect-RPC server + 鉴权 middleware + client;v1 proto 与生成码
common/ 仓库路径解析(repolayout)
hook.sh 默认 Git hook 策略脚本
db/ 私有数据库(规划中)
updater/ 更新器(规划中)
build/ 构建产物
tests/ 集成测试
开发约束
state/内不允许放置任何_test.go文件。涉及 state 的行为验证必须放在state/之外的测试目录中。
实现状态
本文描述的是 simplegit 的目标设计哲学。当前代码正处于向该目标迁移的起点,尚未对齐:
- 鉴权:仍为 console JWT + RBAC 中心(
-auth/ JWKS),HTTP 走 Bearer 或 Basic-with-JWT;待迁移为 PAT + Basic Auth。 - 私有数据库:尚不存在,元数据仍由 console 持有;待引入。
- 更新器:尚未实现;当前仓库生命周期(init/clone/delete/rename)由 console 以系统 token 同步 RPC 调用,待改为事件订阅。
迁移完成后,-auth(RBAC 中心)这一外部依赖将被移除。