Назад

Содержание

Вперед


1.9.6. Система контроля исходного кода.

    При создании и сопровождении длительных проектов возникает необходимость сохранения разных версий файлов. Так, при модификации какой-либо части системы могут возникнуть непредвиденные обстоятельства, например ошибки. В этом случае надо последовательно восстановить предыдущее состояние изменявшихся частей проекта с тем, чтобы увидеть, с какого момента начались неприятности. А потом можно либо исправить неверные версии, либо отказаться от них.

    Для такого сопровождения проектов, в UNIX разработано несколько систем. Первой из них, по-видимому, является "Система контроля исходного кода (Source Code Control System - SCCS). Но наиболее распространенным и общепринятым в настоящее время является комплекс "Система контроля версий" (Revision Control System - RCS). О ней и пойдет речь в данном разделе.

    Система RCS обеспечивает запись, поиск и хранение версий текстовых файлов. Это позволяет вести учет изменений и контролировать права доступа к ним при одновременной работе нескольких пользователей. Система применяется для объектов, которые часто редактируются, например , варианты статей, писем, текстов программ и т.п.

    Система RCS обеспечивает возможности, перечисленные ниже.

  1. Ведение для файлов учета всех изменений, которые собираются и заносятся автоматически. Для каждой версии указывается автор, дата и время записи, и краткое описание сути внесенных изменений. Наличие этой информации позволяет проследить историю развития файла, не требуя утомительной операции сравнения листингов различных его модификаций.
  2. Хранение, поиск и выдачу версий файла. RCS сохраняет все версии достаточно экономичным (с точки зрения использования дисковой памяти) способом. Различные варианты объекта, находящиеся под контролем RCS, образуют как бы дерево. Начальная модификация файла получает номер 1.1, следующая 1.2 и т.д. Если необходимо, пользователь может явно задать номер и другие атрибуты модификации, вносимой в RCS (см. ниже). Так, можно из версии 1.2 начать две разных ветви 1.2.1.1 и 1.2.2.1. На рис. 1.1 приведен пример истории развития версий некоторого объекта.

pict-1-1.gif (3542 bytes)

Рис. 1.1. Дерево версий файла, находящегося под контролем RCS.

  1. Версии могут получать символьные имена и иметь статус: экспериментальная, стабильная и т.д. Это обеспечивает достаточно простой способ описания необходимой конфигурации собираемых модификаций. Когда из RCS необходимо "достать" какую-либо из модификаций объекта, то для ее указания можно использовать номер, символьное имя, дату создания, имя автора или статус.
  2. Решение проблем, возникающих при попытке одновременного редактирования одной и той же версии файла несколькими пользователями. Если объект изменяется в настоящее время одним лицом, то попытки других получить к файлу доступ блокируются.
  3. Слияние версий. Две разных ветви развития файла можно слить в одну. При этом система проверяет возможное пересечение редакций и, если такая ситуация обнаружена, сообщает об этом пользователю.
  4. Автоматическое указание при "выписывании" файла из RCS для каждой версии имени, номера, времени создания, автора и т.д. Эта информация может заноситься системой в любое место файла, указанное пользователем.

    Рассмотрим основные команды, которые необходимы для использования системы RCS. Для начала работы с системой достаточно знать всего две из них: ci и co. Первая помещает содержимое текстового файла под контроль RCS, а, если он там уже есть, то образует новую версию. Команда co находит и выдает указанную версию, хранящуюся в системе.

    Рассмотрим использование этих команд на следующем примере. Предположим, что имеется файл "f.c", который требуется передать под контроль RCS. В результате выполнения команды:

