下一个: , 上一个: Repository storage, 上层: Repository


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

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

CVS 目录包含以下若干个文件。 为了保证未来版本的可扩展性,读取此目录的程序应忽略在此目录中但没有在此归档的文件。

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

Root
该文件包含当前 cvs 根目录,请看 Specifying a repository


Repository
该文件包含当前目录对应的仓库里的目录。 该路径可以是绝对路径也可以是相对路径;从 1.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(参阅 Conflicts example),conflict 表示是否存在版本冲突。 如果 conflict 和文件实际的修改时间相同表示用户还没有解决版本冲突问题。 options 包含可选项(例如对二进制文件可以使用 `-kb')。 tagdate 含有 `T' 后面跟标签名,或 `D' 表示日期,后面跟是 sticky 标签或日期。 注意:如果 timestamp 包含一对以空格分隔的时间戳而不是一个,应该按照早于 cvs1.5 的版本处理(这里没有相关文档)。

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

如果 Entries 的某一行的第一个字符是 `D',则该行代表一个子目录。 如果一行只有字符 `D' 则表示生成 Entries 的程序没有记录子目录(因此,如果有这样的一行并且没有别的以字符 `D' 开头的行,可以知道没有子目录)。 否则,行是这样的:

          D/name/filler1/filler2/filler3/filler4
     

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

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


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

如果程序选择只是读而不写则可以忽略 Entries.Log


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


Entries.Static
此文件唯一实质性的事情就是它的存在与否。 如果它存在,那么,意味着只有部分的目录被得到,并且 cvs 将不在该目录中创建附加文件。 可以使用 update 带 `-d' 选项的命令来删除它,该命令将得到附加的文件并且删除 Entries.Static 文件。


Tag
这个文件包含每一目录的粘性标签或时间。 一个分支标记的第一个字符是 `T',对于一个非分支标记则是 `N', 或对于一个日期则是 `D',或别的字符意味着为了将来扩充而文件应该被默默忽略。 这个字符后接的是标签或日期。 注意,每一目录新增加的粘性标签或日期被用来向新增加的文件施加作用这种事情;它们可能不与在单个的文件上的粘标签或日期一样。 关于粘性标签或日期的一般信息,见 Sticky tags


Notify
这个文件存储还没有发送给服务器的通知(如 editunedit 等)。 这里还没有归档它的格式。


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


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


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

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


Baserev.tmp
该文件是针对 Baserev 的,正如 Entries.Backup 针对于 Entries 一样。 即,为了写 Baserev 文件,先将新内容写入 Baserev.tmp 中,然后将(如可能则自动)其更名为 Baserev


Template
这个文件包含由 rcsinfo 文件指定的模版 (参阅 rcsinfo)。 它只用于客户端;非客户/服务器模式的 cvs 直接参考 rcsinfo