Git Server - Nginx

目的, 在服务器上管理自己的Git Repo, 并同时挂载到网页上. Git有提供架设Git服务的文档, Setting Up the Server. 按照文档流程, 基本上能够比较顺利.

同时还提供了GitWeb, CGI脚本管理网页后端. But one downside is, 文档用的是Apache, 而我的网页用Nginx管理, 所以在配置上会有些许差别. 目前为止, 网上关于Git Server的搭建资料比较少, Nginx的更少.

如果想和我一样, 将GitWeb自定义到“牙齿”, 就会比较麻烦. 所以本文记录一些我经历的有意思的点, 并且介于基础搭建的文档已经比较完善, 就不再赘述. 在此非常感谢Witch of Light分享的Hosting My Own Git.

Nginx配置

/etc/nginx/sites-available/下存放virtual host配置, 创建git用于GitWeb, 并在sites-enabled/下创建关于其的symbol link.
我的配置如下:

set $my_root /var/www/git;
root $my_root;

index gitweb.cgi;

server_name git.xinqibao.xyz www.git.xinqibao.xyz;

location / {
    try_files $uri @gitweb;
}

location ~ /\. {
    deny all; # 禁止访问以.开头的隐藏目录和文件
    access_log off; # 关闭访问日志记录
    log_not_found off; # 关闭未找到文件的日志记录
}

location @gitweb {
    include fastcgi_params;
    gzip off;
    fastcgi_param SCRIPT_FILENAME $my_root/gitweb.cgi;
    fastcgi_param PATH_INFO $uri;
    fastcgi_param GITWEB_CONFIG $my_root/gitweb.conf;
    fastcgi_pass unix:/var/run/fcgiwrap.socket;
}

location /static {
    try_files $uri $uri/ =404;
}
uri传给PATH_INFO环境变量, 对于将URL参数传给CGI脚本, ACTIONS, AND URLS.

GitWeb配置

Git关于GitWeb的介绍以及配置文档, gitweb, gitweb.conf, 涵盖了绝大部分的配置信息.

GitWeb的默认CGI脚本以及conf配置文件, 可在/usr/share/gitweb/gitweb.cgi/etc/gitweb.conf找到.
我的配置:

# path to git projects (.git)
$projectroot = "/var/www/git/";

# directory to use for temp files
$git_temp = "/tmp";

# html text to include at home page
$home_text = "static/html/indextext.html";
$site_header = "static/html/header.html";
$site_footer = "static/html/footer.html";

# file with project list; by default, simply scan the projectroot dir.
$projects_list = "static/projects_list";

# stylesheet to use
@stylesheets = ("static/css/gitweb.css", "static/css/styles.css");

# javascript code for gitweb
#$javascript = "static/gitweb.js";

# the 'favicon'
$favicon = "static/img/crab.ico";

# git-diff-tree(1) options to use for generated patches
#@diff_opts = ("-M");
@diff_opts = ();

$site_name = "Xinqi Bao's Git";

$logo = undef;
$feature{'search'}{'default'} = [0];
$feature{'pathinfo'}{'default'} = [1];
关于每个配置的细节, 可以查阅文档. 部分配置并没有在文档中说明, 可以在CGI中找到相关的注释.

不同的git clone

文档的介绍, The Protocols.

SSH

只需在服务器添加自己的ssh key, 即可对repo进行pull和push操作. 在git server完成即可使用, 不需要额外的配置.

GIT

需要启用Git Daemon. --export-all参数允许所有路径下的repo的访问.

只支持pull, 不支持push操作, 适合非repo作者的访问.

HTTP

分为Smart HTTP 和 Dumb HTTP. 暂时没有对Smart HTTP的需求, 详细参见文档, Smart HTTP.

Dumb HTTP在clone的时候, 需要objects/info/packsinfo/refs, 可通过git update-server-info更新获得. 也可以通过挂载hook脚本实现.

hooks/目录下提供了多种hook, 可以在某些固定事件中被触发, 详见Git Hooks.

代码高亮

配置文件添加$feature{'highlight'}{'default'} = [1];激活代码高亮.

参考Syntax highlighting, Highlight manual. 高亮颜色可通过配置css改变.

进阶

尽管GitWeb提供了大量的config功能, 奈何很多东西没法通过配置更改. 所以想要更细致的修改, 需要在gitweb.cgi中直接更改.

创建bare repo的时候, 容易出现一些问题, 比如不小心通过root创建的库, 结果导致没法被git用户正常访问, 同时还需要把自定义的hook脚本复制到新repo中. 故此, 使用的脚本对repo进行创建操作.

#!/bin/bash
set -e

if [ -z $1 ]; then
    echo "Usage: make-repo "
    exit 0
fi
# Strip .git from the name if you specify it, for uniformity
repo=$(basename -s.git $1)
# We don't want to work as root, but we login as root (oops?)
# so it's convenient to automatically switch to the git user
if [ "$EUID" -eq 0 ]; then exec su git -c "$0 $1"; fi
# Only allow running as the git user, for file permissions purposes
if [ $(whoami) != "git" ]; then
    echo "Please run this tool as the 'git' user"
    exit 1
fi
# Don't overwrite existing repositories
if [ -d "/$repo.git" ]; then
    echo "Repository '$1' already exists"
    exit 2
fi

# Make a bare repo for SSH cloning
git init --bare "$repo.git"
#copy all the hooks to nre repo
cp static/hooks/* "$repo.git"/hooks/
# We immediately edit the description file that will show up in GitWeb
#sensible-editor "$repo.git/description"

hooks/post-update会在每次push的时候被触发. 在此脚本中添加git cat-file blob HEAD:README.md | pulldown-cmark > README.html, 将README.md转成README.html, 可被GitWeb识别并显示在repo summary中.