Git 服务器

出自 ArchWiki
(重定向自Git 协议

本文概述了如何托管 Git 服务器。更多信息,请参考 Pro Git 书籍的服务器上的 Git 章节

协议

详细描述以及优缺点,请参考服务器上的 Git - 协议

通用

在 Arch Linux 上设置 git 服务器的分步指南 描述了如何在 Arch 上设置不安全的服务器。

默认情况下,git 用户已过期(“您的帐户已过期;请联系您的系统管理员”)。使用 chage 删除过期条件,例如如下所示

# chage -E -1 git

SSH

您只需要设置一个 SSH 服务器

您可以进一步保护 SSH 用户帐户,只允许此用户帐户执行推送和拉取命令。这可以通过将默认登录 shell 替换为 git-shell 来完成。设置服务器 中对此进行了描述。

当使用 (#SSH) 条款的说明来保护使用 (#通用) 中的说明创建的 git 服务器时,需要在 Arch 上执行以下附加步骤

  1. 更改主目录:为了使 ssh 能够读取 /srv/git/.ssh/authorized_keys/etc/passwd 中 git 的主目录需要从 / 更改为 /srv/git
  2. 当主目录被更正时,更改基本路径:为了使 git 服务仓库,如果仓库从 git 的主目录提供,则 git-daemon\@.service 中的 --base-path 需要更改为 /srv/git

Dumb HTTP

此处的“Dumb”意味着只有 WebDAV 参与拉取和推送。

nginx

按照 nginx 的基本 WebDAV 说明进行操作。通过 WebDAV 推送也需要锁定。这是一个示例 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。将指定的锁定区域添加到配置文件的 http 部分

/etc/nginx/nginx.conf
dav_ext_lock_zone zone=general:10m;

现在执行为服务器准备 git 仓库的常用步骤

  • git clone --bare /path/to/myrepo myrepo.git
  • 将裸仓库复制到服务器
  • 在裸仓库中运行 git update-server-info
  • 将仓库的所有者更改为 http:http

您可能已经注意到我添加了 HTTP 基本身份验证,以便至少有一些访问控制手段。任何在 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

本文或章节需要扩充。

原因: 有许多支持 CGI 的 web 服务器。(在 Talk:Git server 中讨论)

git-http-backend(1) 是一个 CGI 程序,允许通过 HTTP(S) 进行高效的克隆、拉取和推送。

Apache

此设置相当简单,因为您只需要安装 Apache HTTP 服务器,并启用 mod_cgimod_aliasmod_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 的方式访问它们。

注意: 确保 Apache 可以读取和写入您的仓库。

有关更详细的文档,请访问以下链接

Git

Git 协议未加密或身份验证,并且仅允许读取访问。

Git 守护进程 (git-daemon(1)) 可以使用 git-daemon.socket 启动

该服务使用 --export-all--base-path 参数来服务放置在 /srv/git/ 中的所有仓库。

访问控制

对于细粒度的访问控制,可以使用以下解决方案

  • Gitolite — Git 之上的访问控制层,用 Perl 编写。
https://github.com/sitaramc/gitolite || gitolite
  • Gitosis — 用于托管 Git 仓库的软件,用 Python 编写。
https://github.com/tv42/gitosis || gitosis-gitAUR

请注意,如果您愿意为所有应该有权访问仓库的人创建用户帐户,并且不需要在 git 对象级别(如分支)进行访问控制,您也可以使用标准的文件权限进行访问控制。[1]

Web 界面

简单 Web 应用程序

  • Gitweb — Git 自带的默认 Web 界面
  • cgit — 用纯 C 编写的 git Web 界面。
https://git.zx2c4.com/cgit/ || cgit

高级 Web 应用程序

  • Forgejo — 自托管的轻量级软件 Forge。Gitea 的社区管理分支。
https://forgejo.org || forgejo
  • Gitea — 无痛的自托管 Git 服务。它最初是作为 Gogs 的社区管理分支而诞生的,但在 2022 年,它成为 Gitea Limited 拥有并采用商业模式。
https://gitea.io || gitea
  • GitLab — 项目管理和代码托管应用程序,用 Ruby 编写。
https://gitlab.com/gitlab-org/gitlab-ce || gitlab
  • Gogs — 自托管 Git 服务,用 Go 编写。
https://gogs.io || gogsAUR