Ubuntu下搭建Git服务器

下面搭建的git服务器的简易网络拓扑图如下所示:



一、安装及配置所需软件[Git服务器,coffee@workpc1]

git-core是git版本控制核心软件,而且git是通过ssh协议来在服务器与客户端之间传输文件,故openssh-server、openssh-client必不可少。
[coffee@workpc1:~$] sudo apt-get install git-core openssh-server openssh-client


初始化git用户信息(内容随便填写,若省略这步操作,后面的git命令无法完成)

[coffee@workpc1:~$] git config --global user.name "coffee"  
[coffee@workpc1:~$] git config --global user.email "[email protected]"


下载Gitosis。Gitosis是什么?在这不细说,您只需要知道它是Git权限管理系统即可。

[coffee@workpc1:~$] git clone https://github.com/res0nat0r/gitosis.git


安装python的setuptools。Gitosis的工作依赖于某些Python工具,所以首先要安装Python的setuptools包。

[coffee@workpc1:~$] sudo apt-get install python-setuptools


安装Gitosis。这里便需要用到上面安装的python工具了。
[coffee@workpc1:~$] cd gitosis/
[coffee@workpc1:~$] sudo python setup.py install


二、在Git服务器上创建git仓库用户[Git服务器,coffee@workpc1]
1. 什么叫git仓库用户?我是这样定义的:一个“用来将管理仓库(gitosis-admin.git)以及所有的git项目仓库存储于它的home空间”的ubuntu用户。git仓库用户并不一定就是git管理员!!这点必须明白。
2. 此处再罗嗦几句。这一步要创建的用户,网上绝大部分文档都取名为“git”。这点我一直没弄明白,为什么非得叫“git”,而不能是“张三”、“李四”,是Git的明文规定吗?非也!为了更好的理解本篇文章以及git服务器的工作原理,我创建的这个具有git属性的用户名字叫做“john”。(我相信这对初学者来说,对理清思路是有帮助的。当然,对于深入理解git的人来说叫啥都是一样的)
[coffee@workpc1:~$] sudo useradd -m john
[coffee@workpc1:~$] sudo passwd john

将john设置为sudo用户,ubuntu创建的用户默认都不属于sudo用户组。
[coffee@workpc1:~$] sudo vi /etc/group
[coffee@workpc1:~$] sudo:x:27:zhouxiang,john


注意,您不要着急敲下面的命令,只看就行,因为这些命令与《搭建git服务器》其实半毛钱关系也没有!我讲这些的目的是为了不让您再被网上的那些资料所困扰
/////////////////////////////////////////////////////

~$ sudo mkdir /home/gitrepository  
~$ sudo chown john:john /home/gitrepository/  
~$ sudo chmod 700 /home/gitrepository/
~$ sudo ln -s /home/gitrepository /home/john/repositories

/////////////////////////////////////////////////////
我在最开始搭建git服务器的时候,也是参考网上的一些资料,按照他们说的步骤一步一步操作。当碰到上面这些操作的时候,我就蒙圈了!我不明白为什么要这么做?既然Gitosis默认状态下会将git仓库放在服务器上git用户主目录(home)下的repositories目录下,那就让它放在那呗,为什么非得搞一个链接,将repositories指向别的目录呢?难道这也是Gitosis明文规定的吗?非也!可惜,网上这些作者根本就不解释为什么这么做。虽然心中一直“不爽”,但是作为小白的我只能按着“圣典”操作。直到现在,终于理解了,上述命令只是那些作者的一些“个人爱好”而已,完全是没必要的!那些作者们您非要改变它的存放位置,那也请给出适当的解释嘛(比如说是为了防止git用户的存储空间不够用了啊什么的)。废话少说,接着讲正题...


三、生成git管理员的公钥[开发机1,zhouxiang@ZHONGDUANCP-31]
正式任命zhouxiang@ZHONGDUANCP-31为git管理员

[zhouxiang@ZHONGDUANCP-31:~$] ssh-keygen -t rsa #不需要密码,一路回车就行(在本地操作)


[zhouxiang@ZHONGDUANCP-31:~$] scp ~/.ssh/id_rsa.pub coffee@workpc1:/tmp/  #上传ssh public key到Git服务器


说明:如果scp提示如下错误:
ssh: Could not resolve hostname workpc1: Name or service not known
lost connection
两种解决办法,一是修改/etc/hosts文件;二是用ip地址替换主机名workpc1。