ci f.c

    в текущей директории будет создан файл "f.c,v", содержимое файла "f.c" переписано в "f.c,v" в качестве исходной версии 1.1, а сам файл "f.c" уничтожен. Кроме того, при выполнении команды, система потребует ввести краткое описание образованной версии. Все последующие вызовы программы ci будут запрашивать краткий комментарий, который должен отражать суть внесенных изменений (заметим, что если в текущем каталоге есть поддиректория с именем RCS, то файл "f.c,v" будет помещен в него) Файлы с суффиксами ",v" называются файлами RCS.

    Для получения рабочей версии файла "f.c" из предыдущего примера, необходимо вызвать команду:

co f.c

    Она найдет последнюю версию в "f.c,v" и запишет ее в файл "f.c". Можно отредактировать данный файл (его мы будем называть "рабочим") и попытаться занести новую версию в "f.c,v":

ci f.c

    Номер новой модификации будет образован из номера предыдущей версии, увеличенного на единицу. При попытке записи может возникнуть сообщение:

ci error: no lock set by <имя>

    Это означает, что во время создания файла RCS был включен режим блокировки при порождении новых версий. В этом случае при выполнение операции чтения из файла RCS, необходимо сообщить системе, что предполагается создание новой версии файла и требуется запретить попытки параллельного его редактирования до окончания работы над версией. В данном случае, в команде чтения файла должен указываться признак блокировки (ключ -l):

co -l f.c

    При этом гарантируется, что следующий номер версии будет зарезервирован за пользователем, "выписавшем" файл, и попытки других пользователей создать новую его версию будут отвергнуты.

    Существует еще одна возможность зарезервировать за собой право создания очередной версии. Это команда:

rcs -l f.c

    Она эквивалентна "co -l f.c', но "рабочий" файл "f.c" не создается. Команда бывает полезна, если при выписывании файла ключ "-l" не был указан (например, по невнимательности). Если в момент выполнения инструкции, файл уже был захвачен кем-либо, будет выдано сообщение о невозможности блокировки. В этом случае единственно, что можно сделать, это попытаться как-нибудь договориться с соответствующим пользователем, не рассчитывая на мудрость системы RCS.

    Если пользователь является единственным полноправным владельцем файла, то необходимости в использовании аппарата блокировки нет. В этом случае его можно выключить с помощью команды:

rcs -U f.c

    При выключенной блокировке владельцу файла нет необходимости указывать, что создание "рабочего" файла может привести к появлению новой версии (хотя для остальных пользователей это действие является обязательным).

    Включение режима блокировки выполняется с помощью команды:

rcs -L f.c

    Как правило, создание новой версии связано с получением "рабочего" файла, его редактирования и записи новой версии с помощью команды ci, которая уничтожает "рабочий" файл. При использовании ключа -l команда:

co -l f.c

    выполняет все свои обычные действия, но "рабочий" файл не уничтожается, и сохраняется блокировка попыток модификации соответствующего файла RCS другими пользователями. Это позволяет непосредственно продолжить редактирование "рабочего" файла после фиксации промежуточной версии.

    Аналогичные действия выполняются при использовании команды с ключом "-u", однако режим блокировки снимается. Данный ключ часто используется в случае, если после записи версии предполагается последующая работа с "рабочим" файлом (например, компиляция или распечатка).

    Использование обоих ключей приводит к модификации информационных записей в файле (см. ниже).

    Пользователь может помещать в "рабочий" файл специальные строки (маркеры), которые при "выписывании" его, заменяются системой RCS на справочные сообщения. Так, если в файл поместить последовательность символов:

$Header$

    то при получении версии из RCS, в "рабочем" файле она будет заменена на строку вида:

$Header: файл версия дата время автор $

    В процессе работы не возникает необходимости редактирования этой строки, так как система автоматически проводит коррекцию при изменении даты обновления, идентификатора пользователя (автора), номера версии и т.п. Как правило, маркеры размещаются в строках комментария. Если необходимо, чтобы служебная информация попала и в объектный модуль, достаточно завести в исходном тексте программы соответствующую переменную. Например:

