Git 服务器
本文概述了如何托管 Git 服务器。更多信息,请参考 Pro Git 书籍中关于 Git 服务器的章节。
协议
请参考 Git on the Server - The Protocols 以获取详细描述以及优缺点。
通用
Step by Step Guide on Setting Up git Server 描述了如何在 Arch 上设置不安全的服务器。
默认情况下,git 用户已过期(“Your account has expired; please contact your system administrator”)。使用 chage 移除过期条件,例如如下操作
# chage -E -1 git
SSH
你只需要设置一个 SSH 服务器。
你可以进一步保护 SSH 用户账户,仅允许在此用户账户上执行 push 和 pull 命令。这可以通过将默认登录 shell 替换为 git-shell 来完成。详情请参考 Setting Up the Server。
当使用 #通用 中的说明创建 git 服务器,并使用本节 (#SSH) 的说明进行保护时,需要在 Arch 上执行以下额外步骤
- 更改 home 目录:为了使 ssh 能够读取
/srv/git/.ssh/authorized_keys
,需要将/etc/passwd
中 git 的 home 目录从/
更改为/srv/git
。 - 当 home 目录被修正后更改 base path:为了使 git 服务仓库,如果仓库从 git 的 home 目录提供服务,则需要将
git-daemon\@.service
中的--base-path
更改为/srv/git
。
Dumb HTTP
在此上下文中,“Dumb” 意味着只有 WebDAV 参与 pull 和 push 操作。
nginx
按照 nginx 的基本 WebDAV 说明进行操作。通过 WebDAV 推送也需要锁定 (Locking)。这是一个 location 代码块的示例
/etc/nginx/nginx.conf
location /repos/ { auth_basic "Authorized Personnel Only!"; auth_basic_user_file /etc/nginx/htpasswd; dav_methods PUT DELETE MKCOL COPY MOVE; dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK; dav_access user:rw group:rw all:r; dav_ext_lock zone=general; create_full_put_path on; client_body_temp_path /tmp; }
注意 dav_ext_lock zone
。将指定的 locking zone 添加到你的配置文件的 http section 中
/etc/nginx/nginx.conf
dav_ext_lock_zone zone=general:10m;
现在执行为服务器准备 git 仓库的常用步骤
git clone --bare /path/to/myrepo myrepo.git
- 将 bare repo 复制到服务器
- 在 bare repo 中运行
git update-server-info
- 将 repo 的所有者更改为 http:http
你可能已经注意到我添加了 HTTP Basic Authentication,以便至少拥有一些访问控制手段。任何在 htaccess 文件中拥有密码条目的人都可以推送。
现在你可以像往常一样克隆
$ git clone https://www.example.com/repos/myrepo.git Cloning into 'myrepo'... $
进行一些更改,添加、提交和推送
$ git push origin main error: Cannot access URL https://www.example.com/repos/myrepo.git/, return code 22 fatal: git-http-push failed error: failed to push some refs to 'https://www.example.com/repos/myrepo.git'
糟糕!由于某些原因,PROPFIND 报告 401 Unauthorized,仅此而已。nginx 错误日志中没有任何内容。显然,git 客户端在为所有后续请求传递用户名和密码时遇到了问题。运行 git 凭据缓存没有帮助。到目前为止,唯一有效的解决方案是编辑 ~/.netrc (显然 git 使用 curl 进行 http)
~/.netrc
machine www.example.com login git password topsecret
$ > git push origin main Fetching remote heads... refs/ refs/heads/ refs/tags/ updating 'refs/heads/main' from 03f8860418facfbecedd5e0a81b480131b31bcba to ec5536091e31ebf172a34c6d1ebddfc36e3bd3a6 sending 3 objects done Updating remote server info To https://www.example.com/repos/myrepo.git 0318860..ec55560 main -> main
甚至不要考虑将克隆 URL 指定为 https://username:password@www.example.com/repos/myrepo.git
。这对于初始克隆有效,但对于后续推送,你会在错误日志中收到一条错误消息,指出目标 URL 由不同的仓库处理。
Smart HTTP
git-http-backend(1) 是一个 CGI 程序,允许通过 HTTP(S) 进行高效的克隆、拉取和推送。
Apache
此设置相当简单,因为你只需要安装 Apache HTTP Server,并启用 mod_cgi
、mod_alias
和 mod_env
),当然还有 git。
一旦你的基本设置运行起来,将以下内容添加到你的 Apache 配置文件中,该文件通常位于
/etc/httpd/conf/httpd.conf
<Directory "/usr/lib/git-core"> Require all granted </Directory> SetEnv GIT_PROJECT_ROOT /srv/git SetEnv GIT_HTTP_EXPORT_ALL ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
这假设你的 Git 仓库位于 /srv/git
,并且你希望通过类似以下方式访问它们:http(s)://your_address.tld/git/your_repo.git
。
有关更详细的文档,请访问以下链接
Git
Git 协议未加密或身份验证,并且仅允许读取访问。
Git 守护进程 (git-daemon(1)) 可以使用 git-daemon.socket
启动。
该服务使用 --export-all
和 --base-path
参数来服务放置在 /srv/git/
中的所有仓库。
访问控制
为了实现细粒度的访问控制,可以使用以下解决方案
- Gitolite — Git 之上的访问控制层,用 Perl 编写。
- Gitosis — 用于托管 Git 仓库的软件,用 Python 编写。
请注意,如果你愿意为所有应该访问仓库的人创建 用户账户,并且不需要在 git 对象级别(如分支)进行访问控制,你也可以使用标准 文件权限 进行访问控制。[1]
Web 界面
简单的 Web 应用程序
高级 Web 应用程序
- Forgejo — 自托管的轻量级软件 forge。Gitea 的社区管理分支。
- Gitea — 轻松的自托管 Git 服务。它最初是作为 Gogs 的社区管理分支而诞生的,但在 2022 年,它成为 Gitea Limited 所有,并采用商业模式。
- GitLab — 项目管理和代码托管应用程序,用 Ruby 编写。
- Gogs — 自托管 Git 服务,用 Go 编写。
- https://gogs.io || gogsAUR