MIT OpenCourseWare
OCW Home Course List About OCW Help with OCW Feedback
搜索

Search
» 高级搜索
 课程主页
 教学大纲
 教学日程
 参考读物
 讲义
 复习
 实验
 作业
 考试
 项目
 工具
 相关资源

工具


讲义 S2:使用工具或软件

目录:

查看Daikon不变式探测器的文档。

目录设置

你必须在Athena机上你的主目录中建立一个名为6.170的目录,并为6.170课程教员赋予读此目录的访问权限。这样6.170教员就可以在Athena机上阅读并测试你的代码,而不需要为所有的Athena机使用者赋予对你的代码的访问权限。(允许除6.170教员和你本人之外的任何人访问你的~/6.170目录,或者其它保存你的6.170课程代码的目录是违反合作原则的。)6.170教员的组名称是system:6.170。

athena% mkdir ~/6.170
athena% fs sa ~/6.170 system:6.170 read

然后你应该为练习创建~/6.170/ex1,~/6.170/ex2,等等子目录。如果按照合适的顺序执行操作,所有这些子目录应该能够自动继承它们父目录的权限设置。

不把你的代码放到线上相应的位置将导致我们无法收集你的问题设置信息,这将给你的助教带来麻烦,并导致你的成绩降低。

就算你使用你自己的个人计算机来进行6.170问题设置中的编码,你的代码仍应在Athena上面运行。因此,为了测试和打分,你必须把你的源代码和相关文件放置到Athena机上。

在开始最后一个团队项目后,你将得到一个小组存储空间(locker)。你可以对它赋予合适的权限,以允许你的团队成员访问你的文件。之后你将得到关于这个更多的信息。

返回顶部

使用Java™

Athena机上可以使用Sun Microsystems的Java™ Development Kit (JDK),你可以使用它来编码解决6.170课程的问题。在开始使用Athena机上的Java™之前,你需要执行一些基本的安装步骤。

初始安装

你需要将6.170和Java™ lockers绑定起来,同时设置CLASSPATH使之可用。我们提供了一个能够自动编辑你的点文件的脚本,但是你也可以选择手动完成这些改变。

返回顶部

使用安装助手脚本

在你的Athena提示行中输入以下命令:

add 6.170
student-setup.pl

如果看到“6.170 setup complete”消息则说明安装完成。你必须重新登陆以使改动生效。如果你看到错误消息,请与课程教员联系以获得帮助。(最好的办法是在上班时间访问一个实验助理或者在6.170 zephyr实例上寻求帮助。)

返回顶部

安装手册

这部分描述了进行初始安装所需要执行的步骤。如果你使用了上面提到的帮助脚本,那么你可以跳过这部分。但是如果你想要自己完成点文件的编辑,或者想知道到底进行了哪些改变,这部分的内容将是非常有用的。

你需要将6.170和Java™ lockers绑定起来。6.170 locker中包含讲义的副本,在完成你的课程问题时需要用到的代码库,以及一些库的源代码。“java”locker中包括Java™的编译器javac和它的解释器java。

要让这些lockers在登陆Athena机时自动绑定,在你的环境文件中加入以下几行:

 

add 6.170 add -f java_v1.3.0

这些将在你下次登陆Athena机时生效。要让它们立刻生效,你也可以在Athena提示行中输入相同的行。一旦完成这些locker的绑定,你就可以通过/mit/6.170目录访问6.170 locker了。

在开始使用Java™之前,你还需要设置你的CLASSPATH环境使之可用。在你的.environment文件中加入以下几行:

setenv CLASSPATHLIB `perl -e 'print join(":", @ARGV);' /mit/6.170/lib/*.jar` setenv CLASSPATH /mit/${USER}/6.170:${CLASSPATHLIB} setenv RTJAR /mit/java_v1.3.0/jre/lib/rt.jar

说明:

  • CLASSPATH:Java™在搜索用来编译或运行的类时需要用到的变量。我们定义这个来包含所有你编写的6.170课程的代码(/mit/$USER/6.170 部分),以及教员提供的编译完成了的代码(${CLASSPATHLIB})。
  • CLASSPATHLIB:包括6.170课程提供的类库。它并不直接被Java™使用,但是在你的环境中它确实非常有用。(注意外部引号是反引号,下一个内部引号是单引号,而内部引用是双引号。)
  • RTJAR:包括了标准Java™类,例如java.lang.Object。正常情况下你不需要使用这个变量,但是如果使用jikes编译器而不是javac,你将需要它。

