CVS.Система управления параллельными версиями

         

Проверка журнальных записей


Когда вы ввели журнальное сообщение, вы можете проверить его, чтобы убедиться, что в нем представлена вся необходимая информация, такая, как номера исправленных ошибок и т. п.

Файл `verifymsg' полезнее всего использовать вместе с файлом `rcsinfo', который используется в качестве шаблона журнального сообщения.

Каждая строка в файле `verifymsg' состоит из регулярного сообщения и шаблона команды. В шаблоне должно присутствовать имя программы и, возможно, несколько аргументов. К шаблону добавляется полный имя файла с шаблоном журнального сообщения.

Следует заметить, что ключевое слово `ALL' не поддерживается. Если найдено более одной совпадающей строки, используется первая. Это полезно для указания скрипта проверки, используемого по умолчанию, а затем переопределения его в подкаталоге.

Если имя репозитория не совпадает ни с одним регулярным выражением в этом файле, то используется строка `DEFAULT', если она есть.

Если проверочный скрипт завершается с ненулевым кодом завершения, то процесс фиксирования завершается.

Заметьте, что скрипт верификации не может изменять журнальное сообщение, но лишь принимать или отвергать его.

Вот простой пример файла `verifymsg', использующегося вместе с соответствующим шаблоном журнальной записи в файле `rcsinfo' и скриптом проверки этой записи. Сначала --- шаблон журнальной записи. Нам нужно, чтобы в первой строке этой записи находился номер исправленной ошибки. Остаток журнальной записи -- в свободной форме. Вот такой шаблон находится в файле `/usr/cvssupport/tc.template': BugId:

Скрипт `/usr/cvssupport/bugid.verify' используется для проверки журнального сообщения. #!/bin/sh # # bugid.verify filename # # Verify that the log message contains a valid bugid # on the first line. # if head -1 < $1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then exit 0 else echo "No BugId found." exit 1 fi

Файл `verifymsg' содержит строку: ^tc /usr/cvssupport/bugid.edit

Файл `rcsinfo' содержит такую строку: ^tc /usr/cvssupport/tc.template

Редактирование административных файлов


Административные файлы можно редактировать точно так же, как и любой другой модуль. Используйте `cvs checkout CVSROOT', чтобы получить рабочий каталог, редактируйте его и зафиксируйте изменения обычным образом.

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

Рекурсивное поведение


Почти все подкоманды CVS работают рекурсивно, если вы укажете в качестве аргумента каталог. Например, представим себе такую структуру каталогов: $HOME | +--tc | | +--CVS | (служебные файлы CVS) +--Makefile +--backend.c +--driver.c +--frontend.c +--parser.c +--man | | | +--CVS | | (служебные файлы CVS) | +--tc.1 | +--testing | +--CVS | (служебные файлы CVS) +--testpgm.t +--test2.t

Если `tc' -- это текущий рабочий каталог, то верны следующие утверждения: `cvs update testing' эквивалентно cvs update testing/testpgm.t testing/test2.t `cvs update testing man' обновляет все файлы в подкаталогах `cvs update .' или просто `cvs update' обновляет все файлы в каталоге tc

Если команде update не было дано ни одного аргумента, то она обновит все файлы в текущем рабочем каталоге и во всех его подкаталогах. Другими словами, `.' является аргументом по умолчанию для update. Это также истинно для большинства подкоманд CVS, а не только для команды update.

Рекурсивное поведение подкоманд CVS может быть отключено с помощью ключа командной строки `-l', и наоборот, ключ командной строки `-R' может использоваться для принудительной рекурсии, если `-l' был указан в `~/.cvsrc' (see section Ключи по умолчанию и файл ~/.cvsrc). $ cvs update -l # Не обновлять файлы в подкаталогах

Go to the first, previous, next, last section, table of contents.

Репозиторий


Репозиторий в CVS хранит полные копии всех файлов и каталогов, находящихся под контролем версий.

Обычно вам никогда не придется напрямую обращаться к файлам в репозитории. Вместо этого вы будете использовать команды CVS для получения вашей личной копии файлов в рабочем каталоге, а затем будете работать с этими файлами. Когда вы внесли определенные изменения, вы фиксируете их в репозитории. Теперь в репозитории хранится информация о том, какие изменения вы сделали, включая их точное содержание, время изменения и тому подобную информацию. Заметьте, что репозиторий не является подкаталогом рабочего каталога, и обратное также неверно; они находятся в совершенно разных местах.

CVS может обращаться к репозиторию большим количеством способов. Репозиторий может находиться на локальной машине, на соседней машине или на машине, находящейся на другом континенте. Чтобы различать пути доступа к репозиториям, их имена начинаются с метода доступа. Например, метод доступа `:local:' означает, что репозиторий находится в локальном каталоге, то есть `:local:/usr/local/cvsroot' означает, что репозиторий находится в `/usr/local/cvsroot' на компьютере, на котором используется CVS. Другие методы доступа описаны в section Сетевые репозитории.

Если метод доступа не указан, и имя репозитория не содержит `:', то предполагается метод :local:. Если в имени содержится `:', то предполагается метод доступа :ext: или :server:. Например, если ваш локальный репозиторий находится в `/usr/local/cvsroot', то вы можете использовать /usr/local/cvsroot вместо :local:/usr/local/cvsroot. Но если, например, под Windows NT ваш локальный репозиторий находится в `c:\src\cvsroot', то вы должны указать метод доступа, то есть :local:c:\src\cvsroot.

Репозиторий делится на две части. `$CVSROOT/CVSROOT' содержит административные файлы CVS. Все прочие каталоги содержат модули, определенные пользователем.

Ревизии


В большинстве случаев использования CVS не требуется сильно беспокоиться о номерах ревизий; CVS присваивает номера типа 1.1, 1.2 и т. д., и этого достаточно. Некоторые, однако, хотели бы иметь больше информации и лучше контролировать то, как CVS присваивает номера ревизий.

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

Резервное копирование репозитория


Файлы в репозитории, в сущности, не обладают никакими особыми свойствами, в большинстве случаев можно делать их резервные копии как обычно. Есть, однако, несколько аспектов, которые необходимо учитывать.

Во-первых, с параноидальной точки зрения, следует либо не использовать CVS во время резервного копирования, либо сделать так, чтобы программа резервного копирования блокировала репозиторий в процессе. Чтобы не использовать CVS, вы можете запретить логины на машины, которые могут иметь доступ к репозиторию, отключить CVS-сервер или сделать что-либо подобное. Детали зависят от вашей операционной системы и от настройки CVS. Чтобы заблокировать CVS, создайте файлы блокировок (`#cvs.rfl') в каждом каталоге репозитория. См. section Совместный доступ нескольких разработчиков к CVS за дополнительной информацией о блокировках CVS. Даже учитывая вышесказанное, если вы просто скопируете файлы, ничего особенно страшного не произойдет. Однако, при восстановлении из резервной копии репозиторий может находиться в неустойчивом состоянии, что, впрочем, нетрудно исправить вручную.

Когда вы восстанавливаете репозиторий из резервной копии, предполагая, что репозиторий изменился с момента последнего резервного копирования, рабочие каталоги, которые не пострадали, могут ссылаться на ревизии, не существующие более в репозитории. Попытка выполнения CVS в таких каталогах приведет к сообщению об ошибке. Один из способов вернуть все изменения в репозиторий таков: Получите новый рабочий каталог. Скопируйте файлы из рабочего каталога, сделанного перед аварией, поверх файлов в новом рабочем каталоге (не копируйте содержимое каталогов `CVS'). Работая в новом рабочем каталоге, используйте команды типа cvs update и cvs diff, чтобы выяснить, что изменилось, а затем зафиксируйте изменения в репозиторий.

Режимы подстановки


Вместе с каждым файлом хранится режим подстановки по умолчанию, и каждая копия файла в рабочем каталоге также имеет режим подстановки. Режим по умолчанию задается с помощью ключа `-k' команд cvs add и cvs admin; режим в рабочем каталоге задается с помощью ключей `-k' и `-A' команд cvs checkout и cvs update. Команда cvs diff также имеет ключ `-k'. Некоторые примеры приведены в section Обработка двоичных файлов.

Доступные режимы таковы: `-kkv' Генерировать строки из ключевых слов стандартным образом, то есть из ключевого слова Revision получается $Revision: 5.7 $. `-kkvl' Подобно `-kkv', только всегда указывается имя блокировщика, если данная ревизия в настоящий момент заблокирована. Имя блокировщика имеет смысл только если используется cvs admin -l. `-kk' Генерировать только имена ключевых слов и опускать их значения. Например, для ключевого слова Revision получается строка $Revision$, а не $Revision: 5.7 $. Этот ключ полезен для игнорирования изменения, возникших в результате подстановки ключевых слов, при сравнении разных ревизий файла. `-ko' Генерирует старую строку, присутствовавшую в рабочем файле перед тем, как он был зафиксирован. Например, для ключевого слова Revision генерируется строка $Revision: 1.1 $ вместо $Revision: 5.7 $, если она была записана именно так, когда файл был помещен в репозиторий. `-kb' Подобно `-ko', но также предотвращает преобразование символов конца строк между канонической формой, в которой они хранятся в репозитории (только символ перевода строки), и формой, принятой в используемой операционной системе. Для систем, подобных UNIX, в которых для завершения строк используется символ перевод строки, этот режим совпадает с `-ko'. Дальнейшая информация о двоичных файлах находится в section Обработка двоичных файлов. `-kv' Генерирует только значения ключевых строк. Например, для ключевого слова Revision генерируется строка 5.7 вместо $Revision: 5.7 $. Это может помочь при генерации файлов в языках программирования, в которых сложно отщепить разделители, такие как $Revision: $, от конца строки. Однако, дальнейшая подстановка ключевых слов не может быть осуществлена, когда удалены ключевые слова, поэтому этот ключ нужно использовать осторожно. Часто бывает полезно использовать `-kv' совместно с командой cvs export -- see section Команда export: экспортировать исходные тексты. Помните только, что этот ключ некорректно экспортирует двоичные файлы.

Руководство по командам CVS


В этом приложении описывается общая структура команд CVS, а некоторые команды описываются детально; краткий справочник по командам CVS находится в see section Краткий справочник по командам CVS.

Сетевые репозитории


Рабочая копия исходных текстов и репозиторий могут быть на разных машинах. Использование CVS таким образом известно как режим клиент/сервер. Вы выполняете CVS-клиент на машине, на которой смонтирован ваш рабочий каталог, и говорите ему общаться с машиной, на которой смонтирован репозиторий, с CVS-сервером. Вообще использование сетевого репозитория похоже на использование локального, только формат имени репозитория таков: :метод:пользователь@машина:/путь/к/репозиторию

Детали зависят от того, как вы соединяетесь с сервером.

Если метод не указан, а имя репозитория содержит `:', то метод по умолчанию -- ext или server, в зависимости от платформы; оба метода описаны в section Соединение с помощью rsh.

Слежение за чужими исходными текстами


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

В терминологии, используемой в CVS, поставщик программы называется производителем. Неизмененный комплект поставки помещается на отдельную ветку, которая называется ветка производителя. CVS резервирует для этой цели ветку с номером 1.1.1.

Когда вы изменяете исходный текст и фиксируете его, ваши изменения окажутся в основном стволе. Когда поставщик выпускает новую версию, вы помещаете её на ветку производителя и копируете изменения в основной ствол.

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

Слияние изменений между двумя ревизиями


С помощью двух флагов `-j ревизия', команды update и checkout могут сливать изменения между любыми двумя ревизиями в ваш рабочий файл.

Команда

$ cvs update -j 1.5 -j 1.3 backend.c

отменит изменения, сделанные между ревизиями 1.3 и 1.5. Обратите внимание на порядок указания ревизий!

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

Указав два ключа командной строки `-j', можно также отменить удаления и добавления файлов. Например, предположим, у вас есть файл `file1', существовавший в ревизии 1.1. Затем вы удалили его, создав "мертвую" ревизию 1.2. Теперь предположим, что вы хотите добавить его опять, с тем же самым содержимым, что он имел ранее. Вот как сделать это: $ cvs update -j 1.2 -j 1.1 file1 U file1 $ cvs commit -m test Checking in file1; /tmp/cvs-sanity/cvsroot/first-dir/file1,v

Слияние веток


Вы можете объединить изменения, сделанные на ветке, с вашей рабочей копией, добавив флаг `-j ветка' к команде update. В результате CVS внедряет в рабочую копию изменения, сделанные между ревизией, где отщепилась ветка и свежайшей ревизией на этой ветке.

Ключ командной строки `-j' означает "объединить" (join).

Представьте себе такое дерево ревизий: +-----+ +-----+ +-----+ +-----+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 ! +---! 1.2.2.1 !----! 1.2.2.2 ! +---------+ +---------+

Ветке 1.2.2 была назначена метка (символическое имя) `R1fix'. В нижеследующем примере предполагается, что модуль `mod' содержит единственный файл, `m.c'. $ cvs checkout mod # Извлчеь последнюю ревизию, 1.4 $ cvs update -j R1fix m.c # Слить все изменения, сделанные на ветке, # т. е. изменения между ревизиями 1.2 # и 1.2.2.2, в рабочую копию файла $ cvs commit -m "Included R1fix" # создать ревизию 1.5.

В результате операции слияния может произойти конфликт. В это случае вам сначала надо справиться с ним перед фиксированием изменений. See section Пример конфликта.

Команда checkout также поддерживает флаг `-j ветка'. Можно добиться эффекта, обсуждавшегося выше, с помощью $ cvs checkout -j R1fix mod $ cvs commit -m "Добавлен R1fix"

Соединение с помощью rsh


CVS использует протокол rsh для работы с сетевым репозиторием, поэтому на сетевой машине должен быть создан файл `.rhosts', позволяющий доступ данному пользователю.

Например, предположим, что вы пользователь `mozart' на локальной машине `toe.example.com', а сервер находится на `faun.example.com'. На машине `faun' поместите в файл `.rhosts' в домашнем каталоге пользователя `bach' следующее: toe.example.com mozart

Потом протестируйте, что rsh работает, запустив rsh -l bach faun.example.org 'echo $PATH'

Затем вам следует убедиться, что rsh найдет сервер. Убедитесь, что путь, напечатанный в результате выполнения этого примера содержит каталог, содержащий исполняемый файл `cvs', который является серверной версией CVS. Вы можете установить путь в `.bashrc', `.cshrc', и т. п., но не в файлах `.login' или `.profile'. Можно также установить переменную среды CVS_SERVER на клиентской машине, чтобы указать, какой исполняемый файл вы хотите использовать, например, `/usr/local/bin/cvs-1.6'.

Не требуется редактировать `inetd.conf', чтобы запустить CVS как демона.

Вы можете использовать в CVSROOT два метода доступа для rsh. :server: задает использование внутреннего клиента rsh, который поддерживается только в некоторых портах CVS. :ext: указывает внешнюю программу rsh. По умолчанию это rsh, но вы можете установить переменную среды CVS_RSH, чтобы выполнять другую программу, которая может соединиться с сервером (например, remsh на HP-UX 9, потому что rsh немного отличается. Эта программа должна уметь пересылать данные с сервера и на сервер, не изменяя их; например, rsh из Windows NT не подходит, потому что он транслирует CR-LF в LF. Порт CVS для OS/2 содержит хэк, который передает rsh параметр `-b', чтобы обойти это,но так как это может привести к проблемам с программами, не являющимися стандартным rsh, это может быть изменено в будущем. Если вы устанавливаете CVS_RSH в ssh или какую-нибудь другую замену rsh, то инструкции по настройке `.rhosts', скорее всего, неприменимы, поэтому обратитесь к документации по соответствующей программе.

Продолжая наш пример, предположив, что вы хотите обратиться к модулю `foo' в репозитории `/usr/local/cvsroot' на машине `faun.example.org', вы набираете: cvs -d :ext:bach@faun.example.org:/usr/local/cvsroot checkout foo

(Можно не писать `bach@', если имена пользователей совпадают на локальной и сетевой машинах.)

Сообщения команды output


Команда import сообщает вам о своей деятельности, печатая строку на каждый файл, в начале которой находится один символ, сообщающий о статусе файла: U file Файл уже существует в репозитории и не был локально изменен; будет создана новая ревизия, если нужно. N file Это новый файл и теперь он добавлен в репозиторий. C file Файл уже существует в репозитории, но был изменен локально, поэтому вам потребуется объединить изменения. I file Файл игнорируется (see section Игнорирование файлов с помощью cvsignore). L file Файл является символической ссылкой; cvs import игнорирует символические ссылки. Периодически предлагается изменить это поведение, но нет четкого соглашения, как именно. (Различные ключ в файле `modules' могут использоваться для воссоздания символических ссылок при извлечении, обновлении и т. п.; see section Файл `modules').

Сообщения команды release


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

Предупреждение: Все каталоги, которые вы создали, но не добавили в репозиторий с помощью команды add (see section Добавление файлов в каталог), будут бесшумно проигнорированы (и удалены, если был указан флаг `-d'), даже если эти каталоги содержат файлы. U file P file В репозитории существует новая ревизия этого файла, а вы изменили его рабочую копию (`U' и `P' означают одно и то же). A file Файл был добавлен в ваш рабочий каталог, но еще не был помещен в репозиторий. Если вы удаляете вашу копию исходных текстов, то этот файл будет потерян. R file Файл был удален из вашего рабочего каталога, но еще не был удале из репозитория, потому что вы еще не зафиксировали удаление. See section Команды commit: поместить файлы в репозиторий. M file Файл изменен в рабочем каталоге. В репозитории также может быть более новая ревизия. ? file file находится в рабочем каталоге, но не соответствует ни одному файлу в репозитории, и не находится в списке файлов, которые нужно игнорировать (см. описание ключа `-I' и see section Игнорирование файлов с помощью cvsignore). Если вы удалите рабочий каталог, изменения будут потеряны.

Сообщения команды update


Команды update и checkout информируют о своей деятельности, печатая строчку на каждый обработанный файл. Первый символ означает статус этого файла: U file Файл был обновлен из репозитория. Обновление производится: для файлов, существующих в репозитории, но не в вашем рабочем каталоге; для файлов, которые вы не изменяли, и для которых в репозитории существует более свежая ревизия. P file Похоже на `U', но для этого файла CVS-сервер посылает файл с исправлениями вместо целого файла. Результирующий файл оказывается тем же самым. A file Файл был добавлен в вашем рабочем каталоге, и будет помещен в репозиторий, когда вы выполните команду commit. Это сообщение -- напоминание о том, что файл требуется зафиксировать. R file Файл был удален из вашей личной копии исходников, и будет удален из репозитория, когда вы выполните команду commit. Это сообщение -- напоминание о том, что файл требуется зафиксировать. M file Файл был изменен в вашем рабочем каталоге. `M' может означать одно из двух состояний файла, над которым вы работаете: либо этот файл не менялся в репозитории, и поэтому остался неизменным в результате выполнения команды update, либо же файл изменился как в рабочем каталоге, так и в репозитории, но слияние изменений в ваш рабочий файл прошло успешно, без конфликтов. CVS выдает некоторые сообщения, когда сливает изменения, и оставляет резервную копию рабочего файла (как он выглядел перед выполнением update). Точное имя этого файла печатается во время работы update. C file При попытке объединить изменения из репозитория в вашу рабочую копию файла был обнаружен конфликт. file (ваша рабочая копия) теперь является результатом попытки объединить две ревизии; неизмененная копия файла также находится в рабочем каталоге, с именем `.#file.revision', где revision -- это ревизия, на которой был основан измененный вами файл. Разрешение конфликтов описано в section Пример конфликта. (Заметьте, что некоторые системы автоматически удаляют файлы, начинающиеся с `.#', если к этим файлам не было обращений в течение нескольких дней. Если вы хотите сохранить копию исходного файла, переименуйте его.) Под VMS имя файла начинается с `__', а не с `.#'. ? file file находится в вашем рабочем каталоге, но не соответствует ни одному файлу в репозитории, и не находится в списке файлов, которые нужно игнорировать (см. описание ключа `-I' и see section Игнорирование файлов с помощью cvsignore).

Go to the first, previous, next, last section, table of contents.

Совместимость между версиями CVS


Формат репозитория совместим со старыми версиями вплоть до CVS 1.3. Обратитесь к section Использование слежений со старыми версиями CVS, если у вас есть копии CVS 1.6 или раньше, и вы хотите использовать новые возможности для общения разработчиков.

Формат рабочего каталога совместим с версиями вплоть до CVS 1.5. Этот формат изменился между версиями CVS 1.3 и CVS 1.5. Если вы используете CVS 1.5 или новее в рабочем каталоге, извлеченном с помощью CVS 1.3, то произойдет автоматическая конвертация, но для того, чтобы вернуться обратно к CVS 1.3, нужно извлечь новый рабочий каталог с помощью CVS 1.3.

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

Go to the first, previous, next, last section, table of contents.

Совместный доступ нескольких разработчиков к CVS


Если несколько разработчиков попытаются одновременно выполнить CVS, один из них получит такое сообщение: [11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo

CVS попытается повторить операцию каждые 30 секунд, и либо успешно выполнит ее, либо опять напечатает сообщение, если опять нужно ждать. Если блокировка сохраняется слишком долго, найдите того, кто создал ее и спросите его, что за команду он выполняет. Если он не выполняет команд CVS, загляните в каталог репозитория, упомянутый в сообщении, и удалите файлы, чьи имена начинаются с `#cvs.rfl', `#cvs.wfl', или `#cvs.lock', принадлежащие указанному пользователю.

Заметьте, что эти блокировки предназначаются для защиты внутренних структур данных CVS и не имеют никакого отношения к слову блокировка в том смысле, который используется в RCS и означает блокированные извлечения (see section Несколько разработчиков).

Неограниченное количество пользователей может одновременно читать репозиторий; только когда кто-либо пишет туда, блокировки препятствуют прочим как читать, так и писать.

Можно было бы надеяться, что верно следующее утверждение: Если кто-либо фиксирует несколько изменений одной командой CVS, то команда update, выполненная кем-то еще, получит либо все изменения, либо ни одно из них.

К сожалению, при работе с CVS это утверждение неверно. Например, если имеются файлы a/one.c a/two.c b/three.c b/four.c

и кто-то выполняет cvs ci a/two.c b/three.c

а затем кто-то еще в то же самое время выполняет cvs update, то он может получить изменения для `b/three.c', и не получить изменения в `a/two.c'.

Создание дерева каталогов из нескольких файлов


Когда вы начнете использовать CVS, вы, скорее всего, уже имеете несколько проектов, которые можно поместить под контроль CVS. В этих случаях самым простым методом будет использование команды import. Самым простым объяснением, вероятно, будет привести пример. Если файлы, которые вы хотите поместить под CVS, находятся в `wdir', а вы хотите, чтобы они появились в репозитории в каталоге `$CVSROOT/yoyodyne/rdir', вы можете сказать: $ cd wdir $ cvs import -m "Imported sources" yoyodyne/rdir yoyo start

Если вы не укажете журнальное сообщение с помощью ключа командной строки `-m', то CVS запустит редактор, в котором можно будет набрать это сообщение. Строка `yoyo' -- это тэг производителя, а `start' -- это тэг релиза. В данном контексте они могут не иметь назначения, но CVS требует их присутствия. See section Слежение за чужими исходными текстами, за дальнейшей информацией.

Теперь вы можете проверить, что все работает и удалить ваш исходный каталог. $ cd .. $ mv dir dir.orig $ cvs checkout yoyodyne/dir # объяснение следует $ diff -r dir.orig yoyodyne/dir $ rm -r dir.orig

Было бы неплохо удалить изначальные файлы, чтобы случайно не начать редактировать их в dir без использования CVS. Конечно же, перед удалением хорошо было бы убедиться, что у вас есть резервная копия исходных текстов.

Команда checkout получает в качестве аргумента имя модуля (как в предыдущих примерах) или имя каталога относительно $CVSROOT, как в вышеприведенном примере.

Хорошо было бы проверить, что права доступа на созданные CVS каталоги правильны, и что эти каталоги принадлежат должным группам. See section Права доступа к файлам

Если какие-то из файлов, которые нужно импортировать, являются бинарными, вам потребуется использовать обертки, чтобы указать, какие именно. See section Файл `cvswrappers'.

Создание дерева каталогов с нуля


Для нового проекта самоым простым способом, вероятно, будет создать пустую структуру каталогов, например: $ mkdir tc $ mkdir tc/man $ mkdir tc/testing

Затем используйте команду import, чтобы создать соответствующую (пустую) структуру каталогов внутри репозитория: $ cd tc $ cvs import -m "Created directory structure" yoyodyne/dir yoyo start

Затем используйте команду add, чтобы добавлять файлы и новые каталог по мере их появления.

Убедитесь, что права доступа, которые CVS дает новым каталогам в `$CVSROOT', правильны.

Создание файлов из других систем контроля версий


Если у вас есть проект, который обслуживается другой системой контроля версий, например, RCS, вы можете захотеть поместить эти файлы под управление CVS и сохранить историю изменения этих файлов. Из RCS Если вы использовали RCS, найдите все RCS-файлы, обычно файлу `foo.c' будет соответствовать файл `RCS/foo.c,v' (этот файл может также находиться в другом месте, обратитесь к документации на RCS. Затем создайте соответствующие каталоги в CVS, если они еще не существуют. Затем скопируйте файл в соответствующие каталоги в репозитории (имя в репозитории должно совпадать с именем исходного файла с добавленным `,v'; файлы находятся прямо в соответствующем каталоге репозитория, а не в подкаталоге `RCS/'. Это --- один из редких случаев, когда желателен прямой доступ к репозиторию, без использования команд CVS. Теперь вы можете извлечь новый рабочий каталог. RCS-файл не должен быть заблокирован, когда вы перемещаете его под управление CVS, иначе у CVS будут проблемы при работе с этим файлом. Из другой системы контроля версий Многие системы контроля версий способны экспортировать RCS-файлы в стандартном формате. Если ваша система умеет так делать, экспортируйте RCS-файлы и следуйте вышеприведенным инструкциям. Если это не так, вероятно, лучшим выходом будет написать скрипт, который извлекает каждую ревизию файла, используя интерфейс командной строки старой системы, а затем фиксирующий эти ревизии в CVS. Скрипт `sccs2rcs', упомянутый ниже, является хорошим примером. Из SCCS В каталоге `contrib/' среди исходных текстов CVS есть скрипт `sccs2rcs', конвертирующий файлы SCCS в файлы RCS. Замечание: вы должны выполнить этот скрипт на машине, на которой установлен как SCCS, так и RCS, и этот скрипт не поддерживается. Из PVCS В каталоге `contrib/' среди исходных текстов CVS есть скрипт `pvcs_to_rcs', конвертирующий архивы PVCS в файлы RCS. Вы должны выполнить этот скрипт на машине, на которой установлены как PVCS, так и RCS, и как и все прочее в каталоге `contrib/', этот скрипт не поддерживается. Детали описаны в комментариях к скрипту.

Создание репозитория


Чтобы настроить CVS-репозиторий, сначала выберите машину и диск, на котором будет храниться история ревизий исходных текстов. Требования к процессору и памяти умеренны, поэтому подойдет практически любая машина. Детали описаны в section Требования к серверу.

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

К репозиторию должен быть доступ (прямой или с помощью сетевой файловой системы) со всех машин, которые будут использовать CVS в серверном или локальном режиме; клиентские машины не требуют никакого доступа к репозиторию кроме протокола CVS. Использование CVS для доступа только для чтения все равно требует прав на запись в репозиторий для создания файлов блокировок (see section Совместный доступ нескольких разработчиков к CVS).

Чтобы создать репозиторий, выполните команду cvs init. Она создаст пустой репозиторий в корневом каталоге CVS, заданном обычным образом (see section Репозиторий). Например, cvs -d /usr/local/cvsroot init

cvs init следит, чтобы не перезаписать уже существующие файлы, поэтому никакого вреда от запуска cvs init по уже настроенному репозиторию не произойдет.

cvs init включит журналирование истории; если вы не хотите этого, удалите файл истории после выполнения cvs init. See section Файл history.

Создание ветки после редактирования


Предположим, вы работали над каким-то крайне экспериментальным продуктом, основанным на какой-то ревизии, извлеченной из репозитория неделю назад. Если кто-либо еще в вашей группе захочет вместе с вами работать над этим продуктом, не мешая при этом основному направлению разработки, то вы можете зафиксировать изменения в новую ветку. Другие смогут извлечь результаты вашего эксперимента и воспользоваться автоматическим исправлением конфликтов с помощью CVS. Сценарий таков: [[ hacked sources are present ]] $ cvs tag -b EXPR1 $ cvs update -r EXPR1 $ cvs commit

После команды update ключ `-r EXPR1' прилипнет ко всем файлам. Заметьте, что ваши изменения в файлах никогда не будут удалены командой update. Команда commit автоматически поместит изменения на правильную ветку, потому что ключ `-r' является липким. Вы также можете сделать так: [[ hacked sources are present ]] $ cvs tag -b EXPR1 $ cvs commit -r EXPR1

но в этом случае только те файлы, которые вы изменили, будут иметь прилепленный флаг `-r EXPR1'. Если вы поредактируете еще какие-либо файлы и зафиксируете их без указания флага `-r EXPR1', то эти файлы могут случайно оказаться в главном стволе.

Для того, чтобы работать вместе с вами над экспериментальной версией, другием могут просто сказать: $ cvs checkout -r EXPR1 whatever_module

Создание ветвей и слияние


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

Позже вы можете переместить изменения с одной ветки на другую или же с ветки в ствол, это называется слиянием. Сначала выполняется cvs update -j, чтобы слить изменения в рабочий каталог, а затем эти изменения фиксируются, что приводит к копированию изменения в другую ветку.

Создание ветви


Вы можете создать ветвь, используя tag -b. Например, предполагая, что вы находитесь в каталоге с рабочей копией: $ cvs tag -b rel-1-0-patches

Это отщепляет ветку, основанную на текущей ревизии рабочей копии, и присваивает этой ветке имя `rel-1-0-patches'.

Важно понимать, что ветки создаются в репозитории, а не в рабочей копии. Создание ветки, основанной на текущей ревизии, как в вышеприведенном примере, НЕ переключает рабочую копию на использование ветки (как сделать это -- описано в section Доступ к веткам).

Можно также создать ветку вообще без использования рабочей копии, используя rtag. $ cvs rtag -b -r rel-1-0 rel-1-0-patches tc

`-r rel-1-0' означает, что эта ветка имеет корневую ревизию, соответствующую метке `rel-1-0'. Это не обязательно должна быть самая последняя ревизия: довольно часто бывает полезно отщепить ветку от старой ревизии (например, для исправления ошибки в старой версии, которая в основном стабильна).

Как и в случае с `tag', ключ командной строки `-b' заставляет rtag создать ветку (а не алфавитное имя ревизии). Заметьте, что номера ревизий, соответствующих `rel-1-0', скорее всего, будут различаться от файла к файлу.

Таким образом, полный эффект этой команды -- создать новую ветку, которая называется `rel-1-0-patches', в модуле `tc', которая растет в дереве ревизий из точки, помеченной как `rel-1-0'.

Специальные файлы


В обычных условиях CVS работает только с обычными файлами. Какждый файл в проекте считается устойчивым: его можно открыть, прочесть и закрыть, и делать это несколько раз. CVS также игнорирует права доступа и владельцев файлов, предоставляя разработчику решать такие вопросы во время инсталляции. Другими словами, нельзя "поместить" устройство в репозиторий; если устройство не может быть открыто, CVS откажется обрабатывать его. Файлы также могут потерять права доступа и владельцев во время транзакций в репозитории.

Если в репозитории установлена переменная PreservePermissions (see section Файл конфигурации CVSROOT/config), то CVS сохранит в репозитории такие характеристики файлов: пользователь- и группа-владелец файла права доступа основной и вспомогательный номер устройства символические ссылки структуру жестких ссылок

Использование опции PreservePermissions влияет на поведение CVS в нескольких местах. Во-первых, некоторые новые операции, поддерживаемые CVS не доступны всем пользователям. В частности, владельцы файла и характеристики специальных файлов могут изменяться только суперпользователем. Таким образом, когда переменная конфигурации PreservePermissions установлена, пользователи должны стать пользователем root, чтобы выполнять операции с CVS.

Когда используется PreservePermission, некоторые операции CVS (такие, как `cvs status'), не смогут определить структуру жестких ссылок файла, и будут выдавать предупреждения о несовпадающих жестких ссылках. Причиной этого является то, что внутренние структуры CVS не обеспечивают простого способа собрать всю информацию о жестких ссылках, поэтому они проверяют конфликты файлов, пользуясь неточными данными.

Более тонким различием является то, что CVS считает, что файл изменился, только если изменилось его содержимое (особенно если время модификации рабочего файла не совпадает с временем модификации файла в репозитории). Таким образом, если у файла изменились только права доступа, владелец, или основной и вспомогательный номера устройства, то CVS не заметит этого.
Для того, чтобы принудительно поместить такое изменение в репозиторий, используйте ключ `-f' команды `cvs commit'. Это также означает, что если права доступа файла изменились, а файл в репозитории новее, чем рабочая копия, то выполнение `cvs update' просто изменит права доступа на рабочей копии. Изменение жестких ссылок в репозитории CVS является особенно тонкой процедурой. Предположим, что файл `foo' был связан с файлом `old', а затем связан с файлом `new'. Вы можете попасть в необычную ситуацию, когда несмотря на то, что у `foo', `old' и `new' изменилось количество жестких ссылок, только файлы `foo' и `new' были изменены, поэтому `old' не является кандидатом на фиксирование в репозитории. Таким образом можно прийти к результатам, несоответствующим действительности. Если необходимо хранить в репозитории жесткие ссылки, мы рекомендуем применять команду touch ко всем файлам, чьи ссылки или статус изменились со времени последней фиксации. В действительности, было бы правильным выполнять touch * перед каждой фиксацией, если в каталоге находится сложная система ссылок на файлы. Стоит заметить, что только обычные файлы могут быть объединены, по причинам, которые, надеемся, очевидны. Если `cvs update' или `cvs checkout -j' попытаются объединить символическую ссылку с обычным файлом, или два файла устройств друг с другом, то CVS сообщит о конфликте и откажется производить объединение. В то же самое время `cvs diff' не сообщит о различиях между этими файлами, потому что с файлами, не содержащими текста, нельзя совершать текстуальные сравнения. Параметр PreservePermissions не работает с клиент-серверной версией CVS. Другим ограничением является то, что жесткие ссылки должны быть между файлами, находящимися в одном каталоге; жесткие ссылки между разными каталогами не поддерживаются. Go to the first, previous, next, last section, table of contents.

Специфические для Windows права доступа


Некоторые вопросы, связанные с правами доступа, специфичны для операционных систем класса Window (Windows 95/98, Windows NT и, скорее всего, будущие подобные операционные системы. Часть нижесказанного может быть применима к OS/2, хотя я не уверен).

Список ключевых слов


Вот список ключевых слов: $Author$ Имя пользователя, который поместил ревизию в репозиторий. $Date$ Дата и время (в UTC), когда была зафиксирована ревизия. $Header$ Стандартный заголовок, содержащий полное имя RCS-файла, номер ревизии, дату в UTC, имя автора, состояние и имя блокировавшего этот файл (если файл заблокирован). Файлы обычно не блокируются при использовании CVS. $Id$ Точно так же, как $Header$, только имя RCS-файла указано без полного пути. $Name$ Имя метки, использованной при извлечении этого файла. Это ключевое слово заменяется только если при извлечении было явно задано имя метки. Например, при выполнении команды cvs co -r first это ключевое слово заменяется на `Name: first'. $Locker$ Имя пользователя, который заблокировал эту ревизию (пустое, если файл не заблокирован, как обычно и бывает, если не использовалась команда cvs admin -l). $Log$ Журнальное сообщение, которое было введено во время фиксации изменений, перед которым идет имя RCS-файла, номер ревизии, имя автора и дата в UTC. Существующие журнальные сообшения не заменяются. Вместо этого, новое журнальное сообщение добавляется после $Log:...$. Каждая новая строка содержит в начале ту же самую строку, которая находится перед ключевым словом $Log$. Например, если в файле находится /* Here is what people have been up to: * * $Log: frob.c,v $ * Revision 1.1 1997/01/03 14:23:51 joe * Add the superfrobnicate option * */ то перед дополнительными строками, которые добавляются при замене ключевого слова $Log$, будет находиться ` * '. В отличие от предыдущих версий CVS и RCS, префикс комментария из RCS-файла не используется. Ключевое слово $Log полезно при накоплении полного журнала изменений в исходном файле, но по нескольким причинам это может привести к определенным проблемам. See section Проблемы с ключевым словом $Log$.. $RCSfile$ Имя RCS-файла без полного пути. $Revision$ Номер ревизии. $Source$ Полное имя RCS-файла. $State$ Состояние, присвоенное ревизии. Состояния могут назначаться с помощью cvs admin -s -- см. section Ключи команды admin.

Справочник по административным файлам


В репозитории CVS в каталоге `$CVSROOT/CVSROOT/' находится несколько вспомогательных файлов. При работе с CVS эти файлы можно и не использовать, но, будучи правильно настроенными, они способны сильно облегчить вам жизнь. Методика редактирования таких файлов обсуждается в section Справочник по административным файлам.

Самым важным таким файлом является `modules', которые описывает модули, находящиеся в репозитории.

Стандартные ключи командной строки


В этой главе описываются `ключи_команды', доступные для использования с несколькими командами CVS. Эти ключи всегда задаются справа от имени `команды_CVS'. Не все команды поддерживают эти ключи, но лишь те, для которых ключ имеет смысл. Однако, если команда имеет один из этих ключей, вы можете быть уверены в одинаковом поведении этих ключей с разными командами. (Другие ключи команд, описанные вместе с отдельными командами, могут иметь различное поведение с разными командами CVS).

Предупреждение: команда `history' является исключением, она поддерживает различные ключи, конфликтующие даже со стандартными ключами.

@macro std-option-f -f Если не найдено совпадающей ревизии, извлечь самую свежую ревизию (а не игнорировать файл). @macro std-option-l -l Не обходить дерево каталогов, работать только в текущем рабочем каталоге. @macro std-option-R{verb} -R \verb\ каталоги рекурсивно. По умолчанию это именно так. См. section Рекурсивное поведение. -D дата Использовать самую свежую ревизию, сделанную не позже чем дата. В данном случае дата -- это одиночный аргумент, являющийся описанием прошедшей даты. Указанная дата становится липкой, когда вы используете её, чтобы сделать копию файла с исходным текстом, то есть, когда вы извлекаете рабочий файл, используя `-D', то CVS запоминает указанную дату, так что последующие команды обновления, выполненные в том же каталоге, будут использовать ту же дату (дальнейшая информация по липким меткам и датам находится в see section Липкие метки). Ключ `-D' доступен совместно с командами checkout, diff, export, history, rdiff, rtag и update. (Команда history использует этот ключ немного отличающимся способом; see section Ключи команды history). CVS поддерживает большое множество форматов даты. Самыми стандартными являются ISO-8601 (от Международной Организации по Стандартизации) и стандарт электронной почты (описанные в RFC822, с поправками в RFC1123). Даты в формате ISO-8601 имеют множество вариантов, но вот несколько примеров: 1972-09-24 1972-09-24 20:05 Вероятно, вы совсем не желаете увидеть перечисление полного списка форматов, описанных в ISO8601 :-).
Вдобавок к датам, разрешенным в электронной почте в Интернет, CVS также позволяет пропускать некоторые поля. Например: 24 Sep 1972 20:05 24 Sep Считается, что дата находится в местной временн'ой зоне, если только таковая не задана явно. Предпочтительными являются два формата представления данных. Однако же, CVS в настоящее время поддерживает широкий диапазон других форматов представления даты. Они нарочно не документируются здесь, а будущие версии CVS могут уже не поддерживать их. Одним из таких форматов является месяц/день/год. Такой взаимный порядок дня и месяца может смутить некоторых, например, `1/4/96' --- это четвертое января, а не первое апреля. Не забудьте написать аргумент команды `-D' в кавычках, чтобы ваша оболочка не посчитала пробелы разделителями аргументов. Команда, использующая ключ `-D', может выглядеть так: $ cvs diff -D "1 hour ago" cvs.texinfo -f Когда вы задаёте команде CVS конкретную дату или метку, то эта команда обычно игнорирует файлы, не содержащие заданной метки (или не существовавшие на указанный момент времени). Используйте ключ `-f', если вы хотите, чтобы файлы извлекались, даже если они не совпадают с меткой или со временем, в этом случае будет использована самая свежая ревизия файла. `-f' доступна с командами annotate, checkout, export, rdiff, rtag, и update. Предупреждение: Команды commit и remove также имеют ключ `-f', но он имеет другое поведение. Смотри section Ключи команды commit и section Удаление файлов. -k kflag Изменить обработку ключевых слов по умолчанию. See section Подстановка ключевых слов, о значении kflag. Указанное значение kflag становится липким, когда вы создаёте личную копию файла. Это означает, что когда вы используете этот ключ вместе с командами checkout или update, то CVS связывает значение kflag с файлом, и использует это значение при последующих командах обновления этого файла, если вы не укажете обратного. Ключ `-k' доступен с командами add, checkout, diff, import и update. @std-option-l Предупреждение: это не тот глобальный ключ `-l', который вы указываете слева от команды CVS! Доступен с командами annotate, checkout, commit, diff, edit, editors, export, log, rdiff, remove, rtag, status, tag, unedit, update, watch, и watchers. -m "сообщение" Использовать "сообщение" в качестве журнальной записи, вместо того, чтобы запустить редактор.


Флаг доступен с командами add, commit и import. -n Не выполнять соответствующие программы при выполнении команд `checkout', `commit' и `tag'. (В базе данных модулей могут быть указаны программы, которые нужно выполнить при выполнении одной из этих команд, а этот ключ используется для того, чтобы избежать этого). Предупреждение: этот флаг -- не тот глобальный флаг `cvs -n', который задаётся слева от команды CVS! Флаг доступен с командами checkout, commit, export и rtag. -P Удалять пустые каталоги. См. section Удаление каталогов. -p Выдать файлы, извлеченные из репозитория, на стандартный вывод, а не записывать их в текущем каталоге. Флаг доступен с командами checkout и update. -R Рекурсивно обрабатывать каталоги. Включено по умолчанию. Доступно с командами annotate, checkout, commit, diff, edit, editors, export, rdiff, remove, rtag, status, tag, unedit, update, watch и watchers. -r метка Использовать ревизию, указанную в параметре метка, вместо головной ревизии (HEAD) по умолчанию. Помимо меток, созданных с помощью команд tag и rtag, всегда доступны две специальные метки: `HEAD' ссылается на самую свежую ревизию, находящуюся в репозитории, а `BASE' ссылается на ревизию, которую вы извлекли в текущий рабочий каталог. Указанная метка становится липкой, если вы используете checkout или update, чтобы создать собственную копию файла: CVS запоминает метку и продолжает использовать её при дальнейших командах обновления, пока вы не укажете обратного (дальнейшая информация о липких метках/датах находится в section Липкие метки). Метка может быть номером ревизии или именем. See section Метки ревизий. Задание глобального ключа `-q' вместе с ключом `-r' часто бывает полезным, чтобы избежать предупреждающих сообщений о том, что RCS-файл не содержит указанной метки. Предупреждение: не перепутайте этот ключ с глобальным ключом `cvs -r', который вы пишете слева от команды CVS! Ключ `-r' доступен с командами checkout, commit, diff, history, export, rdiff, rtag и update. -W spec Задаёт имена файлов, которые нужно отфильтровать.Этот ключ можно использовать в командной строке несколько раз. spec может быть шаблоном имени файла, таким же, который можно использовать в файле `.cvswrappers'. Ключ доступен с командами import и update.

Статус файла


Основываясь на операциях, которые производятся над извлеченным файлом, а также на операциях, которые производятся над этим файлом в репозитории, можно классифицировать несколько состояний файла. Команда status рапортует об этих состояниях. Они таковы: Up-to-date Файл идентичен последней ревизии в репозитории, находящейся на используемой ветке. Locally Modified Вы редактировали этот файл и еще не зафиксировали изменения. Locally Added Вы добавили этот файл с помощью cvs add, и еще не зафиксировали изменения. Locally Removed Вы удалили файл с помощью cvs remove и еще не зафиксировали изменения. Needs Checkout Кто-то еще поместил новую ревизию в репозиторий. Название немного сбивает с толку, потому что требуется использовать команду cvs update, а не cvs checkout, чтобы получить свежайшую версию. Needs Patch Похоже на "Needs Checkout", но CVS-сервер пошлет заплату, а не целый файл. В принципе это приведет к тому же самому результату. Needs Merge Кто-то еще поместил новую ревизию в репозиторий, а вы также изменили этот файл. File had conflicts on merge Похоже на "Locally Modified", только последняя выполненная команда cvs update обнаружила конфликт. Если вы еще не исправили его, сделайте это, как описано в section Пример конфликта. Unknown CVS ничего не знает об этом файле. Например, вы создали новый файл и еще не выполнили cvs add.

Чтобы уточнить состояние файла, cvs status также сообщает о Working revision, являющейся ревизией, на основе которой создан файл в рабочем каталоге, и Repository revision, являющейся свежайшей ревизией в репозитории, находящейся на используемой ветке.

Ключи команды status перечислены в section Краткий справочник по командам CVS. Информация о Sticky tag и Sticky date находится в section Липкие метки. Информация о Sticky options находится в описании флага `-k' в section Ключи команды update.

Команды status и update можно рассматривать как соответствующие друг другу. update используется для извлечения самых свежих файлов, а status -- для выяснения, что же произойдет, если выполнить update (конечно, состояние репозитория может измениться до того, как вы выполните update). В действительность, если вы хотите узнать состояние файлов в более краткой форме, выполните

$ cvs -n -q update

Ключ командной строки `-n' указывает не выполнять обновление, а просто сообщить о состоянии файлов; `-q' не печатает имена каждого каталога. Прочуя информацию о команде update можно найти в section Краткий справочник по командам CVS.

Титры


Roland Pesch (roland@wrs.com), когда-то работавший в Cygnus Support, написал страницы руководства, которые распространялись с CVS версии 1.3. Большая часть их текста была скопирована в это руководство. Она также читал ранние черновики этого руководства и внес множество идей и исправлений.

Список рассылки info-cvs иногда бывает информативным. В это руководство включена информация их писем David G. Grubbs (dgg@think.com).

Часть текста извлечена из страниц руководства по RCS.

В часто задаваемых вопросах (FAQ) по CVS, созданных тем же Дэвидом Г. Груббсом, нашлось множество полезного материала. Этот FAQ, однако, больше не поддерживается, а это руководство является его ближайшим наследником (по крайней мере, с точки зрения использования CVS).

Вдобавок, эти люди помогли мне, указав на совершенные ошибки: Roxanne Brunskill rbrunski@datap.ca>, Kathy Dyer dyer@phoenix.ocf.llnl.gov>, Karl Pingle pingle@acuson.com>, Thomas A Peterson tap@src.honeywell.com>, Inge Wallin ingwa@signum.se>, Dirk Koschuetzki koschuet@fmi.uni-passau.de> and Michael Brown brown@wi.extrel.com>.

Полный список участников создания руководства можно найти в файле `doc/ChangeLog' в дистрибутиве исходных текстов CVS.

Go to the first, previous, next, last section, table of contents.

Требования к серверу


Простой ответ: требования к серверу умеренны -- если дерево каталогов не очень большое, и активность не слишком высока, то подойдет машина с 32Mb памяти или даже меньше.

В реальной жизни, конечно, все сложнее. Оценка пикового использования памяти достаточна, чтобы оценить общие требования. Здесь документированы две такие области максимального потребления памяти; все остальные по сравнению с ними незначительны (если вы обнаружите, что это не так, дайте нам знать, как описано в section Что делать с ошибками в CVS и этом руководстве?, чтобы мы обновили документацию.

Первая область большого потребления памяти -- извлечения больших рабочих каталогов. Сервер состоит из двух процессов на каждого обслуживаемого клиента. Потребление памяти дочерним процессом должно быть невелико. Родительский процесс же, особенно когда сетевые соединения медленны, может вырасти до размеров, чуть больших размера исходных тестов, или до двух мегабайт, смотря что больше.

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

Вторая область большого потребления памяти -- diff при фиксировании изменений в больших файлах. Это требуется даже для бинарных файлов. Можно предусмотреть использование примерно десятикратного размера самого большого файла, который только будет фиксироваться, хотя пятикратный размер будет вполне адекватен. Например, если вы хотите фиксировать файл размером в десять мегабайт, то в машине, на которой выполняется фиксирование (сервер или локальная машина, на которой находится репозиторий), должно быть сто мегабайт. Скорее всего, это будет файл подкачки, а не физическая память. Так как эта память требуется на непродолжительное время, то особенной нужды выделять память под несколько одновременных фиксирований нет.

Потребление ресурсов для клиентской машины еще более умеренны -- любая машина, способная выполнять соответствующую операционную систему, будет пригодна.

Информация о требованиях к дисковому пространству находится в section Создание репозитория.

Уборка за собой


Перед тем, как перейти к другим занятиям, вы решаете удалить рабочую копию tc. Конечно же, это можно сделать так: $ cd .. $ rm -r tc

но лучшим способом будет использование команды release (see section Команда release: сообщить, что модуль более не используется): $ cd .. $ cvs release -d tc M driver.c ? tc You have [1] altered files in this repository. Are you sure you want to release (and delete) directory `tc': n ** `release' aborted by user choice.

Команда release проверяет, что все ваши изменения были зафиксированы. Если включено журналирование истории, то в файле истории появляется соответствующая пометка. See section Файл history.

Если вы используете команду release с флагом `-d', то она удаляет вашу рабочую копию.

В вышеприведенном примере команда release выдала несколько строк. `? tc' означает, что файл `tc' неизвестен CVS. Беспокоиться не о чем, `tc' -- это исполняемый файл компилятора, и его не следует хранить в репозитории. See section Игнорирование файлов с помощью cvsignore за информацией о том, как избежать этого предупреждения. See section Сообщения команды release за полной информацией о возможных сообщениях команды release.

`M driver.c' -- более серьезное сообщение. Оно означает, что файл `driver.c' был изменен с момента последнего получения из репозитория.

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

Вы решаете перестраховаться и отвечаете n RET, когда release просит подтверждения.

Удаление файлов


Содержимое каталогов меняется. Добавляются новые файлы, исчезают старые. Однако же, вам хотелось бы извлекать точные копии старых версий вашего проекта.

Вот как можно удалить файл, сохранив доступ к его старым ревизиям: Убедитесь, что у вас неизмененная версия этого файла. See section Просмотр изменений, там описан один из способов убедиться в этом. Можно также использовать команды status или update. Если вы удалите файл без предварительной фиксации изменений, вы, конечно же, не сможете извлечь этот файл в том виде, в котором он находился перед удалением. Удалите файл из рабочей копии каталога. Например, можно использовать программу rm. Выполните `cvs remove имя-файла', чтобы сообщить CVS, что вы действительно хотите удалить этот файл. Выполните `cvs commit имя-файла', чтобы зафиксировать удаление файла в репозитории.

Когда вы фиксируете удаление файла, CVS запоминает, что этого файла более не существует. Впрочем, он может существовать на одних ветках и не существовать на других, или же можно впоследствии добавить другой файл с тем же самым именем. CVS корректно создаст или не станет создавать файл, основываясь на ключах командной строки `-r' или `-D', заданных в командах checkout или update.

Команда: cvs remove [ключи] файлы ...

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

Вот пример удаления нескольких файлов: $ cd test $ rm *.c $ cvs remove cvs remove: Removing . cvs remove: scheduling a.c for removal cvs remove: scheduling b.c for removal cvs remove: use 'cvs commit' to remove these files permanently $ cvs ci -m "Removed unneeded files" cvs commit: Examining . cvs commit: Committing .

Для удобства можно удалять файлы и одновременно делать cvs remove, используя ключ командной строки `-f'.
Например, вышеприведенный пример можно переписать так: $ cd test $ cvs remove -f *.c cvs remove: scheduling a. c for removal cvs remove: scheduling b.c for removal cvs remove: use 'cvs commit' to remove these files permanently $ cvs ci -m "Removed unneeded files" cvs commit: Examining . cvs commit: Committing . Если вы выполните команду remove, а затем перемените свое решение, еще не зафиксировав удаление, то команду remove можно отменить с помощью команды add. $ ls CVS ja.h oj.c $ rm oj.c $ cvs remove oj.c cvs remove: scheduling oj.c for removal cvs remove: use 'cvs commit' to remove this file permanently $ cvs add oj.c U oj.c cvs add: oj.c, version 1.1.1.1, resurrected Если вы осознаете свою ошибку перед выполнением команды remove, можно использовать update, чтобы воскресить файлы: $ rm oj.c $ cvs update oj.c cvs update: warning: oj.c was lost U oj.c Когда вы удаляете файл, он удаляется только с той ветки, на которой вы работаете (see section Создание ветвей и слияние). Позже можно слить удаления на другую ветку, если захотите (see section При слиянии можно добавлять и удалять файлы).

Удаление каталогов


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

Можно удалить каталог, удалив все файлы в нем. Нет способа удалить сам каталог. Вместо этого вы задаете командам cvs update, cvs checkout или cvs export ключ командной строки `-P', который заставит CVS удалять пустые каталоги в рабочем каталоге. Вероятно, лучше всего будет всегда указывать `-P', если вы хотите, чтобы существовал пустой каталог, поместите в него пустой файл, например, `.keepme', чтобы не дать CVS с ключом `-P' удалить этот каталог.

Заметьте, что при использовании ключей `-r' или `-D' с командами checkout и export подразумевается также использование `-P'. При этом CVS сможет создать или не создавать каталог, в зависимости от того, находились ли в этом каталоге какие-либо файлы в конкретной версии проекта.

Удаление, перемещение и удаление меток


Обычно метки не изменяются. Они существуют, чтобы хранить историю репозитория, поэтому изменять и удалять их обычно не нужно.

Однако же, могут быть случая, в которых метки используются лишь временно или случайно помечаются неверные ревизии. Таким образом, нужно удалить, переместить или переименовать метку. Предупреждение: команды в этой секции опасны, они навсегда уничтожают информацию об истории и восстановление после ошибок может быть трудным или невозможным. Если вы -- администратор CVS, вы можете захотеть ограничить использование этих команд с помощью файла `taginfo' (see section Настройка журналирования).

Чтобы удалить метку, задайте ключ командной строки `-d' команде cvs tag или cvs rtag. Например: cvs rtag -d rel-0-4 tc

удаляет метку rel-0-4 из модуля tc.

Когда мы говорим перемещение метки, мы хотим, чтобы существующее имя указывало на другие ревизии. Например, метка stable может указывать на ревизию 1.4 файла `backend.c', а мы хотим, чтобы она указывала на ревизию 1.6. Чтобы переместить метку, задайте ключ командной строки `-F' командам cvs tag или cvs rtag. Например, вышеупомянутая задача может быть решена так: cvs tag -r 1.6 -F stable backend.c

Когда мы говорим переименовать метку, мы хотим, чтобы другое имя указывало на те же ревизии, что и существующее. Например, мы могли ошибиться в написании имени метки и хотим исправить его, пока остальные не начали его использовать. Чтобы переименовать метку, сначала создайте новую метку, используя ключ командной строки `-r' команды cvs rtag, затем удалите старое имя. После этого новая метка указывает на точно те же самые файлы, что и старая. Например: cvs rtag -r old-name-0-4 rel-0-4 tc cvs rtag -d old-name-0-4 tc

Управление ревизиями


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

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

Версии и ревизии


Как описано выше, у файла может быть несколько ревизий. У программного продукта может быть несколько версий. Программным продуктам обычно дают номера версий типа `4.1.1'.

Ветки и ревизии


Обычно история ревизий файла -- это линейная возрастающая последовательность номеров (see section Номера ревизий): +-----+ +-----+ +-----+ +-----+ +-----+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! +-----+ +-----+ +-----+ +-----+ +-----+

Однако же, CVS не ограничен линейной разработкой. Дерево ревизий может быть расщеплено на ветви, где каждая ветвь -- самостоятельная линия разработки. Изменения, сделанные на одной ветке, легко могут быть внесены также и в основной ствол.

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

Все ревизии на ветке имеют номера ревизий, образованные путем добавления порядкового номера к номеру ветки. Вот иллюстрация создания веток. +-------------+ Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 ! / +-------------+ / / +---------+ +---------+ +---------+ Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 ! / +---------+ +---------+ +---------+ / / +-----+ +-----+ +-----+ +-----+ +-----+ ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 ! +---------+ +---------+ +---------+

Обычно не требуется задумываться о точных деталях того, как строятся номера веток, но вот еще подробности: когда CVS создает номер ветки, он берет первое неиспользованное четное число, начиная с двойки. Поэтому, если вы хотите создать ветку от ревизии 6.4, она будет называться 6.4.2. Номера веток, заканчивающиеся на ноль (например, 6.4.0), используются для внутренних нужд CVS (see section Волшебные номера веток). Ветка 1.1.1 имеет специальное значение. See section Слежение за чужими исходными текстами.

Волшебные номера веток


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

Номера веток состоят из нечетного количества десятичных целых, разделенных точками. See section Номера ревизий. Однако же, это не полная правда. Из соображений эффективности CVS иногда вставляет лишний ноль во вторую справа позицию (1.2.4 становится 1.2.0.4, а 8.9.10.11.12 становится 8.9.10.11.0.12 и так далее).

CVS довольно хорошо прячет такие "волшебные" ветки, но в нескольких местах ему это не удается: Номера волшебных веток появляются в выдаче cvs log. Вы не можете указать символическое имя ветки в команде cvs admin.

Можно использовать команду admin, чтобы переназначить символическое имя ветки на то, которое ожидает увидеть CVS. Например, если R4patches присвоено ветке 1.4.2 (волшебный номер 1.4.0.2) в файле `numbers.c', можно сделать так: $ cvs admin -NR4patches:1.4.2 numbers.c

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

Вопросы безопасности при парольной аутентификации


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

Отдельный файл паролей CVS (see section Настройка сервера для парольной аутентификации) позволяет использовать для доступа к репозиторию пароль, отличающийся от пароля для доступа к машине. С другой стороны, если пользователь получил доступ к репозиторию для чтения и записи, он может различными способами выполнять программы на сервере. Таким образом, доступ к репозиторию означает также довольно широкий диапазон другого доступа к системе. Можно было бы модифицировать CVS, чтобы предотвратить это, но до сих пор никто этого не сделал. Более того, могут быть другие способы, которыми люди, имеющие доступ к репозиторию, получат доступ к системе; никто не производил тщательного аудита.

Заметьте, что из-за того, что каталог `$CVSROOT/CVSROOT' содержит `passwd' и прочие файлы, использующиеся в целях безопасности, нужно следить за правами доступа к этому каталогу так же хорошо, как из правами доступа к `/etc'. То же самое применимо к самому каталогу `$CVSROOT' и любому каталогу, находящему в нем. Кто угодно, получив доступ для записи в этот каталог, сможет стать любым пользователем в системе. Заметьте, что эти права доступа обычно строже при использовании pserver.

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

Вопросы использования двоичных файлов


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

Одной из основных функций контроля версий -- просмотр различий между двумя ревизиями. Например, если кто-то еще создает новую ревизию файла, то вам хотелось бы взглянуть на то, что изменилось и выяснить, верно ли были сделаны изменения. Для текстовых файлов CVS обспечивает такую функциональность с помощью команды cvs diff. Для двоичных файлов можно извлечь две ревизии и сравнить их с помощью внешнего инструмента (например, в текстовых процессорах обычно имеется такая возможность. Если такого инструмента не существует, нужно отслеживать изменения посредством с помощью других механизмов, например, заставляя людей писать хорошие журнальные сообщения, надеясь при этом, что они действительно сделали то, что намеревались сделать.

Другая возможность системы контроля версий -- объединение двух ревизий. Для CVS это происходит в двух контекстах. Во-первых, пользователи редактируют файлы в различных рабочих каталогах (see section Несколько разработчиков). Во-вторых, объединения совершаются явно, используя команду `update -j' (see section Создание ветвей и слияние).

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

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

Возврат к последней версии от поставщика


Вы также можете полностью отменить локальные изменения и вернуться к последней версии от поставщика, установив головную ревизию в ветку поставщика для всех файлов. Например, если у вас есть извлеченная копия исходников в `~/work.d/wdiff', и вы хотите вернуть все файлы в этом каталоге в то состояние, в котором вам предоставил их поставщик, напечатайте: $ cd ~/work.d/wdiff $ cvs admin -bWDIFF .

Вы должны написать `-bWDIFF' без пробелов после `-b'. See section Ключи команды admin.

Временные каталоги на сервере


В процессе работы CVS-сервер создает временные каталоги. Они называются cvs-servpid

где pid -- это номер процесса сервера. Они находятся в каталоге, указанном в переменной окружения TMPDIR (see section Все переменные окружения, используемые в CVS), ключом командной строки `-T' или в `/tmp' по умолчанию.

В большинстве случаев сервер сам удалит временный каталог в конце работы. В некоторых случаях сервер может завершиться, не удалив свой временный каталог, например: если сервер аварийно завершается из-за внутренней ошибки, он может оставить временный каталог, чтобы облегчить отладку; если сервер был убит так, что не смог убрать за собой (например, `kill -KILL' под UNIX); система прекращает свою работу, не сообщив предварительно серверу об этом факте.

В таких случаях вы должны вручную удалить каталоги `cvs-servpid'. Если нет сервера с номером процесса pid, то сделать это можно совершенно безопасно.

Go to the first, previous, next, last section, table of contents.

Все переменные окружения, используемые в CVS


Вот полный список переменных окружения, влияющих на работу CVS. $CVSIGNORE Список шаблонов файлов, разделенный пробелами. CVS будет игнорировать эти файлы. See section Игнорирование файлов с помощью cvsignore. $CVSWRAPPERS Список имен файлов, разделенный пробелами. CVS будет считать такие файлы обертками. See section Файл `cvswrappers'. $CVSREAD Если эта переменная установлена, команды checkout и update будут стараться создавать файлы в вашем рабочем каталоге в режиме только для чтения. Если эта переменная не установлена, то поведением по умолчанию будет разрешить изменение ваших рабочих файлов. $CVSUMASK Управляет правами доступа к файлам в репозитории. См. section Права доступа к файлам. $CVSROOT Эта переменная должна содержать полный путь к репозиторию исходных текстов CVS (там, где хранятся RCS-файлы). Эта информация должна наличествовать для выполнения большинства команды CVS; если $CVSROOT не установлена, или же вы хотите один раз использовать другой репозиторий, вы можете использовать такую командную строку: `cvs -d cvsroot cvs_command...'. После того, как вы извлекли рабочий каталог, CVS сохраняет путь к репозиторию в файле `CVS/Root', поэтому обычно вам нужно беспокоиться об этом только при первом извлечении. $EDITOR $CVSEDITOR $VISUAL Задает программу, использующуюся для написания журнальных сообщений во время фиксирования. $CVSEDITOR переопределяет $EDITOR. См. section Фиксирование изменений. $PATH Если переменная $RCSBIN не установлена, и путь поиска программ не задан на этапе компиляции, то CVS будет использовать $PATH, чтобы найти все используемые программы. $HOME $HOMEPATH $HOMEDRIVE Используется для установки каталога, в котором хранится файл `.cvsrc' и некоторые другие файлы. Под UNIX CVS проверяет только $HOME. Под Windows NT система устанавливает переменные $HOMEDRIVE, например, `d:' и $HOMEPATH, например, `\joe'. Под Windows 95 вам, скорее всего, потребуется самому установить $HOMEDRIVE и $HOMEPATH. $CVS_RSH Задает внешнюю программу, с помощью которой CVS устанавливает соединение, когда используется метод доступа :ext:. see section Соединение с помощью rsh. $CVS_SERVER Используется в режиме клиент-сервер при обращении к сетевому репозиторию с помощью rsh. В этой переменной задается имя программы, которую нужно запустить на сервере при доступе к сетевому репозиторию с помощью rsh. Значение по умолчанию --- cvs. see section Соединение с помощью rsh. $CVS_PASSFILE Используется в режиме клиент-сервер при обращении к cvs login server. Значение по умолчанию -- `$HOME/.cvspass'. see section Использование клиента с парольной аутентификацией. $CVS_CLIENT_PORT Используется в режиме клиент-сервер при доступе к серверу с помощью Kerberos. see section Прямое соединение с помощью Kerberos. $CVS_RCMD_PORT Используется в режиме клиент-сервер. Если установлено, задает номер порта, который используется при обращении к демону RCMD на сервере. (В настоящий момент не используется для клиентов Unix). $CVS_CLIENT_LOG Используется для отладки в режиме клиент-сервер. Если установлено, то все, что посылается на сервер, журналируется в файле `$CVS_CLIENT_LOG.in', а все, что принимается от сервера, журналируется в `$CVS_CLIENT_LOG.out'. $CVS_SERVER_SLEEP Используется для отладки на стороне сервера в режиме клиент-сервер. Если установлена, задерживает запуск нового процесса-сервера на указанный период времени, чтобы вы могли присоединить к процессу отладчик. $CVS_IGNORE_REMOTE_ROOT Для CVS 1.10 и старше установка этой переменной не позволяет CVS перезаписывать файл `CVS/Root', когда задан глобальный ключ `-d'. Поздние версии CVS не перезаписывают этот файл, поэтому $CVS_IGNORE_REMOTE_ROOT игнорируется. $COMSPEC Используется только под OS/2. Задает имя командного интерпретатора, по умолчанию `cmd.exe'. $TMPDIR $TMP $TEMP Каталог, в котором расположены временные файлы. CVS-сервер использует TMPDIR. See section Глобальные ключи командной строки, где описано, как задать этот параметр. Некоторые части CVS всегда используют `/tmp' (с помощью функции tmpnam(), которая обеспечивается системой). Под Windows NT используется $TMP (с помощью функции _tempnam(), которая обеспечивается системой).Программа patch, которая используется клиентом CVS, использует TMPDIR, а если она не установлена, то `/tmp' (по крайней меер, это так для GNU patch 2.1). Заметьте, что если ваши сервер и клиент оба используют CVS 1.9.10 или позже, то CVS не вызывает внешнюю программу patch. Go to the first, previous, next, last section, table of contents.

Выбор между блокированными и неблокированными извлечениями


Блокированные и неблокированные извлечения имеют свои "за" и "против". Достаточно сказать, что это в основном вопрос мнения, или же принятого в группе стиле работы. Впрочем же, вот краткое описание некоторых возникающих вопросов. Существует множество способов организовать команду разработчиков. CVS не пытается насильно внедрить какой-либо способ. CVS -- это просто инструмент, который можно использовать различными способами.

Блокированные извлечения могут оказывать отрицательное влияние на производительность. Если два человека хотят отредактировать различные части файла, какие могут быть причины помешать кому-нибудь из них сделать это? Обычным делом также является заблокировать файл, предполагая поредактировать его, а затем забыть снять блокировку.

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

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

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

Возможность слежения, описанная выше, в главе section Как отследить, кто редактирует файлы?, может считаться промежуточной моделью между блокированными и неблокированными изменениями. Когда вы редактируете файл, можно узнать, кто ещё редактирует его. Система, вместо того, чтобы просто запретить двум людям редактировать файл, может описать ситуацию и позволить вам самому решить, является ли этот конкретный случай проблемой или нет. Таким образом, для некоторых групп механизм слежения может считаться объединением лучших черт блокированных и неблокированных изменений.

Go to the first, previous, next, last section, table of contents.

Выполнение программ на разных стадиях фиксирования


Флаг `-i' в файле `modules' может использоваться для выполнения определенной программы, когда соответствующие файлы помещаются в репозиторий (see section Файл `modules'). Файлы, описанные в этой секции, обеспечивают другие, более гибкие способы выполнения программ при фиксировании.

Есть три вида программ, которые можно выполнять при фиксировании. Они указываются в файлах в репозитории, как описано ниже. В этой таблице находится сводка таких файлов и назначение соответствующих программ: `commitinfo' Программа, ответственная за проверку, разрешена ли команда фиксирования изменений. Если эта программа заканчивается с ненулевым кодом завершения, фиксирование будет прервано. `verifymsg' Указанная программа используется для проверки журнального сообщения, чтобы убедиться, что оно содержит все требуемые поля. Полезно использовать этот файл в комбинации с `rcsinfo', который может содержать шаблон журнального сообщения (see section Файл rcsinfo). `editinfo' Заданная программа используется для редактирования журнального сообщения, и, возможно, проверки, что оно содержит все требуемые поля. Это особенно полезно в комбинации с файлом `rcsinfo', который может содержать шаблон журнального сообщения (see section Файл rcsinfo). Устарело. `loginfo' Указанная программа вызывается, когда завершено фиксирование. Она получает журнальное сообщение и дополнительную информацию, и может сохранить сообщение в файле, отправить его по почте ответственному человеку, поместить в местной группе новостей, или... Пределом является только ваше воображение!

Журнальные записи


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

Для того, чтобы просмотреть журнальные записи, соответствующие каждой зафиксированной ревизии, используйте команду cvs log (see section Команда log: напечатать информацию о файлах).