Gitolite 介绍

2019-07-31

今天给大家介绍一下 gitolite

一提起 Git,大家基本上都会想到 GitHub, GitLab 这一类在线托管平台。

我们可能习惯了在这些平台上创建仓库、推拉代码、创建 Pull/Merge Request、发起 Issue。但这些特性都不是 Git 提供的,Git 能跟踪的只有代码信息。这类平台是在 Git 之上重新构建了一套 Web 系统来保存诸如用户、Pull/Merge Request、Issue 等信息的。

功能越强大,系统越复杂。

如果你只是想简单控制一下用户权限,则不需要这么复杂的系统,gitolite 就够用。我也是偶然发现 gitolite 的,很喜欢这种轻量级的设计。我没想到的是好多著名的开源项目也在使用 gitolite:

gitolite 的原理很简单。首先,它提供了一个 gitolite-shell。当你使用 ssh 访问 gitolite 时 ssh 服务会启动 gitolite-shell。这个脚本会检查当前用户是否有权限访问对应的仓库。如果用户通过 git push 修改了仓库内容,则会触发 gitolite 预先配置 git hook,这些 hook 会执行创建仓库、添加用户之类的操作。

gitolite 的本质是几个 prel 脚本加一些纯文本配置文件,没有什么魔法。

简单说一下 gitolite 的安装与使用。

先安装好 git 和 openssh,再创建一个 git 系统用户:

# -m 表示创建对应的 /home/git 目录
$ userad -m git

把你的 ssh 公钥保存成 yourname.pub 备用。你可以把这个 yourname 改成你喜欢的名字。

这个时候,基础准备工作就完成了,开始安装:

$ su - git
$ git clone https://github.com/sitaramc/gitolite
$ ./gitolite/src/gitolite setup -pk /tmp/yourname.pub
Initialized empty Git repository in /home/git/repositories/gitolite-admin.git/
Initialized empty Git repository in /home/git/repositories/testing.git/
WARNING: /home/git/.ssh missing; creating a new one
    (this is normal on a brand new install)
WARNING: /home/git/.ssh/authorized_keys missing; creating a new one
    (this is normal on a brand new install)

这里的 -pk 选项是指定管理员的公钥和用户名。git 跟 gitolite 服务器通信用的是 git 这个真正的系统用户,而 gitolite 控制仓库权限则是使用自己的虚拟用户。这里的 yourname 就是虚拟用户。

好了,到此安装完毕。让我们来体验一下。gitolite 默认为大家创建了一个开放的 testing 仓库。

$ git clone git@yourhost:testing.git
Cloning into 'testing'...
warning: You appear to have cloned an empty repository.

如果你想克隆一个不存在的仓库,则会报错:

$ git clone git@yourhost:foo.git
Cloning into 'foo'...
FATAL: R any foo yourname DENIED by fallthru
(or you mis-spelled the reponame)
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

那怎样添加新仓库呢?这就得用到 gitolite-admin 这个特殊的仓库了,先克隆下来,其目录结构如下:

tree .
.
├── conf
│   └── gitolite.conf
└── keydir
    └── yourname.pub

    2 directories, 2 files

keydir 保存用户的公钥,一个用户对应一个文件。conf/gitolite.conf 保存用户权限。

$ cat conf/gitolite.conf
repo gitolite-admin
    RW+     =   yourname

repo testing
    RW+     =   @all

这里配置了两个仓库,gitolite-admin 仓库只有 yourname 用户可以读写。testing 仓库的读写权限则授予了 @all,不用猜就知道是授予所有人可以读写的意思。

如是想添加一个新仓库,则添加一条 repo 配置就行,比如:

$ cat conf/gitolite.conf
repo gitolite-admin
    RW+     =   yourname

repo testing
    RW+     =   @all

repo foo
    RW+     =   @all

改好之后提交并推送到远端,gitolite 就会自动创建 foo 仓库。

$ git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 378 bytes | 378.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Initialized empty Git repository in /home/git/repositories/foo.git/
To 192.168.56.101:gitolite-admin.git
   c8a8aa8..d36e1a1  master -> master

显然,gitolite 是利用 git 的 hook 机制自动创建 foo 仓库的。

加人就更简单。如果要添加的用户名是 hello,则只需将将 hello 的公钥保存到 keydir/hello.pub 并推到远端就可以了。就个是候你打开服务端的 /home/git/.ssh/authorized_keys 会发现:

# gitolite start
command="/home/git/gitolite/src/gitolite-shell hello",...
command="/home/git/gitolite/src/gitolite-shell yourname",...
# gitolite end

hello 的用户名已经配置好了。

gitolite 使用 git 来管理 git 的权限,是不是有点自举的意思。

gitolite 还支持仓库分组、用户分组、分支/tag权限控制等高级功能,大家可以移步官方文档,我就不赘述了。

最后总结一下。gitolite 是一个非常轻量级的 git 代码托管方案,只能控制权限,没有 Pull Request/Issue 等功能,有好多大型开源项目在使用。同时,gitolite 也是很好的学习 git 相关知识的平台。