请确认你所做的编辑是正确的,如果没有正确的设置你的CLASSPATH,你将无法访问6.170课程提供的类。

返回顶部

编写和编译代码

要编写Java™代码,你需要从编写一个Java™源文件开始。Java源文件名通常有一个“.java”扩展名。源文件只是文本文件,你可以使用Emacs或者你喜欢的编辑器来创建并编辑它们。

在运行之前,你必须先编译你的源代码。Javac编译器可以用来将Java™程序转换为字节码的形式,保存在一个类文件中。可以通过它们的.class扩展名来分辨类文件。接着类文件中的字节码就可以被Java™解释器执行了。

更多关于javac、Java™、以及其它JDK中工具的在线文档可以通过Sun's Java页面找到(http://www.sun.com/java)。

一个Java™程序由一个或多个包组成,每个包定义了一组相关的抽象。每个包由一个或多个类组成。每个类由一个源文件生成,并实现一个抽象。

通过javac,一个或多个源文件可以被编译成能够被解释器执行的类文件。至少要有一个类定义一个名为“main”的方法,它将作为程序执行的入口。一旦完成所有源文件的编译,就可以使用Java™解释器java来运行程序了。执行下面一行命令:

javac [options] file1.Java file2.Java...

这将对每个指定的源文件生成类文件file1.class、file2.class等等。在Athena提示行中输入“man javac”可以获得更多关于javac选项的信息。你应该总是使用-g选项,这将提供改良的调试输入。

一旦将你的代码编译成为类文件,你就能够使用Java™解释器java来执行它们了。使用下面命令:

java options classname

这将执行classname指示的类。这个类必须在你当前的CLASSPATH中存在,或者你可以使用-classpath选项来指定另一个CLASSPATH。你要执行的类中也必须包含之前讨论到的“main”方法。如果你要运行一个不包含在默认包中的类,你必须指定完整的类名,例如,使用:

java ps1.Test

来运行ps1包中的Test类的main方法。要获得所有Java选项的完整描述,在Athena提示行中输入 -help。

返回顶部

有用的Java™站点

返回顶部

使用Emacs编辑Java™代码

6.170教员们已经对Emacs进行了一系列定制,使得在它上面进行Java™代码的编辑变得更容易一些。要使用这些定制,在你的.emacs文件中加入下列行(或者在你的主目录创建一个包含下列行的.emacs文件,如果你没有一个.emacs文件的话):

(load "/mit/6.170/etc/emacs/6170.el")

这将导致以下改变:

  • 按下RET(返回)键不只是插入新的一行,同时还对下一行进行缩进。而C-j只是插入新的一行。
  • 按下C-c C-c将保存并编译当前程序。如果当前目录没有一个makefile,则Java™文件的默认执行命令是:javac -g *.java。
  • 按下C-h f (助记:“help for function”)将运行jdk-lookup,它展示JDK中关于Java™包、类、方法或者域的文档。
  • 按C-c C-r下会将选择的区域注释出来,而按下C-u C-c C-r将解除该区域注释(在Emacs中你可以通过移动到一点,按下C-SPC,再移动到另一点来选择一个区域;或者在一点点击并拖动到另一点来选择一个区域)。
  • 中击一个Java™栈将会把你带到点击弹出帧的代码中。
  • 默认的缩排是每次缩进两个空格。
  • 包括编辑Java™文件在内的所有模式中,语法高亮标识(Emacs中称为“font locking”)功能都是开启的。

如果你只需要这些定制功能中的一部分,在装载以前将以下一行

(setq make-6170-changes nil)

添加到你的.emacs文件中。这将定义所有的功能,但是不会使用它们中的任一个。查看6170.e1文件,并从中拷贝出你需要使用的部分。

返回顶部

使用Java™doc和Six170Doclet生成规格说明

Sun的JDK中包括了Javadoc,它是一个从含有特定格式注释的源代码中生成规格说明的工具。注释中可能包含“标记”,这将由一个at符号(@)引入。

