搭建阿里云Git服务器

警告
本文最后更新于 2019-11-29,文中内容可能已过时。

Git:版本控制系统

搭建 Git 服务器

第一步,安装git:

1
$ sudo apt-get install git

第二步,创建一个git用户,用来运行git服务:

1
$ sudo adduser git

第三步,创建证书登录:

收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

1
2
3
cat ~/.ssh/id_rsa.pub

## 复制公钥到 /home/git/.ssh/authorized_keys

第四步,初始化Git仓库:

先选定一个目录作为Git仓库,假定是/srv/test.git,在/srv目录下输入命令:

1
sudo git init --bare test.git

Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:

1
sudo chown -R git:git test.git

第五步,禁用shell登录:

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:

1
git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

1
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

第六步,克隆远程仓库:

现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:

1
2
3
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.

剩下的推送就简单了。

版本控制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
## 如果没有使用 gitosis
## git clone git@47.98.117.71:/home/git/codebase/test.git

## 如果使用 gitosis, 默认存放在 /home/git/repositories
git clone git@47.98.117.71:test.git

git checkout master
git pull

git branch dev
git checkout dev
git add ./*
git commit -m "modify dev"
git push origin dev

git checkout master
git merge dev
git add ./*
git commit -m "modify master"
git push origin master

## 本地获取其他分支
## 将远程git仓库里的指定分支拉取到本地(本地不存在的分支)
git checkout -b 本地分支名 origin/远程分支名

## 如果出现提示:
## fatal: Cannot update paths and switch to branch 'dev2' at the same time.
## Did you intend to checkout 'origin/dev2' which can not be resolved as commit?
## 表示拉取不成功。需要先执行
git fetch
## 然后再执行
git checkout -b 本地分支名 origin/远程分支名

团队管理

使用 gitosis 管理权限

gitosis 现已经被改写升级成 gitolite, 更好得支持在 branch 级别的权限控制

把团队成员的公钥保存到 /home/git/.ssh/authorized_keys 文件的做法,对于小规模的队伍是可行的。但是,这样的弊端也是十分明显:

  1. 随着团队规模的扩大、成员的离开,需要重复的增加/删除成员的公钥,这样比较繁琐,而且存在安全隐患
  2. git默认的权限是对于所有成员开放的,即所有成员都拥有对项目的读写权限,如果是非管理员用户,不小心在分支修改了代码,但是提交到了master上面,有可能导致整个项目崩盘
  3. 此外,我们还希望给部分成员拥有管理权限,部分成员拥有可读可写权限,而剩下的[实习]成员则只有可读权限,这个需要通过项目的权限管理机制实现。

安装 gitosis

gitosispython 项目,需要安装 python-setuptools 模块

1
apt-get install python-setuptools

然后安装 gitosis

1
2
3
4
cd ~
git clone https://github.com/tv42/gitosis.git
cd gitosis
sudo python setup.py install

默认情况下,gitosis 会把项目放在 /home/git/repositories

1
2
3
4
5
total 16
drwxr-x--- 8 git git 4096 Nov 30 13:22 gitosis-admin.git
drwxr-x--- 7 git git 4096 Nov 30 13:05 solarflare.git
drwxr-x--- 7 git git 4096 Nov 30 13:22 test2.git
drwxr-x--- 7 git git 4096 Nov 30 13:06 test.git

如果原来代码已经放在别的文件夹,可以使用 ln

1
ln -s /opt/git /home/git/repositories

Gitosis 将会帮我们管理用户公钥,所以先把当前控制文件改名备份,以便稍后重新添加,准备好让 Gitosis 自动管理 authorized_keys 文件:

1
mv /home/git/.ssh/authorized_keys /home/git/.ssh/authorized_keys_bk

接下来,修改 git 通过 shell 登录

1
2
3
4
vim /etc/passwd

## 修改成如下
git:x:1000:1000::/home/git:/bin/sh

增加管理员

gitosis 默认会搭建一个 gitosis-admin.git 的仓库用来管理所有的用户权限。因此,我们需要增加一个代码管理员来管理这个repo,即只有这个用户才有权限修改项目的权限归属。 比如,我(william)的本地机器作为 gitosis-admin.git 的所有者,需要把本地的 id_rsa.pub 加入到 gitosis-admin.git,然后开始初始化仓库

1
2
3
scp ~/.ssh/id_rsa.pub root@47.98.117.71:/tmp

sudo -H -u git gitosis-init < /tmp/id_rsa.pub

这样,我(william)的本地机器变成了 gitosis-admin.git 的所有者,管理所有仓库的权限。

接下来,需要手工对该仓库中的 post-update 脚本加上可执行权限:

1
sudo chmod 755 /home/git/gitosis-admin.git/hooks/post-update

试着登录服务器的git

1
2
3
4
5
ssh git@47.98.117.71

PTY allocation request failed on channel 0
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to 47.98.117.71 closed.

说明 Gitosis 认出了该用户的身份,但由于没有运行任何 Git 命令,所以它切断了连接。那么,现在运行一个实际的 Git 命令 — 克隆 Gitosis 的控制仓库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
cd ~/Documents
git clone git@47.98.117.71:gitosis-admin.git
cd gitosis-admin

gitosis.conf  keydir

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

total 20K
drwxrwxr-x  4 william william 4.0K Nov 30 13:22 ./
drwxr-xr-x 50 william william 4.0K Nov 30 12:57 ../
drwxrwxr-x  8 william william 4.0K Nov 30 15:29 .git/
-rw-rw-r--  1 william william  399 Nov 30 13:22 gitosis.conf
drwxrwxr-x  2 william william 4.0K Nov 30 13:10 keydir/

其中

  1. gitosis.conf是配置文件
  2. keydir存放公钥.pub
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat gitosis.conf

[gitosis]

[group gitosis-admin]
members = william.lian.fang@gmail.com
writable = gitosis-admin

[group hicloud-hft]
members = william.lian.fang@gmail.com
writable = solarflare

[group hicloud-hft]
members = william.lian.fang@gmail.com fl166
writable = test

[group hicloud-test]
members = william.lian.fang@gmail.com
writable = test2

[group hicloud-test-readonly]
members = fl166
readonly = test2
1
2
3
4
5
6
7
8
cd keydir
ll

total 16K
drwxrwxr-x 2 william william 4.0K Nov 30 13:10  ./
drwxrwxr-x 4 william william 4.0K Nov 30 13:22  ../
-rw-rw-r-- 1 william william 1.2K Nov 30 13:10  fl166.pub
-rw-rw-r-- 1 william william  409 Nov 30 12:42 'william.lian.fang@gmail.com.pub'

看到上面的文件,如 fl166.pub,存放的便是公钥,这个文件名需要对应以上的 members 才能够被识别。

我们可以看出

  1. 对于 test.git, william.lian.fang@gmail.comfl166 拥有 writable 的可读可写权限。
  2. 而对于 test2.git, william.lian.fang@gmail.com 拥有 writable 的可读可写权限, 而 fl166 只有读的权限,即不可参与项目代码修改,如果推送修改会报错
    1
    2
    3
    4
    5
    
    ERROR:gitosis.serve.main:Repository write access denied
    fatal: Could not read from remote repository.
    
    Please make sure you have the correct access rights
    and the repository exists.

使用 gitolite 管理权限

安装 gitolite

由于 gitolite 使用 Perl 编写,因此我们需要先安装

1
sudo yum install perl

同样,我们需要修改

1
2
3
4
vim /etc/passwd

## 修改成如下
git:x :1000:1000::/home/git:/bin/sh

然后切换到用户 git 安装

1
2
3
4
5
6
7
su git
cd /home/git
git clone git://github.com/sitaramc/gitolite

## 安装到 /home/git/bin 目录下
mkdir -p /home/git/bin
./gitolite/install -to /home/git/bin/

添加管理员

可以有两种方式添加管理员

  1. 服务器作为管理员
  2. 第三方用户作为管理员

我更倾向第二种方法,因为这样可以避免频繁的登录服务器操作。

1
2
## !!! 在本地机器操作
scp ~/.ssh/id_rsa.pub root@47.98.117.71:/home/git/.ssh/william.pub

Gitolite 将会帮我们管理用户公钥,所以先把当前控制文件改名备份,以便稍后重新添加,准备好让 Gitosis 自动管理 authorized_keys 文件:

1
2
3
4
cd ~/
chmod 700 -R .ssh
chmod 600 authorized_keys
mv /home/git/.ssh/authorized_keys /home/git/.ssh/authorized_keys_bk

然后在服务器终端操作

1
2
3
4
/home/git/bin/gitolite setup -pk /home/git/.ssh/william.pub

Initialized empty Git repository in /home/git/repositories/gitolite-admin.git/
Initialized empty Git repository in /home/git/repositories/testing.git/

出现以上消息说明操作成功,我们可以看到在 /home/git/repositories 初始化了两个repo

1
2
3
4
ll
total 8
drwx------ 8 git git 4096 Dec  1 15:15 gitolite-admin.git
drwx------ 7 git git 4096 Dec  1 15:15 testing.git

如此一来,我们便可以在 william 的这台电脑上设置用户权限了。

设置用户权限

我们在本地机器(william)终端操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
## 本地机器 william

cd ~/Documents
git clone git@47.98.117.71:gitolite-admin.git

cd gitolite-admin
ll
total 20K
drwxrwxr-x  5 william william 4.0K Dec  1 14:24 ./
drwxr-xr-x 52 william william 4.0K Dec  1 14:34 ../
drwxrwxr-x  2 william william 4.0K Dec  1 15:07 conf/
drwxrwxr-x  8 william william 4.0K Dec  1 15:43 .git/
drwxrwxr-x  2 william william 4.0K Dec  1 15:15 keydir/

其中:

  1. keydir 用来存放用户的 id_rsa.pub 公钥,文件名字对应用户名称,如 fl166.pub 则对应 fl166 这个用户,需要在 gitolite.conf 配置文件使用到。

    1
    2
    3
    4
    5
    6
    7
    
    cd keydir
    ll
    total 16K
    drwxrwxr-x 2 william william 4.0K Dec  1 15:15 ./
    drwxrwxr-x 5 william william 4.0K Dec  1 14:24 ../
    -rw-rw-r-- 1 william william  409 Dec  1 14:28 fl166.pub
    -rw-rw-r-- 1 william william  409 Dec  1 14:24 git_admin_william.pub
  2. conf 是配置文件,修改用户所属项目的读写权限

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    cd conf
    ll
    
    total 12K
    drwxrwxr-x 2 william william 4.0K Dec  1 15:07 ./
    drwxrwxr-x 5 william william 4.0K Dec  1 14:24 ../
    -rw-rw-r-- 1 william william  210 Dec  1 15:15 gitolite.conf
    
    cat gitolite.conf
    
    repo gitolite-admin
    	RW+     =       git_admin_william
    
    repo testing
    	RW+		=		@all
    
    repo test1
    	RW+		=		@all
    
    repo test2
    	RW+ 	     =	    git_admin_william
    	R   master   = 	    fl166
    	RW+ from166  =      fl166

    这里,以 test2 为例,说明各个用户的权限

    • git_admin_william 拥有顶级的可读(R)、可写(W)、以及强制更新(+)权限
    • fl166 只拥有对 master 分支的读取权限,没有其他(写)权限
    • fl166 还拥有对的分支 from166 的可读(R)、可写(W)、以及强制更新(+)权限

开发项目结构

参考链接

  1. gitosis 安装使用及错误整理:步骤讲解比较详细
  2. git 团队协作:快速入门必备

相关内容

william 支付宝支付宝
william 微信微信
0%