当前位置: 首页 > 嵌入式Linux > 正文

嵌入式之行(7):使用CVS

说明:

笔者对于CVS的使用仅仅限于个人的(即没有团队)、本机的、浅层的使用。下面的例子中仅仅是为了说明问题,在实际应用中所用到的不外那么几个命令:importcheckoutupdate等等。

1、安装及配置

(1)、安装

安装过程似乎不用说也可以吧?我所用的Red Flag系统已经安装好了,但FC10上没有安装,可以这样:

# yum install xinetd

按提示进行安装就可以了。

 

(2)、添加用户

任何一个开发团队使用CVS都应当添加CVS组以及几个CVS用户。但本文没有使用这种方式,因为在一个人使用的情况下,添加组、用户略显麻烦,这告诉我们遇到具体的情况要具体分析并制定符合实际的方案。

如果实在想这样做,添加组和用户也十分easy,如下:

# groupadd cvs                                     // cvs

# useradd cvs_latelee                          // cvs用户

# usermod –g cvs cvs_latelee                     // 添加cvs_lateleecvs组中

# passwd cvs_latelee                           // 修改密码

 

(3)创建CVS仓库目录

目录名称可以为cvs_rootcvs_home或者其它有意义的名称。可以在自己的家目录创建,也可以在系统的/目录下创建,如果是个人使用,可以以root权限将这些目录的权限修改为自己的,如果是团队使用,可以将仓库目录的属性修改为0774

因为在/目录中,普通用户是不能创建目录的,所以必须以root身份来创建:

# cd /

# mkdir cvs_home

# chown –R latelee:latelee cvs_home

对于latelee:latelee前一个是指用户,后一个是指用户组,也可以指定为cvs组。当然,在自己的家目录下就不存在这种问题了。

 

(4)服务器配置

CVS配置文件在/etc/xinetd.d/cvs文件中(不保证所有的Linux系统中都是此路径),以root身份来修改:

# default: off

# description: The CVS service can record the history of your source

#              files. CVS stores all the versions of a file in a single

#              file in a clever way that only stores the differences

#              between versions.

service cvspserver

{

      disable                  = no

      port               = 2401

      socket_type          = stream

      protocol        = tcp

      wait               = no

      user                     = latelee       // 用户

      passenv                = PATH

      server                   = /usr/bin/cvs

      env                = HOME=/var/cvs

      server_args        = -f –allow-root=/cvs_home pserver    // 目录

#    bind               = 127.0.0.1

}

user指定了用户,server_args指定了仓库目录(/cvs_home)以及访问方式(pserver)

 

(5)启动服务

命令如下:

#service xinetd restart

可以看一下2401端口是否处于监听状态:

# netstat -ln | grep 2401

tcp        0      0 0.0.0.0:2401                0.0.0.0:*                   LISTEN

fedora中可以让xinetd开机自动启动。

 

(6)、初始化服务器

初始化服务器有两种方式,一是在终端export CVSROOT环境变量是使用在系统中初始化环境变量,前者只在一个终端有效,后者比较方便。在自己家目录的.bashrc文件最后添加:

CVSROOT=/cvs_home

export CVSROOT

注意:这里的家目录是指你所用的用户目录,比如有人喜欢使用root,那么就要在/root/.bashrc文件添加了。

CVS初始化命令,普通用户与root用户都可执行,但最好是使用你所用的用户来执行该命令:

$ cvs init

初始化成功,会在/cvs_home目录生成一个CVSROOT目录。里面有许多文件,是与CVS相关的。不用理会也行。

、使用例子

注意:如果设置了CVSROOT环境变量,则输入cvs命令时可以不指定仓库目录。此处设置了在.bashrc中环境变量CVSROOT=/cvs_home

 

(1)、常用

检入(import),这里没有-m选项,所以会出现默认的编辑器VI,可以在里面写一些有关的信息。

[latelee@localhost thread]$ cvs import thread thread_project ver_0-1

N thread/thread.cpp  

N thread/thread.h

N thread/main.cpp

N thread/Makefile

 

No conflicts created by this import

 

没有check out,不能update

[latelee@localhost thread]$ cvs update

cvs update: in directory .:

cvs [update aborted]: there is no version here; run ‘cvs checkout’ first

 

check out时,会在当前目录下创建该工程目录,注意:我们本来的目录是/home/latelee/linux-c/thread/,之后则变为:/home/latelee/linux-c/thread/thread,当然,也可以在别的目录下check out

[latelee@localhost thread]$ cvs co thread

cvs checkout: Updating thread

U thread/Makefile

U thread/main.cpp

U thread/thread.cpp

U thread/thread.h

 

可以看一下某些文件的状态:

[latelee@localhost thread]$ cvs status -v main.cpp

=========================================================

