假设:
cvsroot user:cvsroot home=/home2/cvsroot/cvsroot
cvs group:cvs
1:安全
#groupadd cvs
#mkdir /home2/cvsroot#注意:/home2/cvsroot为root所有
#useradd -g cvs -G cvs -d /home2/cvsroot/cvsroot cvsroot
/***未经实验**/
#mv /usr/bin/cvs /usr/bin/cvs.real
#cat > /usr/bin/cvs
#!/bin/sh
umask 2# Or whatever your site standard is.
exec /usr/bin/cvs.real ${1+"$@"}
^D
/*************/
2:多仓库
注意,我们用cvsroot仅仅是用来管理,所以,不要在它$HOME下面创建任何仓库
另外,cvsroot用户的初始环境不应该包含非空的$CVSROOT.
使用cvsroot来进行的任何管理工作都指明CVSROOT是一个好的习惯.
OK,开始给单个项目建仓库
假设有两个项目,project1,project2,希望单独存放,便于管理
#mkdir /home2/cvsroot/pro1
#mkdir /home2/cvsroot/pro2
#chown cvsroot.cvs /home2/cvsroot/pro1
#chown cvsroot.cvs /home2/cvsroot/pro2
#chmod 2775 /home2/cvsroot/pro1
#chmod 2775 /home2/cvsroot/pro2
(更高的安全要求则$chmod 2770 /home2/cvsroot/cvsroot/pro1)
OK,开始建立仓库
#su - cvsroot
$cvs -d /home2/cvsroot/pro1 init
$cvs -d /home2/cvsroot/pro2 init
$chmod 2775 /home2/cvsroot/pro1
$chmod 2775 /home2/cvsroot/pro2
修改启动文件
service cvspserver
{
disable = no
flags= REUSE
socket_type= stream
wait= no
user= root
bind= 192.168.0.1
only_from= 192.168.0.0/24
server= /usr/bin/cvs
server_args= -f --allow-root=/home2/cvsroot/pro1 --allow-root=/home2/cvsroot/pro2 pserver
log_on_failure += USERID
}
/********技巧*************/
由于xinetd的server_args长度限制,当你想运行很多的单个仓库的时候,可以这么做,
#vi /etc/xinetd.d/cvspserver
service cvspserver
{
disable= no
flags= REUSE
socket_type= stream
wait= no
user= root
bind= 192.168.0.1
only_from= 192.168.0.1.0/24
server= /home2/cvsroot/cvs.run
log_on_failure += USERID
}
:wq
然后写脚本/home2/cvsroot/cvs.run
#vi /home2/cvsroot/cvs.run
#!/bin/bash
/usr/bin/cvs -f --allow-root=/home2/cvsroot/pro1 --allow-root=/home2/cvsroot/pro2 --allow-root=/home2/cvsroot/pro3 --allow-root=/home2/cvsroot/pro4 --allow-root=/home2/cvsroot/pro5 --allow-root=/home2/cvsroot/pro6 pserver
:wq
#chmod +x /home2/cvsroot/cvs.run
#service xinetd restart
OK!
/*************************/
修改不同仓库的策略
#su - cvsroot
$export CVSROOT=/home2/cvsroot/pro1
$cvs co CVSROOT
$cd CVSROOT
$vi config
# Set this to "no" if pserver shouldn't check system users/passwords
SystemAuth=no
# Put CVS lock files in this directory rather than directly in the repository.
LockDir=/var/cache/cvs/pro1
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no
# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
# history file, or a subset as needed (ie `TMAR' logs all write operations)
LogHistory=TOFEWGCMAR
:wq
$vi loginfo
ALL (echo %{sVv}; cat) | /usr/local/viewcvs-0.9.2/loginfo-handler#SQL checkin
:wq
$cvs commit -m "auth change,log change"
OK,既然不使用系统用户验证,那么我们来创建用户
/************/
不使用系统帐号的原因是充分保证安全,避免系统帐号直接删除仓库里的文件.
虽然麻烦,但是很有必要,因为无法保证每一个程序员都对cvs操作很有经验.
在这种情况下,为每一个工程各建一个等效系统用户,此用户应该是cvs组的成员.
不必有shell.
(也可以为所有的项目建一个等效用户,私有的cvs Server完全可以这么做,甚至可以
直接使用cvsroot,呵呵,就是比较危险而已)
#adduser -g cvs -G cvs -s /bin/false -d /home2/cvsroot/pro1 -M cvspro1
/************/
创建一个LockDir(选择/var/cache是因为某些系统放在/var/lock下面有问题)
#mkdir /var/cache/cvs
#chown cvsroot.cvs /var/cache/cvs
#chmod 2775 /var/cache/cvs
#mkdir /var/cache/cvs/pro1
#chown cvspro1.cvs /var/cache/cvs/pro1
#chmod 2775 /var/cache/cvs/pro1
创建用户
先清除环境
$export CVSROOT=
$cd ~cvsroot
$rm -rf CVSROOT
直接切换到pro1的仓库下
$cd /home2/cvsroot/pro1
$cd CVSROOT
创建用户hleil
$htpasswd -c passwd hleil
修改passwd成cvs的格式
$vi passwd
hleil:svcsdasdcvjn:cvspro1
:wq
加入writers组
$echo hleil >>writers
/*****这里有一个问题**********/
如果用户hleil需要writers权限,那么,他绝对不可以出现在readers组中.
writers,readers,passwd的文件尾空行是必要的.
等效系统帐号如果不存在,将导致access failed.
cvs帐号尽量没有对应的系统帐号,如果有,确保它们的passwd不同.
/******************************/
OK了!
项目pro2同理.
3:够建模块化的工程
关于模块化,大家挂在口边也不是一天两天了,这里指的是项目的模块化,不是指具体的程序.
正常的项目开始具体实施之前,必定做好了系统分析和结构设计,当然,像打印"Hello World!"
这样的"项目"或许不用进行系统分析吧:P,所以也不用麻烦我们辛苦构建的cvs.
软件设计完成之后,各个模块应该也就出来了,在实施之前,我们需要考虑用cvs贯彻设计结果.
cvs的模块不必细化到疯狂的程度,大致按照功能划分并且兼顾工作组就可以了.同一模块必需
仅有单一工作组负责.
确定模块之后,我们来建立模块.
#su - hleil
$export CVSROOT=:pserver:hleil@192.168.0.1:/home2/cvsroot/pro1
$cvs login
$cvs co CVSROOT
假设有这样的目录结构,
pro01
libs
libs/01
libs/02
每个目录下面都有一个初始化文件init(方便import)
我们可以这样定义modules,
$vi CVSROOT/modules
pro01pro01 & libs
libs-01-d 01libs/01
libs-02 -d 02libs/02
libs-a libs-01 libs-02
:wq
$cvs commit -m "init modules"
倒入目录结构,
$cvs import -m "init checkin" pro01 init start
现在,你的三个小组可以分别工作于pro01,libs-01,libs-02,全部程序只要co pro01就行了.
简单吧:P
4:克隆
构建模块
$export CVSROOT=remote
$cvs login
$cvs co CVSROOT/modules
$cvs logout
$mv CVSROOT/modules .
$rm -rf CVSROOT
$export CVSROOT=local
$cvs login
$cvs co CVSROOT/modules
$cp modules CVSROOT/modules
$cvs commit -m "clone init modules"
研究目录结构
所有的 -a 定义的模块不需要checkout
$sed "/#/d" modules > modules.tmp
$sed "/^$/d" modules.tmp > modules.tmp2
$sed s/" "*/" "/g modules.tmp2 > modules.tmp
$cat modules.tmp|sed /-a/d >mymodules
仔细研究目录结构,以便co不含有垃圾的代码
$cp mymodules co-list
编辑co-list,不需要的注释,OK
$sed "/#/d" co-list > co-list.tmp
$cut -d " " -f 1 co-list.tmp >co-list
OK,此时的co-list就是我们所需要得所有模块
$export CVSROOT=remote
$cvs login
$for mm in $(cat co-list)
do
cvs co $mm
done
$cvs logout
$export CVSROOT=local
$cvs login
作合适的目录调整
如果modules 里面有
xxx yyy
那么,co xxx将产生xxx目录,实际应该是yyy
保留co-list.tmp以便于查证
比如:
gobj-lib -d gobj libs/gobj
co gobj 则将在本地产生(- d) gobj的目录,实际仓库中的位置是libs/gobj
可以根据co-list.tmp的内容编辑一个脚本,
$cvs import -m "cvs checkin init" modulesname init start
OK!
(