对于今天越来越受欢迎的Git,相信做开发的朋友都基本有所耳闻。它最大的便利就是分布式的开发库,让使用git作为源码管理库的开发者可以在本地提交代码的修改而不用提交到远程的库,同时需要和团队协作、同步代码时,也仅仅是多一条指令而已。如果你想了解git的全貌,可以看《Progit》,他有中文版,貌似没有维护到最近的,需要的可以googleit。
Git使用者的日常流程:
1、从gitserver远程库上clone一个副本到本地库(gitclone),
2、本地开发,然后本地提交修改(gitadd改动的文件;gitcommit提交);无限循环这个周期。
3、第3、4步是和服务器同步。先把远程库的改动抓下来,本地解决版本合并有问题的地方(gitpull)
4、然后把合并后的本地代码库提交到远程库(gitpush);按你的团队计划,也许每天一次。
5、另外,user除了与服务器同步外,也可以与其他协作者直接同步;如上图左和中间的头像标示。
以下介绍的,是使用gitolite管理gitserver,进行源代码的团队协作。本文的读者最好有linux的经验。
Gitolite介绍
其实,每一个Git库只需要–bare-shared就可以简单实现类似共享代码库服务器的功能,在git的世界,代码都是自由share的,每个人扮演的角色,和linux系统赋予这个用户的权限有关。但如果采用这种SSHauthorized_keys的方式,直接系统通过shell进行gitclone的方法,会缺少了一项很必须的权限管理——每个用户对某个repository中所有项目均拥有完整的读写权限(可通过linux系统的权限设定,但依然麻烦),如果在一些大项目,涉及到多种角色权限,并要指定访问路径时,直接管理authorized_keys的方式,就显得力不从心,试想一下如果你要管理超过1000号人的authorized_keys?
Gitolite安装步骤
gitolite的安装其实非常简单,官方网址上给出的quickinstall仅仅4步,需要的可以看这里。另外,gitolite也有多种安装模式,例如
1、使用安装包自动安装;apt-getinstall/yuminstall
2、使用root帐号手动安装为全局应用,这样每一个服务器上的用户都可以开设代码仓库;
3、或手动在指定的普通用户帐号下安装。
以下的安装使用上述第三种方法,这样会最小程度“污染”你的server运行环境,并且能随时更新到最新版本的gitolite。
安装环境
1、假设我们现在有两台机器,serverandclient;
2、我们指定管理gitserver的管理员叫sunny;
3、并有一个普通的clientuser帐号jacob
下面的步骤,只是step-by-step的how-to,没有太多的why,如果要详细研究,请看gitolite的官方文档,或蒋鑫的编著《git权威指南》。
另外,gitolite的安装,会依赖git,如果你的服务器上还没安装git套件,请先自行安装。
fordeb系:apt-getinstallgit-core或apt-getinstallgit
forRH系:yuminstallgit
步骤
root@server#adduser--system--shell/bin/bash--groupgituser2.给用户gituser设定密码,在SSH公钥建立后可以把这个密码禁掉
root@server#passwdgituser3.管理员在本地创建一个sshkeypair对
sunny@client$ssh-keygen如果你不想影响本机现有的一些keypair,可用-f参数
sunny@client$ssh-keygen-fsunny_key4.推送管理员的公钥到remoteserver
sunny@client$ssh-copy-id-i~/.ssh/id_rsa.pubgituser@server如果是用带有-f参数生成的,注意这里要指向正确的文件
sunny@client$sshgituser@server6.执行
gituser@server$mv.ssh/authorized_keyssunny.pub7.下载源码安装,或自动安装;推荐源码安装,也就三个命令;如install时候提示git版本tooold,可以下载旧版本的gitolite,例如2.1的,或者1.5.9之后的,如需要下载旧版本,点击这里
gituser@server$gitclonegit://github.com/sitaramc/gitolite#下载源码gituser@server$gitolite/src/gl-system-install#如果提示gittooold,请下载旧版本的gitolitegituser@server$gl-setup-q~/sunny.pub执行gl-setup时几点注意:
gl-setup要放到$PATH,请确定~/bin已放在PATH变量,如没有,请编辑~/.bashrc,最后面添加
PATH=~/bin:$PATH并执行以下命令生效:
sh~/.bashrc旧版本的gl-setup,没有-q参数,如使用旧版本gitolite(例如1.5.9),直接赋参数即可
gituser@server$gl-setup~/sunny.pub8.直接package管理工具安装(如不需要的请跳过)
Gitolite的管理及权限设定
gitolite的管理,包括用户管理和代码库管理,都是通过操作一个指定名称的库来实现:gitolite-admin仓库。因此gitolite的管理员sunny需要先把这个库抓到本地,进行必要的配置后,再push到remote服务器,让设定生效:
抓取gitolite-admin仓库到本地
sunny@client$gitclonegituser@server:gitolite-adminsunny@client$cdgitolite-admin1.新增用户
先要获取待加用户(jacob)的pubkey,如果不知道怎么获取,请让jacob参考上述第三步生成他自己的id_rsa.pub
sunny把用户jacob的pubkey,放到gitolite-admin/keydir目录,并重命名为jacob.pub
sunny@client:~/gitolite-admin$gitadd.sunny@client:~/gitolite-admin$gitcommit-m"addjacobpubkey"sunny@client:~/gitolite-admin$gitpush此时jacob已增加到gitolite,但是,除了系统自带的testing库外,他操作不了其他的库
2.新增并设定代码库
现在要在remoteserver新建一个代码仓proj,依然是对gitolite-admin进行配置
编辑gitolite-admin/conf/gitolite.conf,仿照以后的库的格式,添加:
repoproj_a#这里设定是新增库的名称RW+=sunny#R是读权限,W是写权限,+是包括“强制更新一个分支,删除分支和更新一个Tag”的权限RW=jacob#设定RW权限的人执行add,commmit,push进行推送,即可
sunny@client:~/gitolite-admin$gitadd.sunny@client:~/gitolite-admin$gitcommit-m"addanewrepo"sunny@client:~/gitolite-admin$gitpushgitolite.conf的格式其实有相当多的复杂配置(详情请看官方手册),一般来说,象以下这样的,已够几个人的开放型小团队使用,例如:
@proj_a=sunnyjacob#@proj_a是分组命名,分组用@表示,可以在后面引用分组@proj_b=sunnytaylorjean#如果有多个用户,用空格隔开@admins=sunny@qa=elapseflora@engineers=sunnyjacobtaylorjean@staff=@admins@qa@engineers#分组可以被引用
repogitolite-admin#这个是gitolite的管理仓库,sunny是指定可以对其进行操作的管理员RW+=sunny
repoproj_aRW+=@adminsRW=@proj_aelapse
repoproj_bRW+=sunnyRW=@engineersfloraRrefs/tags/=@qa#这里设定的,是QA这个组,对refs/tags/开头的路径的文件只有读权限
repotestingRW+=@stall
3.普通用户签出操作
例如jacob要把代码库checkout出来,本地修改,然后再和remote库的代码进行版本合并。这些操作是纯粹的git操作了,团队的日常开发流程,正是这样子开展。请参阅本文一开头的那副git工作流程图,以下是几种不同情况的用户签出。
把remote库抓取下来,然后才开始修改
jacob@client:~$gitclonegituser@server:proj_a#项目默认放到proj_a目录或jacob@client:~$gitclonegituser@server:proj_amy_proj_a#项目被下载到my_proj_a目录下jacob本地已有一个现成的项目proj_a正在开发,并用git在管理着,现在想share到这个项目到proj_a
jacob@client:~$cdproj_ajacob@client:~/proj_a$gitpush--allgituser@myserver:proj_a#推送到remoteserver如果希望在当前目录使用一个已有的库(即合并项目),那样比较复杂,要采取非常规方法,替换.git/config文件才行
4.删除用户
管理员在本地,删除了gitolite-admin/keydir目录下对应的用户pubkey,然后执行git的rm操作,再commit,push推送,即可
sunny@client:~/gitolite-admin$rm-fkeydir/jacob.pubsunny@client:~/gitolite-admin$gitrmkeydir/jacob.pubsunny@client:~/gitolite-admin$gitcommit-m"deleteauser"sunny@client:~/gitolite-admin$gitpush5.删除代码库
gitolite没有删除repo的代码,如要删除repo,管理员要分两步走:
root@server:/home/gituser/repositories$rm-Rfproj_a.git#库对应proj_a的目录,带.git结尾6.修改代码库的名字
改名,也是分两步,和上面执行删除的顺序反过来,
先用gituser帐号或root帐号进入服务器,cdrepositories,执行移动
root@server:/home/gituser/repositories$mvproj_a.gitproj_b.git回到客户端,修改conf/gitolite.conf,把old-name的地方修改为new-name,然后add,commit并push
7.列出本人拥有权限的库
jacob@client:sshgituser@server例如会返回:
hellojacob,thegitoliteversionhereis1.5.4-2+squeeze1~bpo50+1(Debian)thegitoliteconfiggivesyouthefollowingaccess:RWproj_a@R@WtestingConnectionto192.168.0.101closed.上面列出的proj_a和testing,就是用户jacob所能操作的库,并都拥有R和W的权限。
附记
如果你对ssh很熟悉的话,gitolite的安装与使用,那是问题不大的。若你对ssh和git两者都不十分了解,使用起来可能会不算顺利。本文是gitolite配置使用的step-by-step,对于配置文件gitolite.conf,以及gitolite所支持的强大权限管理、路径正则匹配、user命名空间、和gitweb整合、委托管理以及代码库镜像备份等等,都没有叙述。如果你需要这些进阶知识,推荐看官方的帮助文档,以及《gitolite构建git服务器一文》。