File: main.cpp          Status: Locally Modified

 

   Working revision:    1.1.1.1 Thu Apr 22 04:43:21 2010

   Repository revision: 1.1.1.1 /cvs_home/thread/main.cpp,v

   Sticky Tag:          (none)

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        ver_0-1                         (revision: 1.1.1.1)

        thread_project                  (branch: 1.1.1)

修改某些文件了,但还没有提交到仓库,更新会出现:

[latelee@localhost thread]$ cvs update

cvs update: Updating .

M main.cpp

M thread.cpp

M thread.h

? thread

其中M代表当前目录下已修改了的文件,这里有三个,?是说thread在仓库里没有找到,因为我检入库时是没有这个文件的,这里是编译后生成的可执行文件,一般来说,在仓库里的基本上都是源代码和说明文档等等,在这里,我不将编译生成的结果检入库。好,那么就检入库:

[latelee@localhost thread]$ cvs commit

cvs commit: Examining .

Checking in main.cpp;

/cvs_home/thread/main.cpp,v  <–  main.cpp

new revision: 1.2; previous revision: 1.1

done

Checking in thread.cpp;

/cvs_home/thread/thread.cpp,v  <–  thread.cpp

new revision: 1.2; previous revision: 1.1

done

Checking in thread.h;

/cvs_home/thread/thread.h,v  <–  thread.h

new revision: 1.2; previous revision: 1.1

done

当输入cvs commit时,我没有带参数(这里的参数是指文件),则代表目录下所有的文件都入库,这里有三个。回车后,将会出现文本编辑器(此处是VI,当然也可以修改,如-e emacs),在VI中记录修改日志。保存退出,即可。

 

下面再check out这个工程,在上一目录中执行cvs co thread,它不再是check out,而是update,因为当前目录已有了thread目录了。

[latelee@localhost thread]$ ls

main.cpp  Makefile  thread  thread.cpp  thread.h //注意,第三个文件thread其实是我们的工程目录

[latelee@localhost thread]$ cvs co thread

cvs checkout: Updating thread 

 

我们再看一下main.cpp的状态:

[latelee@localhost thread]$ cvs status -v main.cpp

=========================================================

File: main.cpp          Status: Up-to-date

 

   Working revision:    1.2     Thu Apr 22 04:57:48 2010

   Repository revision: 1.2     /cvs_home/thread/main.cpp,v

   Sticky Tag:          (none)

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        ver_0-1                         (revision: 1.1.1.1)

        thread_project                  (branch: 1.1.1)

可以看到,版本已经变化了。

 

(2)、标记

我们创建一个标记:

[latelee@localhost thread]$ cvs tag pre_alpha_0-1

cvs tag: Tagging .

T Makefile

T main.cpp

T thread.cpp

T thread.h

标记名为pre_alpha_0-1,这个名称可以随意修改。

 

我也不知道下面这个是什么意思。在书上的

[latelee@localhost thread]$ cvs update -d -r pre_alpha_0-1

cvs update: Updating .

U Makefile

U main.cpp

U thread.cpp

U thread.h

 

再看一下main.cpp的状态:

[latelee@localhost thread]$ cvs status -v main.cpp

=========================================================

File: main.cpp          Status: Up-to-date

 

   Working revision:    1.2     Thu Apr 22 05:02:20 2010

   Repository revision: 1.2     /cvs_home/thread/main.cpp,v

   Sticky Tag:          pre_alpha_0-1 (revision: 1.2)

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        pre_alpha_0-1                   (revision: 1.2)

        ver_0-1                         (revision: 1.1.1.1)

        thread_project                  (branch: 1.1.1)

 

改名:

[latelee@localhost thread]$ cvs tag -r pre_alpha_0-1 pre_alpha_0-1_branch_root

cvs tag: Tagging .

T Makefile   

T main.cpp

T thread.cpp

T thread.h

[latelee@localhost thread]$ cvs status -v main.cpp

=========================================================

File: main.cpp          Status: Up-to-date

 

   Working revision:    1.2     Thu Apr 22 05:02:20 2010

   Repository revision: 1.2     /cvs_home/thread/main.cpp,v

   Sticky Tag:          pre_alpha_0-1 (revision: 1.2)

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        pre_alpha_0-1_branch_root       (revision: 1.2)

        pre_alpha_0-1                   (revision: 1.2)

        ver_0-1                         (revision: 1.1.1.1)

        thread_project                  (branch: 1.1.1)

 

可见,版本1.2有两个标记,下面我们删除一个:

[latelee@localhost thread]$ cvs tag -d pre_alpha_0-1

cvs tag: Untagging .

D Makefile

D main.cpp

D thread.cpp

D thread.h

[latelee@localhost thread]$ cvs status -v main.cpp

cvs status: main.cpp is no longer in the repository

=========================================================

File: main.cpp          Status: Entry Invalid

 

   Working revision:    1.2     Thu Apr 22 05:02:20 2010

   Repository revision: No revision control file

   Sticky Tag:          pre_alpha_0-1 – MISSING from RCS file!

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        pre_alpha_0-1_branch_root       (revision: 1.2)

        ver_0-1                         (revision: 1.1.1.1)

        thread_project                  (branch: 1.1.1)