Six170Doclet扩展了Java™doc,使之能够识别附加的6.170标记,同时还能识别所有Sun的标准Doclet接受的标记。(Six170Doclet实际上是一个预处理程序,它产生一个能够直接被Sun的标准Doclet读取的输入文件。)这些附加的标记描述类的规格说明域,以及方法的需求、改变和效果。

除了增加新的标记,Six170Doclet还可以自动推断缺失的方法摘要,并且还有一些其它的功能使得甚至在阅读代码本身时规格说明都更容易被阅读和编写。

  • 一些扩展的标记应该归为类的概述,它们用来形式的定义一个给定的抽象数据类型的表示。
@specfield name : T // text 指明name是一个类的类型T的一个抽象规格说明域;如果出现的话,将text作为注释添加。
@derivedfield name : T // text 和specfield相同,只是这个还在输出信息中增加了“derived”属性。
@endspec Java™doc发出新号指出在规格说明中没有别的需要建立文档的抽象域了。

派生域可以看成是已经存在的状态上的函数,因此如果一个类有一个规格说明域

@specfield n : integer

我们可以定义一个派生域

@derivedfield pos : boolean // pos = true iff n > 0

派生于不允许保存任何不能够从对象中已经存在的状态中计算得出的信息。因此,你可以使用规格说明域来引入新状态变量,使用派生域来引入这些状态变量上的函数。

规格说明中并不严格要求派生域,但是使用它们能够降低复杂性和冗余。

  • 其它应该归入方法或过程规格说明的扩展标记,它们定义了方法的先决条件、后置条件和副作用。

@requires X 说明X是过程的一个先决条件。
@modifies Y 说明Y之外的任何东西都不能被过程所修改(只要满足X的时候)
@effects Z 说明如果在方法开始时满足X,那么在方法结束时就应该满足Z。                       

在运行javadoc之后,你应该检查输出。你可能会发现你需要增加行终结符(<br>)或段终结符(<p>)以增强可读性。如果你遗漏了相应的标记(比如@endspec),输出中可能就不会出现后面的文本。最后,因为大部分的Java™doc注释文本要被插入到HTML文档中,你应该小心处理可能被解释为HTML标记的文本。例如,如果你写了:

@effects Adds <x> and <y>

那么<x>和<y>在输出中将被解释为HTML标记(而不会被浏览器显示)。

如果Six170Doclet有任何问题,将它们汇报到rhlee@mit.edu(注意不是6.170-staff@mit.edu)。

返回顶部

Zephyr实例

你可能想要订阅一些关于本课程的zephyr实例。这些实例将是有用的资源,请在实验时间访问LA以获得这些实例。主实例名为6.170,这个zephyr实例允许你和班级中的伙伴或者任何值班的实验助理保持联系。(实验助理给在实验时间访问他们的学生更高的优先权,对于任何情况这将是最好的和他们交流的方法。但是,如果时间允许的话,他们将尝试管理实例,并通过那个机制提供帮助。)

返回顶部

机制

要订阅,输入:

zctl add message 6.170 \*

要写实例,输入:

zwrite -i 6.170

要取消订阅,输入:

zctl delete message 6.170 \*

只取消当前会话的订阅,使用“unsub”替代上面的“delete”:

zctl unsub message 6.170 \*

要获得更多zctl的信息,在Athena提示行上输入“man zctl”来查阅可以在线使用的Inessential Zephyr文档。

返回顶部

指导方针

6.170实例严格面向直接与问题设置和Java™相关的问题和答案。如果信噪比率保持较高值,TA和LA通常会订阅6.170实例。我们偶尔会回答实例上的问题,特别是我们看到了一个“不那么正确”的回答或者普遍的疑惑时。但是,如果你有问题要问TA,请给你的TA发电子邮件。而且,实例上的问题不一定会得到一个教员的回应,如果要确保问题得到回答,在工作或实验时间访问一个LA或者TA。