static char rcsid[ ] = "$Header$";

    Для получения справочной информации о версиях используется команда ident, которая находит маркеры в файле любого типа и выдает соответствующие строки. Так могут быть получены сведения о том, какие версии каких файлов использовались при создании указанной программы.

Полный список маркеров, используемых системой RCS, приведен ниже.

$Author$
Идентификатор пользователя, записавшего данную версию.
$Date$
Дата и время записи версии.
$Header$
Стандартный заголовок, содержащий имя файла RCS, номер версии, дату записи, идентификатор пользователя и статус версии.
$Locker$
Идентификатор пользователя, зарезервировавшего за собой право записи модифицированной версии. Если версия не блокирована, выдается строка нулевой длины .
$Log$
Комментарий, записанный пользователем при занесении версии в RCS. Перед ним помещается строка, содержащая: имя исходного файла RCS, номер версии, идентификатор пользователя и дата записи.
$Revision$
Номер версии.
$Source$
Полное имя исходного файла RCS.
$State$
Статус версии, присвоенный командой ci.

    В заключении приведем более детальное описание команд co и ci. Формат командной строки для co выглядит следующим образом:

co [options] file . . .

    Параметр file командной строки задает имя "рабочего" или файла RCS. Параметр options служит для указания ключей, определяющих режим работы команды.

    При задании имен файлов в команде co возможны три случая, указанные ниже.

  1. Заданы как файл RCS, так и "рабочий" файл. Имя первого имеет вид: "path1/workfile,v", а имя второго задано в форме "path2/workfile", где "path1/" и "path2/" являются полными именами директорий, а "workfile" - имя самого файла.
  2. Задан только файл RCS. Тогда предполагается, что "рабочий" файл находится в текущей директории, а его имя получается из имени файла RCS удалением "path1/" и суффикса ",v".
  3. Задан только "рабочий" файл. В этом случае имя файла RCS получается из имени "рабочего" файла удалением "path2/" и добавкой суффикса ",v".

    Если полное имя файла RCS не задано или приведено не полностью (т.е. не указано точное положение файла в файловой системе), команда пытается найти его в директории, заданной переменной среды RCS. Если она не определена, то файл ищется в директории "./RCS" и, если такая отсутствует, или в ней нет требуемого файла, то поиск осуществляется в текущей директории.

    Выбор версии файла может производится по номеру, времени создания, автору или статусу. При отсутствии указаний о том, какую версию файла требуется получить, выдается последняя версия. Если задано несколько условий поиска, выбирается "старшая" из множества подходящих версий. Указание даты, автора или статуса может использоваться при поиске необходимой версии какой-либо ветви дерева. При этом берется либо указанная ветвь, либо, если она не задана, самая "старшая" ветвь во всем дереве версий. Имя или номер искомой модификации можно указывать при задании ключей: "-l", "-p", "-q" и "-r" (см. ниже).

    Список ключей команды co и правила их использования следующие.

-l [rev]
Зарезервировать право модификации данной версии только за текущим пользователем. Правила задания номера или имени версии приведены при описании ключа "-r"
-p [rev]
Выдавать найденную версию в стандартный файл вывода. "Рабочий" файл не создается.
-q [rev]
Неинтерактивный режим. Диагностические сообщения на дисплей не выдаются.
-ddate
Выдать версию; дата создания задана параметром date. Если искомая версия отсутствует, выдается "старшая" версия из созданных до указанной даты. Дата может задаваться в любом формате, допустимом в системе UNIX.
-r [rev]
Получить версию с номером rev. Если таковая отсутствует, выдается "старшая" из множества версий с меньшими номерами. Номер версии состоит из последовательности полей, разделенных символом '.' (точка). Каждое поле содержит либо номер, либо символьное имя, которое может присваиваться пользователем с помощью ключа "-n" в команде ci.
-sstate
Выдать "старшую" версию, имеющую статус state. Статус файла задается при записи файла в архив командой ci (ключ "-s").
-w [login]
Выдать "старшую" версию, записанную пользователем с именем login. Если имя пользователя опущено, поиск осуществляется среди версий, записанных пользователем, выполнившим команду co.

    Команда ci, как было уже сказано выше, записывает новые версии "рабочих" файлов в файлы системы RCS. Формат командной строки ci следующий:

