一,什么是CVS?
Concurrent Versions System 版本控制系统
二,CVS主要面对什么情况
1.修改代码时不小心产生了一些bug但当时没有发现,等发现后又需要回到旧版本做修改
2.成员之间在没有协商好前很容易覆盖文件,一些编辑器如Emacs可保证同一个文件不会两次修改,但使用不同的编辑器保护就没有作用了。
3.每一个新版本就是一个新文件生成,但只记录此版本与上个版本之间的变化部分,而不是重新复制占用过多空间。
4.版本间的不同部分保留在一个文件中。
三,CVS的几个重要概念
1.仓库(repcsitory)
存储全部的版本控制下的文件的备份,通常不能直接访问必须通过cvs命令拷贝到本地修改后在同步回仓库。仓库和工作目录是隔离的。
2.版本(revision)
每个文件都独立的版本系统,如下
file1_版本1----file1_版本2----file1_版本3
file2_版本1----file2_版本2----file2_版本3
3.分支(branch)
好像file1+file2实现了一个功能成为整个项目的一个分支
修改一个分支不会影响到其他分支
4.冲突(conflct)
完全的纯文本冲突无法被cvs解决,比如user1修改x=1后上传,而user2在之后的一分钟修改同一行代码成x=2后上传,那么user1依然认为x=1但当user1调用x函数计算x+y时发现返回截获增加了1。这种冲突只能由用户自身沟通解决。
四,CVS如何解决上述问题的
1.采用开发者隔离,每个人在修改代码前需要先下载代码到本地的工作目录(workspace),修改后在上传
2.采用策略是copy----modify----merge
拷贝到本地----修改代码---上传和以前版本合并内容
下面我们来看看cvs服务器的建立过程
1.创建用户和组
我们的想法是能使用cvs服务器的都在cvs这个组中,cvsroot成为这个组的小管理员,我们在位每个编程人员设定自己喜欢的用户名来登录cvs服务器.
我先建立cvsroot用户和组,并直接把cvsroot加入到cvs组中
![](https://i-blog.csdnimg.cn/blog_migrate/8d5bd49779cb873437af2f9c8799be53.png)
我在为一个编程人员创建他喜欢的账户
-g是直接把fish加入到cvs组中
-M是在建立fish时不产生家目录
![](https://i-blog.csdnimg.cn/blog_migrate/717861ec075c8d8602cc0fed05a2d0a5.png)
2.查看端口配置情况,看到2401在tcp和udp协议上都有即可
![](https://i-blog.csdnimg.cn/blog_migrate/13b91ba229937d9bc40d35396139175d.png)
3.修改启动脚本
vi /etc/xinetd.d/cvs
因为cvs属于xinetd管理,所以只要重启xinetd服务即可重启cvs
![](https://i-blog.csdnimg.cn/blog_migrate/241131df9343b6806f96f82fc25835d5.png)
4.重新启动服务
![](https://i-blog.csdnimg.cn/blog_migrate/076b03c4951680e3e4577001e039549b.png)
5.初始化cvs服务
![](https://i-blog.csdnimg.cn/blog_migrate/409f0a92801630f49ec61ec5a647e7a4.png)
6.修改环境变量让系统启动时就可以认识cvs的仓库
vi /etc/profile
![](https://i-blog.csdnimg.cn/blog_migrate/06c8e42f39de1fff14fe21dd435a0b6b.png)
7.无需重启立刻更新环境变量
![](https://i-blog.csdnimg.cn/blog_migrate/230c9023d268ecfec9903af4973fd758.png)
8.为了能让开发人员都能使用仓库注意给权限
![](https://i-blog.csdnimg.cn/blog_migrate/f296b99c83d2f4c2f81be3ead758f3e3.png)
9.默认情况下cvs使用的是系统用户登录的,也就是/etc/passwd里的用户,为了考虑系统安全,我们可以使用独立的用户管理将用户名和密码保存在/home/cvsroot/CVSROOT/passwd文件中,这样做的好处是你修改了系统账户的权利在cvs中对应的账户也跟着改变,并且cvs账户的密码和系统账户的密码可以不一致,这样当你登录cvs后你输入cvs密码,而有效保护了对应的系统账户密码,因为cvs并没有提供类似可以把明文密码转成密文(MD5)的命令所以借用了apache服务的命令来做的.
创建cvs独立passwd命令为 htpasswd -c passwd cvsroot (/home/cvsroot/CVSROOT下执行)
当然你也可以映射其他用户,注意的是必须保证/home/cvsroot/CVSROOT有权限能被其他用户所访问
当然你也可以映射其他用户,注意的是必须保证/home/cvsroot/CVSROOT有权限能被其他用户所访问
![](https://i-blog.csdnimg.cn/blog_migrate/d51287540a01ab6adb9691a8bea6d0d4.png)
看看../CVSROOT/passwd文件的样子
![](https://i-blog.csdnimg.cn/blog_migrate/3a238a81340caadc7d64dbb83a9708ce.png)
10.现在有个新问题就是如果/home/cvsroot/CVSROOT/passwd文件中没有这个用户,cvs依然会去询问系统的/etc/passwd是否有这个用户及请求验证,那这样最后问来问去又需要输入系统的账户和密码还是有风险.所以我干脆就算在CVSROOT/passwd下找不到这个用户也不去问系统有没有这个用户.
vi /home/cvsroot/CVSROOT/config
![](https://i-blog.csdnimg.cn/blog_migrate/6bd7e65658fcd262802f3f664ae1536e.png)
此时我们可以在/etc/passwd和/etc/shadow里吧关于cvsroot和fish的信息删除掉.我已经悄悄的干掉他们连个了.
11.现在你可以启动cvs服务了
![](https://i-blog.csdnimg.cn/blog_migrate/f592c22e8a1625600f6a5f89ee0c8b55.png)
12.我们看看服务启动后验证一下,端口号已经开启
![](https://i-blog.csdnimg.cn/blog_migrate/7b6d5a995e01602f993f4b61ec9e4515.png)
13.现在我们就可以用刚才的fish开发账户登录测试一下了
![](https://i-blog.csdnimg.cn/blog_migrate/df8563bae88179408fa4a3a88c9d3f84.png)
14.你可以配置用户对仓库文件中的权限,readers文件记录具有"只读"权限的用户,writers文件记录拥有读写权限的用户,readers文件比writers优先,也就是说出现在readers中的用户将会是只读的,不管writers文件中是否存在该用户
********************************************
另外一种建立CVSROOT/passwd文件的方式,参考一下
groupadd cvs
useradd -g cvs -M test1
passwd test1
以后就用test1来登录cvs
useradd -g cvs -M test1
passwd test1
以后就用test1来登录cvs
cp /etc/shadow /home/cvsroot/CVSROOT/passwd
chmod 0644 /home/cvsroot/CVSROOT/passwd
vi /home/cvsroot/CVSROOT/passwd
只保留cvsroot和test1的记录,形式如下
cvsroot:$123456789:cvsroot
test1:$12345sdjkfe:test1
chmod 0644 /home/cvsroot/CVSROOT/passwd
vi /home/cvsroot/CVSROOT/passwd
只保留cvsroot和test1的记录,形式如下
cvsroot:$123456789:cvsroot
test1:$12345sdjkfe:test1
然后再系统中删除掉test1和cvsroot vi /etc/passwd和 /etc/shadow
**********************************************
期待能对开发人员之间的合作有所帮助.