有些问题不应该在zephyr实例上面提出。包括:

  • “这是我的解决方案,它合适吗?足够吗?”

    (这样将把你的解决方案公开发布,违反了不能合作解决问题的规定。将多于5行的代码发布到其上将违反zephyr上的合作规定。)

  • “JDK API中的foo函数能够干什么?它都有哪些参数?”

    This question is evidence of laziness. You should look in the JDK API documentation instead.这个问题是明显的懒惰现象。你应该自己查看JDK API 文档

  • “有没有LA或者TA在线?”

    首先,这个问题是不相干的,在线不一定当班;其次,就算一个LA在值班,这个LA也可能在帮助其他的学生(特别是那些上门拜访LA的学生)。

    你应该访问一个LA或TA;或者仅仅在实例上提出你的问题,并期望能够得到一个回答。

如果你想讨论那些并非指定问题或回答,但是却和6.170相关的话题,你应该使用6.170.d实例。例如,如果你想要展开一个关于Java™美学的讨论,打算聊聊关于问题设置作者的良好书写风格,或者指出你找了两个小时都没有找到的错误,你应该使用6.170.d实例代替6.170实例。

6.170.d实例的机制和6.170实例的是一样的,你只需要在前面的例子中明显的位置中增加一个.d。

返回顶部

Zephyr日志(zlog)

因为6.170zephyr实例经常有很高的访问流量,zephyrs中不变的数据流可以被转移。同样,一些不在线的学生就不能从实例上的实时讨论中得到信息。

6.170 zlog是一个对以上两个问题的解决方案。它记录发送到6.170 zephyr实例上的每一条消息。这样你就可以取消对实例的订阅,而以你自己的的速度在任何时间单独阅读之前其他人在实例上的会话了。你也可以查阅你退出登陆之后发生的会话。在开始解决问题之前先浏览zlog通常是很有帮助的,这样你就可以知道其他人在你将要处理的问题中通常会遇到哪些关于Java™运行时的问题。

返回顶部

怎样使用zlog

6.170 zlog保存在athena机的zlog locker中。要访问它,首先在Athena提示行中输入:

athena% add zlog

6.170 zlog保存在/mit/zlog/6.170目录中。

zlog是一个文本文件。因此,你可以使用你喜欢的文本浏览器打开它。但是,它可能会增长到很大,这将导致很难进行消息导航。

因此,我们推荐使用tail命令来阅读zlog。tail命令类似于Unix中的cathead命令,不同之处是tail从一些靠近文件结尾的点开始,然后打印文件剩下的部分直到结束。这样你就不用看到你上次登陆就已经看过了的zephyrs页面,而直接看到最近新发送的信息了。

你可以告诉tail以任意的相对于文件结尾或开始的偏移量开始,默认的命令:

athena% tail /mit/zlog/6.170

i将打印zlog的最近10行。要让它从更早一些开始,给tail传递-number选项,其中number是开始位置相对于文件结尾的偏移量。因此,

athena% tail -50 /mit/zlog/6.170

输出日志的最后50行。

你甚至可以tail让等待并打印出最新到达的zephyrs,如果你不希望让6.170实例上的会话和你个人的zephyr会话混在一起。要实现这项功能,使用-f选项:

athena% tail -f /mit/zlog/6.170

要获得更多关于tail的信息,阅读man页面,在Athena提示行上输入下面命令:

athena% man tail

返回顶部

创建PDFs

你可以以PDF格式提交你的图(或者其它非代码的作业)。你可以使用Adobe Acrobat Distiller来将PostScript转换为PDF格式,命令如下:

athena% add acro
athena% distill file.ps

这将生成file.pdf

注意,Distiller只能作Sun平台上工作。如果不能满足,你可以选择在一个dialup服务器上运行它,或者使用gnu locker中的ps2pdf工具。

返回顶部

Visio®

可以以zip格式下载Visio® 2000注意:要下载这个文件,你必须拥有一个MIT IP地址。这个文件也比较大(224MB),而CD版本的Visio®数量有限,这将是一个问题。Visio®是一画图程序,你可以使用它来创建对象模型和模块依赖图。要得到更多关于它的信息,请访问Visio® 2000 网站

在一个Windows 2000机器上安装Visio® 2000时,如果你收到这样一个错误信息:“Visio2000: Error Message: The Procedure Entry Point GBL Could Not Be Located in the Dynamic Link Library Vislib32.dll.”,请查看Microsoft帮助支持

可以使用以zip格式存储的Visio® v.56.170 Visio®模板,来创建你的OM和MDD。在下载并解压后,6170目录应该放置在你的Visio®安装路径的Solutions子目录下。

