Пока мы описываем внутреннюю работу CVS, которая иногда становится видна, мы можем также поговорить о том, что CVS хранит в каталогах CVS в рабочих каталогах. Как и в случае с репозиторием, CVS обрабатывает эту информацию, и обычно вы обращаетесь к ней посредством команд CVS. В некоторых случаях, однако, бывает полезно напрямую работать с содержимым этих каталогов, например, в графической оболочке jCVS или пакете VC для emacs. Такие программы должны следовать рекомендациям в этой главе, если они желают нормально работать совместно с другими программами, использующими те же самые файлы, включая будущие их версии, а также с CVS, работающим из командной строки.
Каталог CVS содержит несколько файлов. Программы, читающие этот каталог, должны игнорировать файлы, находящиеся в этом каталоге, но не документированные здесь, чтобы дать возможность развития в будущем.
Файлы хранятся в текстовом формате, соответствующем соглашениям операционной системы. Это означает, что рабочие каталоги не переносимы между системами с разными форматами хранения текстовых файлов. Это сделано специально, исходя из того, что сами файлы, находящиеся под управлением CVS, вероятно, также не переносимы между такими платформами.
Root
Этот файл содержит текущий корневой каталог CVS, как описано в разделе “Как сообщить CVS, где находится репозиторий”.
Этот файл содержит каталог в репозитории, которому соответствует текущий каталог. Здесь может быть имя с полным или относительным путем; CVS способна обрабатывать оба варианта, начиная с версии 1.3. Относительный путь отсчитывается от корня, хотя использование абсолютного пути довольно распространено и программы должны уметь обрабатывать оба варианта. Например, после команды
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.
В этом файле перечислены файлы и каталоги в рабочем каталоге. Первый символ каждой строки указывает тип каждой строки. Если символ нераспознан, программа, читающая файл, должна спокойно пропустить эту строку, чтобы дать возможность развития в будущем. Если первый символ — это /, то формат строки таков:
/имя/ревизия/метка времени[+конфликт]/опции/тэг или дата
где '[' и ']' не являются частью строки, но указывают, что '+' и отметка о конфликте не обязательны. name — это имя файла в каталоге. ревизия — это номер ревизии, на которой основан файл в рабочем каталоге, или '0' для добавленного файла, или '-', за которым следует номер ревизии, для удаленного файла. метка времени — это время, когда CVS создала этот файл; если это время отличается от текущего времени модификации файла, значит, он был изменен. Метка времени записывается в UTC (по Гринвичу), в формате, используемом функцией стандарта ISO C asctime() (например, 'Sun Apr 7 01:29:26 1996'). Можно написать также строку в другом формате, например, 'Result of merge', чтобы указать, что файл всегда должен считаться измененным. Эта строка — вовсе не специальный случай: чтобы узнать, изменился ли файл, CVS берет дату модификации файла и просто сравнивает строку со строкой метка времени. конфликт указывает, что произошел конфликт. Если эта строка совпадает с действительным временем модификации, значит, пользователь еще не справился с конфликтом. опции содержат прилипшие ключи командной строки (например, -kb для двоичных файлов). тэг или дата содержит либо 'T', за которой следует имя тэга, либо 'D', за которой следует прилипший тэг или дата. Заметьте, что если метка времени содержит пару меток времени, разделенных пробелом, а не единственную метку времени, значит, вы имеете дело с версией CVS ранее 1.5 (этот случай здесь не документирован). Если первый символ в строке в файле Entries — это 'D', это означает подкаталог. 'D' на отдельной строке указывает, что программа, которая создала файл Entries, умеет обращаться с подкаталогами (то есть, если такая строка присутствует, и нет других строк, начинающихся с 'D', значит, подкаталогов нет). В противном случае строка выглядит так:
D/имя/заполнитель1/заполнитель2/заполнитель3/заполнитель4
где имя — это имя подкаталога, а все поля заполнитель должны игнорироваться, в целях будущих расширений. Программы, изменяющие файлы Entries, должны сохранять значения этих полей. Строки в файле Entries могут быть в любом порядке.
В этом файле хранится та же самая информация, что и в файле Entries, и с его помощью можно обновлять эту информацию без необходимости полностью переписывать файл Entries, включая возможность сохранять информацию, даже если программа, писавшая в Entries и Entries.Log аварийно завершилась. Программы, читающие файл Entries должны также проверять существование файла Entries.Log. Если последний существует, то они должны прочесть файл Entries и внести в него изменения из файла Entries.Log, после чего рекомендуется записать заново файл Entries и удалить файл Entries.Log. Формат строки файла Entries.Log — односимвольная команда, за которой следует строка, в формате Entries. Команда — это либо 'A' для указания, что строка добавляется, либо 'R' — если строка удаляется, или любой другой символ — если эту строку следует проигнорировать (для будущих расширений). Если второй символ строки в файле Entries.Log — не пробел, значит, файл был создан старой версией CVS (здесь не документируется). Программы, которые пишут, но не читают, могут спокойно игнорировать Entries.Log.
Это временный файл. Рекомендованное использование — записать новый файл Entries в Entries.Backup, затем переименовать его (атомарно, если возможно) в Entries.
Единственная вещь, интересующая нас об этом файле — существует он или нет. Если существует, это значит, что была получена только часть каталога и CVS не будет создавать в нем дополнительных файлов. Чтобы очистить этот файл, используйте команду update с опцией -d, чтобы получить дополнительные файлы и удалить Entries.Static.
В этом файле находятся прилипшие тэги и даты для этого каталога. Первый символ — 'T' для тэга ветки, 'N' для обычного тэга или 'D' для даты. Другие символы должны игнорироваться, для будущих расширений. За этим символом следует тэг или дата. Заметьте, что прилипшие тэги и даты применяются к добавляемым файлам; они могут отличаться от тэгов и дат, прилипших к отдельным файлам. Общая информация о прилипших тэгах и датах находится в разделе “Липкие метки”.
В этих файлах хранятся имена программ, заданных опциями -i и -u в файле modules, соответственно.
См. Checkin.prog.
В этом файле хранятся уведомления (например, для edit или unedit), которые еще не было отосланы на сервер. Их формат еще не документирован здесь.
Этот файл по отношению к файлу Notify является тем же, что Entries.Backup по отношению к Entries. Чтобы создать файл Notify, сначала запишите его новое содержимое в Notify.tmp, затем (атомарно, если возможно), переименуйте его в Notify.
Если используются слежения, то команда edit сохраняет исходную копию файла в каталоге Base. Это позволяет команде unedit работать, даже если нет доступа к серверу.
В этом файле перечислены ревизии каждого файла в каталоге Base. Формат таков:
Bимя/ревизия/расширение
поле расширение должно быть проигнорировано, для будущих расширений.
Этот файл по отношению к Baserev является тем же, чем Entries.Backup по отношению к Entries. Чтобы создать записать файл Baserev, сначала запишите его новое содержимое в Baserev.tmp, затем (атомарно, если возможно), переименуйте его в Baserev.
Этот файл содержит шаблон, заданный файлом rcsinfo. Он используется только клиентом; не-клиент-серверные варианты CVS напрямую обращаются к rcsinfo.