soft-serve git serve 和静态 git 页面
我喜欢 soft-serve 。
它比 gitea/forgejo/gitlab 更轻量:没有 wiki、软件包之类一些可有可无的周边功能,没有复杂的用户和组织权限,甚至没有 Issue/PR。
它比 cgit/git-daemon 更完整:支持 http, git, ssh 三种协议克隆仓库。通过 ssh cli (ssh git.charm.sh help) 即可进行仓库管理。(cgit 不会处理 go-get 的请求,需要自己在中间件里注入,就很别扭)
Static web service
soft-serve 没有 web 前端展示仓库。
动态的 git 仓库前端渲染,是一个比较耗费性能的功能,加上我的 git 仓库的前端界面不是特别重要,只需要能看一下软件介绍,能简单翻阅一下代码。静态的网页显然已经足够了。
可选的 git 静态网页生成器有:
- https://codemadness.org/stagit.html
- https://github.com/mrmekon/itsy-gitsy
- https://github.com/nmeum/depp
我选了 depp ,仅仅因为是我认识的人写的,加上 golang 改起来比较方便。
在服务端用 git post-receive hook 生成:
# file: $SOFT_SERV_DATA_PATH/hooks/post-receive # $SOFT_SERV_DATA_PATH/hooks 为soft-serve 公用 git hooks 目录 if [ -f "$SOFT_SERVE_REPO_PATH/git-daemon-export-ok" ]; then depp -c 10 \ -u "$SOFT_SERVE_GIT_PUBLIC_URL/$SOFT_SERVE_REPO_NAME.git" \ -d "/srv/http/git/$SOFT_SERVE_REPO_NAME" \ "$SOFT_SERVE_REPO_PATH" else [ -z "$SOFT_SERVE_REPO_NAME" ] || rm -rf "/srv/http/git/$SOFT_SERVE_REPO_NAME" fi # using my fork: https://git.lin.moe/fork/depp depp-index -r -x -d /srv/http/git -t git.lin.moe $SOFT_SERVE_DATA_PATH/repos
全部的 server-side hooks 在 https://git.lin.moe/githooks/
nginx 需要能展示静态页面的同时,还要能将 git 请求传递到 soft-serve ,需要写一两条规则:
upstream soft-serve { server localhost:23232; } server{ listen 443 ssl; listen [::]:443 ssl; server_name git.lin.moe; http2 on; ssl_certificate /path/to/certificate.pem; ssl_certificate_key /path/to/prikey.pem; root /srv/http/git/; location / { if ($arg_go-get != "") { proxy_pass http://soft-serve; } try_files $uri $uri/ @softserve; } location @softserve { proxy_pass http://soft-serve; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } }
SSH CLI wrapper
使用 ssh myserver.ltd 的方式有几个小缺点:
- 命令太长了
- 相比本地 cli 稍微会有一点慢,每次都要建立新的 ssh 连接
- ssh 协议是将所有命令参数作为一个字符串传递到服务端,遇到带引号的参数就无法保持原意了,比如
ssh myserver.ltd repo demo desc "This is my repo",服务端实际看到的是repo demo desc This is my repo
也为了以后方便支持 shell completion ,我写了一个小脚本:
: ${RGIT_CONTROL_PATH:="$HOME/.ssh/controlmaster/rgit"}
: ${RGIT_INSTANCE:="ssh://git.lin.moe"}
[ -d $(dirname $RGIT_CONTROL_PATH) ] || mkdir $(dirname $RGIT_CONTROL_PATH)
if [ ! -S $RGIT_CONTROL_PATH ]; then
ssh -f -N \
-o ExitOnForwardFailure=yes \
-o ControlMaster=auto \
-o ControlPath="$RGIT_CONTROL_PATH" \
-o ControlPersist=1h \
$RGIT_INSTANCE
fi
_quoted_args(){
echo -n "'$1'"
shift
for arg in "$@"; do
arg=$(echo $arg | sed "s/'/'\"'\"'/g")
echo -n " '$arg'"
done
}
ssh -o ControlMaster=auto \
-o ControlPath="$RGIT_CONTROL_PATH" \
-T $RGIT_INSTANCE "$(_quoted_args "$@")"
Issue/PR
用邮件列表