四、初始化Gitosis[Git服务器,john@workpc1]
目前为止,Git服务器端还一直在coffe用户下,现切换至john用户(因为在第二步,定义了john为git仓库用户,仓库将都会存放在john的用户空间下)
[john@workpc1:~$] su john

[john@workpc1:~$] cd #转至john的home目录

初始化git用户信息(内容随便填写)
[john@workpc1:~$] git config --global user.name "john"  
[john@workpc1:~$] git config --global user.email "[email protected]"


[john@workpc1:~$] sudo -H -u john gitosis-init < /tmp/id_rsa.pub #用git管理员的公钥来对Gitosis进行初始化


执行之后,home目录下出现一个repositories的目录,目录下存在一个gitosis-admin.git的git库. 其实Gitosis就是通过这个git库来管理所有git库的访问权限的。gitosis-admin的库中存在一个gitosis.conf和一个keydir的目录。其中:

1. gitosis.conf文件就是权限配置的地方(其语法及用法可以去查看相关帮助),该文件位于~/repositories/gitosis-admin.git/。用vi打开gitosis.conf文件,可看到zhouxiang@ZHONGDUANCP-31对giosis-admin.git仓库具有写权限,他即是管理员。


2. keydir目录下存放的是所有客户端的公钥,该目录位于~/repositories/gitosis-admin.git/gitosis-export/keydir/,公钥名字必须和配置文件中的member名字对应。


这里我们还需要对其中的一个post-update文件添加可执行的权限。(其实,在我的环境下,该文件的权限已经是755了)

[john@workpc1:~$] sudo chmod 755 ~/repositories/gitosis-admin.git/hooks/post-update


截止到这,Git服务器架构搭建完毕,仓库是空的(除了自带的gitosis-admin.git仓库),配置文件也是最简单的配置。

接下来,我们来创建git项目,编辑gitosis.conf配置文件为git项目指定可操作的用户和用户所拥有的权限,为用户生成公钥,最后将所有改动上传到Git服务器。


五、配置gitosis-admin[开发机1,zhouxiang@ZHONGDUANCP-31]
目前,git管理员只有一名成员:zhouxiang@ZHONGDUANCP-31,只有它有权限配置gitosis-admin。
[zhouxiang@ZHONGDUANCP-31:~$] git clone john@workpc1:gitosis-admin.git #获取Gitosis管理项目

在当前目录下将会产生一个gitosis-admin的目录,里面有配置文件gitosis.conf和一个keydir的目录,keydir目录主要存放git用户名。

[zhouxiang@ZHONGDUANCP-31:~$] vi gitosis-admin/gitosis.conf  #编辑gitosis-admin配置文件

添加新的git项目的信息:
[group project1]
members = zhouxiang@ZHONGDUANCP-31 tiger@xiaoyulong-ThinkCentre-XXXX
writable = project1

我们指定了project1的members,包含tiger,因此我们还需要将项目成员tiger的公钥上传到Git服务器。



六、生成客户端项目成员的公钥[开发机2,tiger@xiaoyulong-ThinkCentre-XXXX]
[tiger@xiaoyulong-ThinkCentre-XXXX:~$] ssh-keygen -t rsa #不需要密码,一路回车就行(在本地操作)
[tiger@xiaoyulong-ThinkCentre-XXXX:~$] scp ~/.ssh/id_rsa.pub zhouxiang@ZHONGDUANCP-31:/tmp/


七、更新gitosis-admin至Git服务器[开发机1,zhouxiang@ZHONGDUANCP-31]
将开发机2的tiger用户的公钥拷贝到keydir目录下,且必须重命名为[email protected]
[zhouxiang@ZHONGDUANCP-31:~$] cp /tmp/id_rsa.pub ~/gitosis-admin.git/gitosis-export/keydir/[email protected]

[zhouxiang@ZHONGDUANCP-31~$] cd gitosis-admin

[zhouxiang@ZHONGDUANCP-31~/gitosis-admin$] git add . #记录所有操作

[zhouxiang@ZHONGDUANCP-31~/gitosis-admin$] git commit -am “xxxxx” #提交到本地仓库
[zhouxiang@ZHONGDUANCP-31~/gitosis-admin$] git push origin master #将本地仓库提交到Git服务器



八、在客户端创建项目[开发机2,tiger@xiaoyulong-ThinkCentre-XXXX]