如果你在Athena机上进行工作,或者你没有一台Windows机器,你可以使用Dia®来代替Visio®

返回顶部

Dia®

如果你没有一台Microsoft Windows机器(因此不能运行Visio®),你还可以选择另一种画图工具,它的名字是“dia”。

If you have added the 6.170 locker and are on a Sun or Linux machine, then you should be able to run it by running

如果你已经添加了6.170 locker并且在一条Sun或者Linux机器上,那么你应该能够使用下列命令来运行dia:

athena% dia &

Dia® 能够将它的图作为压缩的postscript文件导出,这样你就可以把它转换为.pdf格式,或者你可以使用Dia®自己来打印你所创建的图。

如果你在使用dia时有什么问题请给pnkfelix@mit.edu(不是6.170-staff)发送电子邮件询问。

如果你在使用时遇到什么问题,查阅下面的链接:
教程
Dia®首页

6.170课程并不正式提供Dia®工具(不要问你的TA该如何使用Dia®,他们可能也不知道),但是它是Visio®的一个替代选择。

返回顶部

CVS

CVS(Concurrent Version System)允许多个用户独立的编辑同一个文件,在他们各自的副本上进行工作。主文件保存在一个“repository”中。每个用户“登出”一个工作副本,接着他们对这个副本进行编辑,“登入”或者“提交”他们所作的改动到repository中,并且通过“更新”来将别人所作的改动合并到自己的副本中。CVS保存对你的文件的前一版本的跟踪,因此你可以比较两个版本,或者在你所作的改变导致错误时恢复前一个版本。

CVS repositories保存了如源文件、Makefiles、以及一些文档等基于文本的文件。Repositories中不应该包含编译过的文件(.class)或者生成的文本文件,例如Java™doc文档。你的CVS repository应该只包含不能由repository中其它文件所生成的文件。

这里是一个使用CVS的典型步骤:

  1. “更新”你的登出文件。
  2. 添加或者编辑一个文件。
  3. 再次“更新”来查看在你开始编辑之后repository中的该文件是否被更改。如果被更改了,它的改变将自动合并到你的工作副本中。
  4. 如果有一个因为两处更改相互冲突而产生的“合并冲突”,手动的选择保留哪一个改变。
  5. “提交”,“登入”这个文件。

每个用户将会把他们的工作副本保存在某个地方。我们建议你创建一组/mit/6.170/groups/seNNM/username目录。

返回顶部

安装

安装

如果你在athena机上工作,在你的~/.environment文件中增加下面一行:

add gnu

如果你在家或者在一台Linux机上工作,它上面应该已经安装好了CVS。对于Windows机器,从http://www.wincvs.org/下载WinCVS或者从http://www.cvshome.org/下载它的非图形化版本;也可以查看MIT IS CVS文档。对于Macs,从http://www.maccvs.org/下载MacCVS。

请注意,我们只正式提供Athena机上的CVS使用。

每组安装

安装CVS有两个步骤。首先,创建repository并且添加一个模块到它里面;接着,每个用户登出那个模块。

一个“模块”是CVS中的一组文件。对于6.170课程你可能只需要一个模块就够了。让我们称它为gb。为每组运行一次下列命令:

setenv CVSROOT /mit/6.170/groups/seNNM/.cvs
cvs init
cd /mit/6.170/groups/seNNM
mkdir $USER; cd $USER
mkdir gb; cd gb
cvs import -m "Start" gb seNNM start
cd ..

(-m标记指示一个日志消息; seNNMstart参数是任意的,但是必须在CVS import命令中出现。)

每用户安装

在创建repository之后,每个用户都应该将gb模块登出到自己的工作目录中去,创建你的工作目标并切换到其中:

cd /mit/6.170/groups/seNNM
mkdir -p $USER; cd $USER

然后,登出gb模块:

  • 本地登出(从Athena机上)
    cvs -d /mit/6.170/groups/seNNM/.cvs checkout gb
  • 远程登出(从非Athena机上)
    setenv CVS_RSH ssh
    cvs -d :ext:USERNAME@athena.dialup.mit.edu:/mit/6.170/groups/seNNM/.cvs checkout gb

最后,创建一个包含下列两行的~/.cvsrc文件:

diff -u

update -d -P