ci [ options ] file . . .

    Указываемые параметры и правила поиска "рабочих" и файлов RCS те же, что и в командной строке co.

    Для работы с командой ci может быть необходимо включить в список доступа к соответствующему файлу регистрационное имя пользователя. Эта операция выполняется командой rcs ( ключ "-a"). Она производится, если список доступа пуст, пользователь не является администратором системы (суперпользователем) и не является владельцем файла.

    Для того чтобы добавить новую версию, "старшая" из них должна быть заблокирована пользователем. В противном случае может создаваться только новая ветвь версий. Это ограничение не распространяется на владельца файла. Блокировка, установленная кем-то другим, может быть снята, как было сказано ранее, с помощью команды "rcs -l"'.

    Как правило, команда ci проверяет, отличается ли вновь записываемая версия от предыдущей. Если различий не обнаружено, запись не производится. Пользователю выдается соответствующее сообщение с запросом о необходимости внесения файла в RCS.

    При попытке записать версию, команда ci требует ввести краткий комментарии, который должен отражать суть внесенных изменений и заканчиваться либо отдельно стоящей '.' либо нажатием <Ctrl+D>. Если файл RCS не существует, ci создает его (по умолчанию этой версии присваивается номер 1.1). При этом заводится пустой список доступа.

    При записи файлов в архив системы RCS используются ключи, перечисленные ниже.

-r [rev]
Присвоить записанной версии файла номер rev, снять блокировку, уничтожить "рабочий" файл.
-f [rev]
Принудительная запись. Новая версия записывается без возможных дополнительных сообщений.
-l [rev]
Выполняет функции, аналогичные функциям ключа "-r", но для сохраняемой версии дополнительно исполняется команда co с ключом "-l".
-q [rev]
Неинтерактивный режим. Диагностических сообщений не выдается .
-mmsg
Использует строку msg в качестве комментария для всех заносимых версий.
-sstate
Устанавливает статус записываемой версии state. По умолчанию версия получает статус "Exp" (экспериментальная).

    Команда rcs используется для создания новых файлов RCS или замены атрибутов существующих файлов. Каждый файл RCS содержит: версии "рабочего" файла, список доступа, сообщения об изменениях, комментарии и набор атрибутов.

    Для использования команды rcs, как и в случае ci, может быть необходимо включить в список доступа соответствующего файла регистрационное имя пользователя.

    Формат командной строки команды rcs:

rcs [ options ] file . . .

    В качестве входных файлов используются файлы RCS. Ключи команды rcs перечислены ниже.

-i
Создать и инициализировать пустой файл RCS. Если не задано полное имя файла RCS, система пытается разместить его в директории "./RCS". Если она отсутствует, файл создается в текущей директории. Если указанный файл RCS уже существует, выдается сообщение об ошибке.
-alogins
Добавить указанные идентификаторы пользователей (logins) в список доступа архивного файла. В качестве разделителя в строке logins используется запятая.
-e [logins]
Исключить имена пользователей из списка доступа заданного архивного файла. Если имена пользователей не указаны, из списка доступа исключаются все имена.
-l [rev]
Блокировать версию rev. Если номер версии (rev) не указан, подразумевается "старшая" версия.
-L
Включить механизм блокировки. При работе в данном режиме владелец файла RCS не освобождается от обязанности блокировать версию для последующей записи ее модификаций. Этот режим необходим, если изменением файла занимается несколько пользователей.
-U
Выключить механизм блокировки. В данном режиме владелец файла может записывать новые версии без предварительного блокирования.