在第五步,我们添加了新的git项目的信息,名称为project1,成员有zhouxiang、tiger。现在来创建真正的git项目,可以在开发机1(zhouxiang@ZHONGDUANCP-31),也可以在开发机2(tiger@xiaoyulong-ThinkCentre-XXXX)来创建这个git项目,我选择在开发机2(tiger@xiaoyulong-ThinkCentre-XXXX)下创建:
[tiger@xiaoyulong-ThinkCentre-XXXX:~$] mkdir ~/project1
[tiger@xiaoyulong-ThinkCentre-XXXX:~$] cd ~/project1
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git init
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] touch a.txt #创建一个空文件,这步省略的话,在git push时,会报错。后面有说明
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git add . #新增文件 留意后面有一个点
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git commit -am “初始化项目project1″

然后就到把这个项目放到git server服务器上去.
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git remote add origin john@workpc1:project1.git
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git push origin master
也可以把上面的两步合成一步
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] git push john@workpc1:project1.git master

说明:如果在执行 git push origin master 的时候,提示以下错误:
error: src refspec master does not match any.
error: failed to push some refs to 'john@workpc1:project1.git'
这是由于项目为空的原因,我们在项目目录里新创建一个文件
[tiger@xiaoyulong-ThinkCentre-XXXX:~/project1$] touch a.txt  #创建一个空文件

再经过->add -> commit -> push 就可以解决了


至此,我认为Git服务器搭可正常工作了,相信您可以创建自己的git项目了。用一张图简单表示git服务器的网络拓扑及其成员之前的关系:




九、其它

1. 什么是Gitosis

git作为一个分布式的版本控制系统,其实client端和server的差别并不是很大,只是server端往往没有工作拷贝的需求,所以往往是 一个裸库(bare repository),往往文件夹的名称为xxxx.git ,裸库的内容其实就相当于客户端某个工程下的.git目录了.

使用git的时候,一般和服务器通讯使用的是ssh协议,用ssh的主要优点是速度快(传输前数据会先压缩,比HTTP快),安全,方便读写。 客户端通过ssh访问服务器端的验证方式一般有两种,一种是用户名密码的方式,一种是使用公私钥认证的方式. 使用公私钥的方式比较方便,无需每次登录输入密码。 某个受信任的客户端的公钥会被设置在服务器端的 ~/.ssh/authorized_keys文件中,有关此文件的格式可以参见 sshd的用户手册 man sshd . authorized_keys有个比较厉害的功能是 支持 command参数,使得每次用户使用此公钥进行验证的时候执行此后面的命令.这样就可以做一些逻辑处理了.

一般git库的管理需要权限控制,如何方便简单的进行库的权限管理呢? authorized_keys是一个思路,指定特定command参数,每次验证好用户后首先执行相关逻辑,检测当前用户是否具有某个权限。 所以便有了gitosis,与其说gitosis是一个git权限管理系统,还不如说它是一个authorized_keys文件管理器.
gitosis的设计思路很巧妙,开天辟地之初,需要一个gitosis的管理员,所以你就在你的客户端机器上生成一对公私钥,将公钥拷贝到git服务器 端的/tmp/下,然后通过gitosis在git用户home目录下运行如下初始化命令,后面的公钥便是gitosis首个管理员的公钥

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

执行之后,home目录下出现一个repositories的目录,目录下存在一个gitosis-admin.git的git库. 其实gitosis就是通过这个git库来管理所有git库的访问权限的。
在刚才你的客户端机器上clone出这个库,因为你刚刚用你的公钥初始化了gitosis,所以你有权限访问服务器端的库(其实你可以在服务器端看看 authorized_keys文件便知道原因了)。 这个gitosis-admin的库中存在一个gitosis.conf和一个keydir的目录,gitosis.conf文件就是权限配置的地 方,keydir目录下存放的是所有客户端的公钥,公钥名字必须和配置文件中的member名字对应.至于gitosis.conf的语法及用法可以去查 看帮助。
当修改完配置和添加好需要添加的公钥之后,提交并push到git服务器,这个库的存在hook,当提交后,会根据新的配置和公钥去更新服务器端git用 户的authorized_keys,以便加入新用户的公钥,用于权限控制命令,以及在裸库的目录下提取出新的gitosis.conf文件。


2. git init --bare和git init的区别

git init --bare
初始化的版本库,只生成版本历史记录文件/文件夹,不包含实际项目源文件的拷贝。因此,一般在git服务器上创建新的仓库时,使用此命令。

git init
初始化的版本库,生成.git目录以及在该目录下的版本历史记录文件/文件夹,且当前目录就是git的work目录,可以进行任何git操作(add、commit、push等)。因此,一般在git客户端初始化并上传新的仓库时,使用此命令。

猜你喜欢

转载自blog.csdn.net/zhouxiangbai/article/details/78851276