查看手册来获得更多关于~/.cvsrc文件的信息。

返回顶部

基本用法

更新你的文件

要从repository中得到最新的修改来更新你的工作副本(但是保留你对本地副本所作的所有改变),使用:

cvs update

CVS将尝试合并你上次执行cvs更新之后的所有改变,包括你自己的和其他人做的。如果你的改变和其他人的冲突,cvs更新将通知你,而源文件将按以下格式变成包含所有冲突部分的多个版本(你的和来自repository的):

<<<<<<< 文件名



你的版本



  =======







  REPOSITORY'S 版本







  >>>>>>> repository 版本的修订编号



你必须通过编辑文件来解决冲突,移除标记,并保留你所喜欢的版本(或者手动合并它们)。(查找“<<<”,直到你解决所有冲突是一个好办法。)一旦你解决了任何问题,你就可以安全的将文件提交到repository中去了。

注意,CVS按一行接一行的原理进行工作。也就是,它只能知道一整行是否被修改、增加、或删除。

(CVS更新显示你的工作目录下所有改变了的或者和repository中文件不同的文件的状态,使用一个字母来标志。“U”表示它已经被repository中的最新副本所替代;“M”表示你的工作副本和repository的最新副本不同,并且合并已经成功;“C”表示存在一个合并冲突。)

提交、增加和移除文件

要将一个你编辑过的文件提交到repository中,使用:

cvs commit -m "a log message" filename

如果你遗漏了文件名,CVS将提交当前目录的所有文件。message是一个日志消息,它允许你保持对改变的追踪而不需要阅读所有代码。这将是非常有用的,你应该总是输入一个描述性的日志消息,你应该输入“改正了一些错误”这样的消息。如果你遗漏了-m标记,CVS将即时为你提供一个日志消息。

要将一个文件增加到repository中,使用:

cvs add filename

要从repository中移除一个文件:

rm filename
cvs rm filename
cvs commit -m "移除文件的原因"

这些命令只对文件进行增加或删除标记。在执行cvs add或者cvs rm之后,你还需要使用cvs commit来实际通知repository执行这些改变。

要对CVS中的一个文件或目录进行移动或者更名操作,你必须将它从一个位置移除并添加到另一个位置中去。

增加和移除子目录

你可以使用下列命令来增加一个子目录:

mkdir dirname
cvs add dirname

cvs立即增加一个子目录,不再需要提交。

你不能使用CVS来移除一个子目录。(cvs rm不能对一个目录使用。)最好的方法是使用cvs rm删除该目录下所有文件,然后执行cvs update -P来出去你的工作目录下所有的空子目录。

跟踪改变

改变日志是一个在检查改变时用到的消息列表,通过下面命令来查看它:

cvs log filename

要查看工作副本和repository中的最新副本之间的区别,使用:

cvs diff [filename]

遗漏文件名将查看所有文件的区别。使用-r1.xx标记来和一个特定修订本比较,使用两个 -r标记来对两个版本进行相互比较。

返回顶部

提示和技巧

Emacs中的CVS

Emacs内置了对CVS的支持。有两种方法可以从Emacs内部调用CVS命令:从一个访问文件的缓存中调用,或者从一个列出所有修改了的文件并且允许你对它们进行操作的缓存中调用。

用来从一个文件访问缓存执行操作的CVS命令都以C-x v为前缀(助记:version control)。三个最常用的命令是:

C-x v =: vc-diff
显示你的工作副本和repository版本之间的不同之处,类似cvs diff。
C-x v =: vc-next-action
在大部分情况下,这个命令提交你所做的改变,类似于cvs commit。你将在一个特殊的缓存中插入一个日志消息,然后输入C-c C-c来完成这个文件的实际提交。
C-x v C-h: show VC bindings
列出所有以C-x v为前缀的命令。

另外,你还可以使用pc1-cvs包来运行CVS命令并浏览输出。主命令是:

M-x cvs-update RET

这将执行cvs更新,并为你的浏览器将结果保存到一个*cvs*缓存中。接着你可以通过以下命令对各行进行操作:

