数据在工作目录是怎样存储的

当我们讨论CVS的内部结构时,即是讨论CVS提交了什么信息在工作目录的CVS目录中。对源码库而言,CVS处理内部结构信息并且用户可以通过CVS命令来获取这些信息,但是在更多情况下,更常用的是让外部程序可以浏览这些信息,例如jCVS图形界面和emacs的VC软件包。这些程序如果要和其它使用这些文件的程序协同工作的话,应该遵循本节讨论的推荐标准,相关的这些程序包括提到的程序的未来版本和CVS的命令行客户端。

CVS目录包含以下若干个文件,为了保证未来版本的可扩展性,读取CVS目录的程序应忽略本文没有提到的其它文件。

文件以系统习惯的文本方式保存。这意味着文件在不同习惯系统的工作目录之间不能移植。同理这种系统中cvs管理的文件也无法移植。

ROOT

该文件包含当前CVS根目录,请看[告诉CVS源码库放在哪里]。

Repository

该文件包含源码库里当前路径的映射路径。该路径可以是绝对路径也可以是相对路径,从CVS1.3版本开始,CVS可以读取这两种格式的路径。相对路径相对于根目录并且容易解析,但是绝对路径更通用,所有在应用中源码库文件应该支持这两种格式中的任意一种。例如,执行以下命令以后:

cvs -d :local:/usr/local/cvsroot checkout yoyodyne/tc

Root文件应该包含:

:local:/usr/local/cvsroot

Repository文件同时包含

/usr/local/cvsroot/yoyodyne/tc

或者

yoyodyne/tc

如果特别的工作目录不与源码库的目录相一致,Repository应当包含CVSROOT/Emptydir

Entries

该文件列出了工作目录中的文件和子目录。每一行的第一个字符代表该行的类别。为了保证未来版本的可扩展性,如果一行的第一个字符不可识别,读取文件的程序应默认忽略该行。

如果第一个字符是“/”,则格式如下:

/name/revision/timestamp[+conflict]/options/tagdate

其中:[]不是格式的一部分,仅仅是代表 + 和conflict项是可选的。name是目录中文件的名字。revision 是正在编辑的文件派生的修订版本号。0 代表新添加的文件, -revision:代表删除的文件。 timestamp 为时间戳,表示CVS创建文件的时间。如果时间戳和文件修改的时间不一致,意味着文件已经被修改过。 时间戳以ISO标准的C函数asctime()的格式存储(例如,Sun Apr 7 01:29:26 1996)。用户也可以以缩写形式写入时间字符串来表示文件已经被修改过,比如,合并结果(Result of merge), 但这不是推荐的方式。判断一个文件是否被修改, 一个程序只要读取改文件的时间戳timestamp并进行字符串比较就可以了。如有冲突,文件做了冲突标记之后会在文件的修改时间上设一个conflict[冲突示例 在 第 10 章]。conflict表示是否存在版本冲突。如果该项和文件实际的修改时间相同表示用户还没有解决版本冲突问题。 options包含可选项。(例如对二进制文件可以使用-kb)。如果tagdate后面是sticky标签或日期, 则用T表示标签,用D表示日期。注意:如果时间戳timestamp包含一对以空格分隔的时间戳而不是一个,应该按照早于CVS1.5的版本处理(这里没有相关文档)。

CVS/Entries(本地或全球)里时间戳(timestamp)的时区(timezone)与操作系统使用的时区相同。例如:Unix上时间戳为UT,CVS/Entries里也应如此。VMS上时间戳为本地,cvs就使用当地时间。这样文件就不会因为时区(例如,夏时制)改变而显示被修改。

如果Entries的某一行的第一个字符是D,则该行代表一个子目录。如果该行只有一个字符D则表示生成Entries的程序没有记录子目录(因此,如果只有一行以字符D开头可以知道工作目录下没有下级目录)。否则,格式如下所示:

D/name/filler1/filler2/filler3/filler4

其中:name 是子目录的名称。为了保证未来版本的可扩展性,所有的filler域都应该被忽略。在修改Entries文件的时候应保留这些域。

Entries文件中行的次序无关紧要。

Entries.Log

这个文件不纪录任何与Entries无关的信息,但是它能使你更新一些信息而不必重写整个Entries文件,并且对信息的安全提供保护,甚至在程序写Entries文件和Entries.Log 期间突然发生中断等异常时仍能保证数据的安全。系统在读Entries时会检查Entries.Log。如果后者存在,它将按照Entries.Log所纪录的信息应用到Entries。在使用这些内容后,推荐的操作是重写Entries并且删除Entries.LogEntries.Log的格式为一个单字符的命令加一个空格,接着与Entries行的格式一样。命令有下面几种:A 表示entry已经被加入,R 表示entry已经被删除。其它的字符表示该行应被忽略不计(为以后扩展)。如果第二个字符不是空格,那么,它是由一个老版本的CVS系统生成的(本文档不做介绍)。

如果一个程序不只读还要写可以忽略Entries.Log

Entries.Backup

这是一个临时文件,推荐的作法是将Entries先写到Entries.Backup,然后将它更名为Entries (如可能,自动实现)。

Entries.Static

这个文件唯一的价值就是它存在或不存在。如果它存在,那么,意味着只有部分的目录被得到,并且CVS将不能创建附加文件在这些目录中。你可以使用update -d 命令删除它。该命令将得到附加的文件并且删除Entries.Static文件。

Tag

这个文件包含每一目录的粘性(sticky)标签或时间。第一个字符为 T 表示一个有分支标签,N表示一个无分支标签,D表示一个日期,其它的字符为了以后扩展将被忽略,这个字符后接的是标签内容或日期。注意:每一目录新增加的的粘性标签或日期;他们可能不与在单个的文件上的粘标签或日期一样。如何使用粘性标签或日期表示一般的信息,参见[粘性的标签(Sticky tags) 在 第 4 章]。

Checkin.prog, Update.prog

这些文件存储指定的程序。被存储的程序可在模块文件中使用-i-u选项指定。

Notify(通知)

这个文件存储还没有送给服务器的通知(如editunedit等)。这里不介绍它的格式。

Notify.tmp

该文件是Notify的临时文件,正如Entries.BackupEntries。即在更新Notify文件时,先将新内容写入Notify.tmp中,然后将(自动)该文件更名为Notify

Base

如果监视器在使用状态,那么一个edit命令在Base目录下保存原来的副本,这样即使系统不能与服务器进行交流,也允许unedit命令操作.

Baserev

这个文件列出了对Base目录下文件的每次修订。格式为:

Bname/rev/expansion

其中expansion将被忽略,允许将来扩展。

Baserev.tmp

该文件于Baserev>正如Entries.BackupEntries的临时文件。在更新Baserev文件时,先将新内容写入Baserev.tmp中,然后将(自动)该文件更名为Baserev

Template

这个文件包含由rcsinfo指定的模版[Rcsinfo 在 附录 C]。它只用于客户端,非客户/服务器模式的CVS直接参考rcsinfo。