自托管 Git 的最小组成是一个存储提交的裸仓库、一个能访问它的服务账户,以及明确的 SSH 权限。它不等于在自己电脑上初始化普通仓库。
裸仓库与普通仓库
跳转到“裸仓库与普通仓库”普通仓库包含工作区,适合编辑和构建;裸仓库主要保存 Git 对象与引用,适合充当集中收发端。不要把部署网站的工作目录直接当作任意用户可以推送的 Git 服务器。
下面是假设已由管理员创建 git 服务账户,并将 /srv/git 的写权限交给该账户之后,以该账户执行的示例:
git init --bare --initial-branch=main /srv/git/project.git路径、账户、主机名都应替换为自己的环境;示例没有替你开放服务器访问权限。裸仓库初始没有提交,main 会在首次成功推送后出现。
客户端连接与首次推送
跳转到“客户端连接与首次推送”先通过受信渠道核对服务器 SSH 主机指纹。每位使用者配置自己的公钥,私钥留在客户端;不要在笔记或远程 URL 中粘贴密码和私钥。
# 客户端新项目git init -b main projectcd project# 创建并检查文件后,再选择性 add 和 commitgit remote add origin git@example.com:/srv/git/project.gitgit push -u origin main已有 origin 时,先 git remote -v 检查,再决定新增其他别名或 remote set-url。从已有服务器项目开始则用:
git clone git@example.com:/srv/git/project.git服务器仓库的默认 HEAD 可在裸仓库中通过 git symbolic-ref HEAD refs/heads/main 设置;这是服务器侧操作。客户端的 git remote set-head origin main 只改本地跟踪别名,两者不同。
权限与认证应如何分层
跳转到“权限与认证应如何分层”| 层次 | 需要确认的内容 |
|---|---|
| SSH 主机身份 | known_hosts 中的服务器指纹正确 |
| 用户认证 | 客户端私钥与服务端授权公钥对应 |
| 文件权限 | 接收推送的账户能写裸仓库,但不能任意改其他应用目录 |
| 操作授权 | SSH 登录成功不代表用户只能做 Git;需要按方案限制 shell 或命令 |
| 协作管理 | 分支保护、审查、审计和用户撤权需单独设计 |
Git 官方示例介绍了 git-shell 和共享访问的限制方式。多人协作若需要逐用户授权、合并请求和审计,更适合使用有这些能力的托管平台,不要仅共享一把私钥。
常见误解与验收
跳转到“常见误解与验收”把 SSH 地址换成 http://.../project.git 不会自动得到 HTTP Git 服务;服务器必须配置相应 HTTP 后端或托管应用。也不要用全盘 chmod 777、宽泛所有权修改或全局信任所有仓库来修权限。
首次推送后,在新的客户端目录 clone,并比较 git rev-parse HEAD 与 git ls-remote --heads origin main。再验证无权限用户不能推送。备份应覆盖裸仓库、必要配置和受保护的授权资料,不能只备份某次检出的源文件。