是不是有点麻烦?更名过程就是将旧标记贴上新的标记,再将旧标记删除。

 

(3)分支测试:

在上面的基础上,添加一个分支:

[latelee@localhost thread]$ cvs rtag -r pre_alpha_0-1_branch_root -b pre_alpha_0-1_branch thread

cvs rtag: Tagging thread

[latelee@localhost thread]$ cvs status -v main.cpp

cvs status: main.cpp is no longer in the repository

=========================================================

File: main.cpp          Status: Entry Invalid

 

   Working revision:    1.2     Thu Apr 22 05:02:20 2010

   Repository revision: No revision control file

   Sticky Tag:          pre_alpha_0-1 – MISSING from RCS file!

   Sticky Date:         (none)

   Sticky Options:      (none)

 

   Existing Tags:

        pre_alpha_0-1_branch            (branch: 1.2.2)

        pre_alpha_0-1_branch_root       (revision: 1.2)

        ver_0-1                         (revision: 1.1.1.1)

        thread_project

 

回到上一目录,将一个分支check out出来:

[latelee@localhost thread]$ cvs co -r pre_alpha_0-1_branch thread

cvs checkout: Updating thread

看一下main.cpp的状态:

[latelee@localhost thread]$ cvs status main.cpp

=========================================================

File: main.cpp          Status: Up-to-date

 

   Working revision:    1.2     Thu Apr 22 05:34:38 2010

   Repository revision: 1.2     /cvs_home/thread/main.cpp,v

   Sticky Tag:          pre_alpha_0-1_branch (branch: 1.2.2)

   Sticky Date:         (none)

   Sticky Options:      (none)

 

注意:在实际开发中,分支最好不要跟主干的目录混在一起。

 

(4)远程访问(检出代码)

下面这种方法只适合一个终端,因为export只在一个终端有效。

[latelee@FightNow latelee]$ export CVSROOT=:pserver:latelee@192.168.1.13/cvsroot

[latelee@FightNow latelee]$ cvs login

Logging in to :pserver:latelee@192.168.1.13:2401/cvsroot

CVS password: (在这里输入密码)

没有错误,说明已经连接上服务器了。这里进入到一个测试目录:

[latelee@FightNow latelee]$ cd work/nfs

[latelee@FightNow nfs]$ ls

hello-arm

将代码checkout出来

[latelee@FightNow nfs]$ cvs co camera-server

cvs checkout: Updating camera-server

U camera-server/Makefile

U camera-server/video/utils.h

U camera-server/video/v4l2uvc.h

[latelee@FightNow nfs]$ cvs co camera-client

cvs checkout: Updating camera-client

U camera-client/Makefile

U camera-client/main.c

U camera-client/my-types.h

U camera-client/my_udp.c

U camera-client/v4l2/v4l2uvc.h

目录中多了两个文件夹。

[latelee@FightNow nfs]$ ls

camera-client  camera-server  hello-arm

[latelee@FightNow nfs]$

 

上述例子中没有讲如何在开发过程中添加或删除文件(或目录),下面讲一下。在thread工程中添加了fork.cpp文件。

 

[latelee@51 thread]$ cvs add fork.cpp

cvs add: scheduling file `fork.cpp’ for addition

cvs add: use ‘cvs commit’ to add this file permanently

[latelee@51 thread]$ cvs commit

cvs commit: Examining .

cvs commit: Up-to-date check failed for `main.cpp’

cvs commit: Up-to-date check failed for `thread.cpp’

cvs commit: Up-to-date check failed for `thread.h’

cvs [commit aborted]: correct above errors first!

 

出错了!因为没有check out,正确的cvs commit显示如下:

[latelee@51 thread]$ cvs commit

cvs commit: Examining .

RCS file: /cvs_home/thread/fork.cpp,v

done

Checking in fork.cpp;

/cvs_home/thread/fork.cpp,v  <–  fork.cpp

initial revision: 1.1

done

删除一个文件(fork.cpp)过程如下:

[latelee@51 thread]$ rm fork.cpp

[latelee@51 thread]$ cvs remove fork.cpp

cvs remove: scheduling `fork.cpp’ for removal

cvs remove: use ‘cvs commit’ to remove this file permanently

[latelee@51 thread]$ cvs commit

cvs commit: Examining .

Removing fork.cpp;

/cvs_home/thread/fork.cpp,v  <–  fork.cpp

new revision: delete; previous revision: 1.1

done 

至于目录的添加删除,就不显示了。

 

又:本文的例子不是同一时间、同一台PC上完成的,但对于使用CVS来说,是没有关系的。

本文固定链接: http://www.latelee.org/embedded-linux/learning-elinux-7-cvs.html

如无特别说明,迟思堂工作室文章均为原创,转载请注明: 嵌入式之行(7):使用CVS | 迟思堂工作室

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter