CVS: распределенная клиент-серверная система контроля версий
Автор: © Капил Шарма [Kapil Sharma]
|
ВведениеCVS -- это система контроля версий файлов. С её помощью Вы записываете историю изменения файлов с Вашим исходным кодом. А ещё CVS может помочь, если Вы работаете над проектом в составе группы, сообща используя общий код. Несколько разработчиков могут одновременно работать в проекте, используя клиент-серверную модель CVS, в соответствии с которой комплект исходного кода хранится на центральном сервере CVS, каждый программист получает его на свою "локальную" машину с сервера (checkout) и туда же "возвращает" изменения, после того, как работа заканчивается (checkin). Каждый раз, когда кто-либо из программистов посылает измененные файлы на сервер CVS, там сохраняются отличия от предыдущей версии, а исходный файл не переписывается. Это позволяет воссоздать любую из прежних версий каждого файла, хотя по умолчанию сервер "раздает" самую последнюю версию. В этой статье рассказывается, как работать с CVS в режиме клиент-сервер и как воспользоваться всеми ее возможностями. Где взять CVSCVS можно найти в составе Вашего дистрибутива Linux или скачать исходный код отсюда: http://www.cvshome.org/downloads.html Домашняя страница CVS находится на http://www.cvshome.org. Репозитарий (хранилище) CVSВ репозитарии CVS хранит копию всех файлов и каталогов, помещенных в систему контроля версий. При обычном ходе работы, Вам никогда не понадобится прямой доступ к файлам в хранилище. Вместо этого, Вы воспользуетесь командами CVS для того, чтобы получить копию комплекта файлов в свою рабочую директорию, а затем работать с этими файлами. После внесения намеченных изменений, Вы сохраняете их (commit или check in) в репозитарии. После этого в репозитарии отражаются сделанные Вами изменения, а также то, что именно Вы изменили, когда Вы сделали эти изменения и другая подобная информация. Создания репозитария cvs -d /usr/local/cvsroot init Каталог /usr/local/cvsroot станет резпозитарием. Переменная окружения CVSROOT $ export CVSROOT=:pserver:[email protected]:/usr/local/cvsroot Резервное копирование репозитария
Удаленный репозитарий Настройка сервера: 2401 stream tcp nowait root /usr/local/bin/cvs cvs -f --allow-root=/usr/cvsroot pserver Если Ваша версия inetd хочет символическое имя сервиса, а не голый номер порт, то в `/etc/services' надо добавить следующее: cvspserver 2401/tcp
Защита удалённого репозитария паролем anonymous: kapil:1sOp854gDF3DY melissa:tGX1fS8sun6rY:pubcvs Пароль записывается в обычном для Unix зашифрованном виде. Первая строка -- это пример того, как предоставить доступ любому клиенту CVS, который представится как 'anonymus' с любым паролем, т.е вообще без оного. Вторая строка разрешает доступ пользователю kapil, если он предоставит соответствующий пароль в виде простого текста. Третья строка предоставляет доступ пользователю melissa (если пароль верен), но ее работа с сервером CVS будет вестись от имени системного пользователя pubcvs. Замечание: CVS можно сконфигурировать так, чтобы настоящий файл паролей UNIX, т.е. /etc/passwd, не использовался при аутентификации доступа. Для этого надо записать в конфигурационный файл CVS ($CVSROOT/CVSROOT/config) опцию SystemAuth=no. Использование клиента и аутентификация паролем cvs -d :pserver:[email protected]:/usr/local/cvsroot login После этого на удаленной машине можно выполнять все комманды CVS: cvs -d :pserver:[email protected]:/usr/local/cvsroot checkout someproj Доступ к репозитарию только на чтение kapil yogesh john (Не забудьте про новую строку после последнего имнени.) "Исключение" означает перечисление всех, кто имеет право на запись. Если существует файл $CVSROOT/CVSROOT/writers, то правом внесения изменений в репозитарий могут воспользоваться только перечисленные в нем пользователи, а всем остальным будет предоставлен доступ только на чтение. Формат файла `writers' не отличается от файла `readers'. Помещение файлов в репозитарий $ cd someproj $ cvs import -m "Imported sources" someproj vendor rel1-1
Строка `vendor' -- метка "поставщика"-создателя, а `rel1-1' -- метка релиза. Получение исключительного доступа к репозитарию CVS Для получения исключительного доступа на чтение [read lock], сначала создайте директрорию `#cvs.lock'. Если это не получиться из-за того, что директория уже существует, выждите немного и попытайтесь снова. Когда Вы наконец получите #cvs.lock', создайте файл с именем, начинающимся на `#cvs.rfl.', продолжением имени может быть любая информация, например, имя компьтера и идентификатор процесса. Директорию `#cvs.lock' после этого следует удалить для того, чтобы освободить главный "замок" [master lock]. Читайте репозитарий на здоровье! Когда закончите, просто удалите созданный Вами `#cvs.rfl'-файл, сняв ограничение доступа на чтение. Для того, чтобы получить исключительные права записи, сначала создайте директорию `#cvs.lock' точно так же, как и для ограничения прав записи [read lock]. После этого проверьте, что файлы с именами, начинающимися на `#cvs.rfl.', отсутствуют. Если таковые найдутся, удалите `#cvs.lock', выждите какое-то время и повторите попытку. Если "читателей" нет, то создайте файл с именем, начинающимся на `#cvs.wfl' и дополненый какой-либо информацией по Вашему выбору (например, имя компьтера и идентификатор процесса). "Замок" `#cvs.lock' после этого удалять не надо. Записывайте в хранилище все, что Вам надо. По окончании, сначала удалите файл `#cvs.wfl', а затем каталог `#cvs.lock'. Символические метки релизов [symbolic revision tags] в CVS Для создания метки перейдите в рабочую директорию проекта и выполните следующее: $ cvs tag rel1-1 file.c Эта команда пометит файл "file.c" меткой [tag] релиза 1.1 $ cvs tag rel1-1 . А эта команда пометит меткой релиза 1.1 все файлы в текущей директории. Указав флаг `-v' команды status, можно увидеть все метки, сопоставленные определенному файлу и то, какие номера версий (ревизий:) им соответствуют: $ cvs status -v file.c Теперь, с помощью следующей команды, можно получить из репозитария [checkout] любую версию модуля: $ cvs checkout -r rel1-1 module1 здесь"module1" обозначает имя требуемого модуля. Добавленный к команде checkout флаг -r позволяет в любой момент времени получить файлы исходного кода, составляющие `module1' версии 1.1. Групповая разработкаСтатус файла $ cvs status [options] files Приведение файла(ов) в соотсветствие последним веяниям (update:) Разрешение конфликтов Если два человека одновременно изменяют разные части одного и того же файла, то CVS достанет сообразительности объединить эти изменения самостоятельно. Но вот если два человека изменяют одну и ту же часть файла, CVS не может определить сама, что же должно получиться в результате, в этом случае она "поднимает лапки к верху" со словами "Конфликт!". Конфликты возникают тогда, когда один разработчик сохраняет [commit] изменения, а другой, не выполнив cvs update для получения правки первого, пытается записать свои собственные изменения, не совместимые со сделанными раньше. Разрешение конфликта изменений может занять часы и даже дни. В этом разделе я объясню, как разрешаются конфликты в исходном коде. Когда Вы вызываете команду cvs commit для того, чтобы автоматически загрузить все измененные Вами файлы и все файлы, которые Вы добавили в проект, в репозитарий, сервер CVS может сообщить, что измененные файлы Вашей локальной копии устарели или сказать, что Вам придется вручную обхединить изменения в одном или более файлах с теми, которые другой разработчик сохранил в репозитарии до Вас. Вот как это обычно выглядит в ходе типичного выполнения CVS commit: $ cvs commit cvs commit: Examining . cvs commit: Up-to-date check failed for `andy.htm' cvs commit: Up-to-date check failed for `sample.htm' cvs commit: Up-to-date check failed for `index.htm' ... cvs [commit aborted]: correct above errors first! Вы можете выполнить команду cvs update для внесения в Вашу локальную копию последних изменений из репозитария. Для того, чтобы обновить всю рабочую копию сайта, откройте командную строку, перейдите в каталог, содержащий проект, над которым Вы работаете, и "испустите" команду: $ cvs update Произойдет обновление и изменения, сделанные в каждом файле после того момента, как Вы их скопировали из репозитария, будут автоматом внесены в них. Построчное обновление отдельных текстовых файлов (например, файлов HTML) часто может делаться автоматически. CVS перечислит для Вас все файлы, которые требуют Вашего внимания для "ручных" редактирования и объединения изменений. Пример автоматического объединения: $ cvs commit index.html cvs commit: Up-to-date check failed for `index.html' cvs [commit aborted]: correct above errors first!
Это произошло из-за того, что в репозитарии имеется более свежая версия того же файла. Сначала надо получить последнюю версию из репозитария на локальную машину командой cvs update: $ cvs update index.html RCS file: /usr/local/cvsroot/index.html,v retrieving revision 1.4 retrieving revision 1.5 Merging differences between 1.4 and 1.5 into index.html [Объединение версий 1.4 и 1.5 в index.html] M index.htm После автоматического объединения изменений лучше проверить "объединенную" копию, чтобы убедиться, что все сделано верно. Если получившийся "index.html" Вас устраивает, то можно сохранить изменения [commit] в CVS: $ cvs commit index.htm Checking in index.htm; /usr/local/cvsroot/index.htm,v <-- index.htm new revision: 1.6; previous revision: 1.5 [новая версия 1.6, предыдущая версия 1.5] done Пример ручного объединения изменений: $ cvs commit index.html cvs commit: Up-to-date check failed for `index.html' cvs [commit aborted]: correct above errors first! [сначала исправьте указанные ошибки!]
Командой cvs update приведите Вашу локальную копию сайта в соответствие с последними изменениями: $ cvs update cvs update: Updating . RCS file: /usr/local/cvsroot/index.html,v retrieving revision 1.5 retrieving revision 1.6 Merging differences between 1.5 and 1.6 into index.htm rcsmerge: warning: conflicts during merge cvs update: conflicts found in activity.htm [rcsmerge: внимание: конфликт при объединении cvs update: конфликт в файле activity.htm] C index.htm В этот раз CVS не удалось объединить исправления автоматически, и она создает специальную копию "конфликтного" файла вместо исходного index.html. С помощью специальных маркеров в файле отмечены начало и конец противоречивых участков, например: <<<<<<<< filename
Для того, чтобы разрешить конфликт, отредактируйте index.html и замените текст между маркерами, проверяя результат по ходу дела до тех пор, пока не получится то, что нужно. Кроме того, нужно удалить из файла следующие маркеры: <<<<<<<<========>>>>>>>> После того, как Вы закончите правку и тестирование, воспользуйтесь командой cvs commit для того, чтобы поместить последнюю версию в репозитарий: $ cvs commit Checking in index.html; /usr/local/cvsroot/index.html,v <-- index.html new revision: 1.7; previous revision: 1.6 done Контрольные точки [watches] (использование CVS для связи между разработчиками)
Для того, чтобы воспользоваться контрольками нужно отредактировать два файла в "служебной" части хранилища. Вам придется изменить файл "$CVSROOT/CVSROOT/notify" (из которого CVS узнает, как ей нужно производить извещение) и файл "$CVSROOT/CVSROOT/users", в котором находятся внешние адреса электронной почты. Лучший способ изменения служебных файлов -- "выписать" [checkout] их копию из репозитария, отредактировать и снова "прописать" [checkin] обратно. Для того, чтобы извещение приходило по электронной почте, раскомментируйте следующую строку файла "$CVSROOT/CVSROOT/notify": ALL mail %s -s "CVS notification" Эта команда приведет к тому, что извещение будет посылаться по электронной почте со строкой "CVS notification" в поле темы. После этого нужно создать или отредактировать файл "$CVSROOT/CVSROOT/users" . Формат строки файла users следующий: CVS_USERNAME:EMAIL_ADDRESS. Например: kapil:[email protected] Имя пользователя в начале строки соответствует имени пользователя CVS в файле CVSROOT/password, или же учетному имени (на стороне сервера) лица, запускающего CVS. После двоеточия вписывается адрес внешней (по отношению к серверу CVS) электронной почты, на который CVS должна посылать извещения для данного пользователя. Извещения по e-mail с ведением журнала [logfile] $mailcmd = "| Mail -s 'CVS update: $modulepath'"; После установки log.pl , можно добавить похожие строки в Ваш файл “loginfo”. Файл `loginfo' используется для указания того, куда посылаются журнальные записи о проведенных `cvs commit'. Их можно найти в "$CVSROOT/CVSROOT". projectteam1 CVSROOT/log.pl %s -f CVSROOT/commitlog -m [email protected] projectteam2 CVSROOT/log.pl %s -f CVSROOT/commitlog -m [email protected] Символ формата %s расширится до имени файла, изменения которого были сохнанены с помощью commit; опция -f в вызове log.pl позволяет указать имя файла журнала, в которй будет добавлено сообщение (так что файл CVSROOT/commitlog -- это "вечнорастущий" файл сообщений); а флаг -m позволяет указать адрес электронной почты, по которому log.pl будет посылать извещение о сохраненных изменениях [commits]. Обычно в качестве адреса указывается список рассылки, но опцию -m в командной строке log.pl можно указывать столько раз, сколько нужно. Некоторые команды, имеющие отношение к установке контролек [watches]: Если Вы хотите получать извещения только, скажем, о сохранении изменений [commits], то Вы можете ограничить получаемые извещения, настроив файл watch с помощью ключа -a (от англ. action -- действие): $ cvs watch add -a commit hello.c Или же, если кроме сохранения изменений Вас интересуют "захваты" файлов на редактирование [edits], но не интересуют отмена "захвата" на редактирование, можно использовать ключ -a дважды: $ cvs watch add -a edit -a commit hello.c Добавление новой контрольки с помощью ключа -a никогда не может удалить уже существующую. Если Вы получаете извещения на все три операции с файлом hello.c в хранилище, то выполнение $ cvs watch add -a commit hello.c не повлечет за собой никаких изменений -- как Вы получали извещение о всех трех возможных операциях, так и будете. Для удаления контрольки надо выполнить команду: $ cvs watch remove hello.c которая аналогична команде добавления в том, что по умолчанию отключает отправку извещений сразу для всех операций с файлом хранилища. Если использовать ключ -a, то это остановит отправку только указанных видов извещений: $ cvs watch remove -a commit hello.c Для того, чтобы узнать кто за чем следит, нужно выполнить cvs watchers: $cvs watchers $cvs watchers hello.c Для того, чтобы узнать кто и какие файлы в данный момент редактирует, выполните cvs editors: $cvs editors $cvs editors hello.c Замечание: для того, чтобы вышеописанная команда сработала, прежде, чем приступить к редактированию файла, нужно выполнить "cvs edit", иначе контрольки работать не будут. Для того, чтобы гарантировать это, в CVS есть способ напомнить об этом с помощью команды watch on: $ cd project $ cvs watch on hello.c Выполнив команду cvs watch on hello.c, пользователь kapil делает так, что при всех последующих запросах файлов проекта из репозитария рабочая копия файла htllo.c окажется доступной только для чтения. Попытавшись изменить его, другой разработчик вспомнит о необходимости сначала выполнить команду cvs edit. $cvs edit hello.c Откат к предыдущей версииИногда нужно вернуться к более ранней версии собственного проекта. Помещенный в CVS проект можно легко получить в том виде, который он имел на предыдущих стадиях своей жизни. Вот несколько простых примеров: $ cvs checkout -D '1 year ago' preproject Здесь preproject -- это имя проекта. $ cvs checkout -r1.4 preproject Здесь 1.4 -- номер, под которым данная версия хранится в CVS. Некоторые обычные команды CVSЧасто употребимые термины: Добавление файла в репозитарий CVS "My_Files" $ cvs add File3.txt $ cvs commit cvs add не загружает файл сразу, а просто регистрирует его. Сама загрузка произойдет при следующем сохранении изменений [commit]. При выполнении этой команды [commit] будет вызван текстовой редактор по умолчанию для того, чтобы создать описание сделанных изменений. Сохраните файл и выйдите из редактора. После этого CVS предложит Вам продолжить, соглашайтесь. Вот вы и загрузили новый файл в репозитарий "My_Files". Изменение файла в репозитарии "My_Files" Это можно сделать командой cvs commit. Добавим что-нибудь в файл File2.txt, а затем сохраним изменения в репозитарии. $ ls /var >> File2.txt $ cvs commit Удаление файлов $ cvs remove file.html cvs server: file `file.html' still in working directory cvs server: 1 file exists; remove it first $ Для преодоления возникшего затруднения в команде можно использовать опцию -f или сначала удалить рабочую копию файла, выполнив cvs remove после этого. $ cvs remove -f oldfile.html cvs server: scheduling `oldfile.html' for removal cvs server: use 'cvs commit' to remove this file permanently $ cvs commit Или $ rm File3.txt $ cvs remove File3.txt $ cvs commit Сама по себе эта команда ничего не удаляет на сервере CVS,
а просто делает пометку, что файл(ы) нужно удалить тогда, когда Вы будете сохранять
изменения, сделанные в рабочей копии проекта. Удаление директорий Создание в репозитарии структуры каталогов на основании имеющегося набора
файлов $ cd source source -- это имя того, что Вы хотите поместить в репозитарий. $ cvs import -m "Test Import" My_Files Revision1 start Строка "Revision1" -- это метка разработчика [vendor tag], а строка 'start' -- метка релиза [release tag]. Получение рабочей копии файлов Отлично, а теперь мы хотим скачать эти файлы в Рабочую Директорию. Пора получить пакет из репозитария. $ cvs checkout My_Files Получение изменений, которые сделали другие разработчики Если Вы скачали пакет из репозитария, который поддерживается кем-то другим, то с помощью следующей команды Вы можете получить самые последние изменения: $ cvs update -dP Ключ "d" создает все отсутствующие директории. Ключ "P" удаляет все каталоги, удаленные в репозитарии. Просмотр изменений $ cd project $ cvs diff index.html Эта команда использует diff для сравнения версии 'index.html', которую Вы скачали из репозитария с той, которая находится в рабочей директории. Здесь "project" -- имя локального каталога проекта. $ cvs diff -r 1.20 -r 1.21 hello.c А эта команда показывает разницу между двумя версиями одного и того же файла. Команда annotate $cvs annotate Просмотр журналов [logs] $ cvs log -r 1.21 hello.c Команда выведет содержимое журнала для файла hello.c версии 1.21 Дополнительный инструментарий CVS CVSweb Хеннера Целлера [Henner Zeller] Martin Cleaver's CVSweb Мартина Кливера [Martin Cleaver] LinCVS WinCVS Дополнительные сведенияРуководство по CVS: http://www.cvshome.org/docs/manual/cvs.html Рассылка CVS: http://www.cvshome.org/communication.html
Капил Шарма [Kapil Sharma]Капил -- консультант по безопастности Linux/Unix и Internet. Работает в сфере различных Linux/Unix систем и сетевой безопастности более трех лет. Поддерживает веб-сайт, предоставляющий бесплатные и коммерческие услуги по поддержке веб-решений и решений на базе Linux/Unix (http://linux4biz.net).
|
Copyright © 2001, Kapil Sharma. Copying license http://www.linuxgazette.com/copying.html Published in Issue 66 of Linux Gazette, May 2001 |
Вернуться на главную страницу |