=: cvs-mode-diff
显示你的工作副本和repository版本之间的不同之处,类似cvs diff。
f: cvs-mode-find-file
使用Emacs“查找”(编辑)文件。
c: cvs-mode-commit
提交你所做的改变,类似于cvs commit。你将在一个特殊的缓存中插入一个日志消息,然后输入C-c C-c来完成这个文件的实际提交。
g: cvs-update
重新执行cvs update,并使用新结果更新当前(*cvs*)缓存。
r: cvs-mode-remove
删除文件并对它执行cvs remove。你仍需要提交改变。
m: cvs-mode-mark
标记一个以后将要对其进行操作的文件。这允许你同时对多个文件进行操作,例如使用同一个日志信息同时提交它们。大部分cvs-mode操作(提交、移除,等等)对所有标记的文件起作用;如果没有被标记的文件,这些操作将对Emacs游标(“point”)所指的文件起作用。
u: cvs-mode-unmark
解除对一个文件的标记。
h: cvs-mode-help
给出关于命令的一个简短帮助。

返回顶部

最小化合并冲突

CVS并不能替你完成管理工作!协调工作是非常重要的,就算你一个人单独工作也是这样。你应该尽量减少同时在同一个文件上的工作。如果必须在同一个文件上工作,那么应该把工作放在它的不同部分上。模块化代码并将它们分散到多个文件中去常常能够提高工作效率。在实现你的设计决定之前,你应该将它们告诉你的团队伙伴,尤其是当你的设计中涉及会对他们的代码产生影响的接口的时候。

你应该在何时提交?如果不进行足够的测试就频繁提交,你可能会给repository中注入错误并影响你的小组同伴的工作。但是如果你很少提交,你的小组同伴将使用过时的代码,这将导致无效的努力和以后的合并冲突。

并没有特别严格的规则,但是一个很好的规则是在你登入之前所有的东西都应该至少编译过。没有比登出了别人所作的改变之后因为你的代码使编译停止更令人郁闷的事情了。

另一个很好的经验规则(虽然这个规格可以有很大的扩展)是在一天结束之前你应该尽量减少没有提交的东西。在你不进行编码的时候可能发生很多事情,因此在你离开之前最好保存并提交你所作的改变。由于前一个规则(不要登入不能工作的代码)更加重要,在你进行较大改动的时候这个规则就很难满足。因此,一次完成一个功能通常是一个好的策略,这样你可以快速的完成各个部分并保证了repository的更新。

当然,协调你和你的小组同伴的工作才是最小化合并冲突的真正关键。请再次注意,CVS并不能替你完成管理工作!

返回顶部

缺陷

这里是一些避免使用CVS常常遇到的问题的提示:

  • 不要手动编辑repository,它不是为人所设计的。

  • 不要一次进行过多的改变。这将减小化合并冲突。这通常也是好的编程实践。

  • 在开始编辑一个文件之前先执行cvs update。人们常常忘记这点。如果你没有更新,你可能会编辑一个过时的版本,并导致恼人的合并冲突。

  • 如果其他组员没有提交他们的改变,你可能需要替他们提交。你可以通过进入他们的工作目录并在那里执行一个cvs commit命令。但是在无计可施的时候才可以使用这种办法。在你执行之前,你应该先使用cvs diff命令来查看他们到底做了哪些改变,你是不是真的必须将这些改变登入。

  • 注意制表符。Emacs的自动制表符对于不同的人可能有不同的宽度,而且其他的文本编辑器对于制表符也有不同的处理方法,包括制表符宽度、制表符是真的制表符还是空格或者都有。你的组员使用的文本编辑器必须有相同的制表符使用约束。这是因为CVS基于行比较原理,因此不同的制表符可能会导致恼人的合并冲突。这只是“你们应该在代码格式约定上达成一致。”中的一个特定情况。

返回顶部

更多信息

上面的介绍只是CVS的一个快速入门,实际上CVS还有很多其它功能。要获得更多帮助请阅读相关的文档。

要在Athena机上阅读CVS手册,请使用info cvs命令。或者,要从Emacs上查看,使用M-x info RET m cvs RET,其中M-x指按下alt键后按下x键,RET是返回键,你不需要再输入任何空格。特别的,请查看“开始一个新项目”和“概述/一个会话实例”部分。另外,如果你的组员中有人想在家工作,你们应该阅读“Repository/远程repositories”部分。

返回顶部




 
MIT Home
Massachusetts Institute of Technology Terms of Use Privacy