системы контроля версий. Лекция 4 Системы контроля версий. Лекция 4 Системы контроля версий
Скачать 52.96 Kb.
|
Лекция 4 Системы контроля версий https://www.youtube.com/watch?v=pLg6v9rBrtw Перед тем, как говорить про какую-либо конкретную систему контроля версий необходимо понимать, что это такое, какими они бывают и зачем вообще они появились. Эта лекция предназначена для первоначального знакомства с системами контроля и управления версиями, и сначала рассмотрим происхождение инструментов для контроля версий, какие системы управления версиями сейчас популярны и в чем у них основные различия. О контроле версийЧто такое контроль версий, и зачем он вам нужен?Наверное, стоит начать с определения системы контроля версий (СКВ) — это система, регистрирующая изменения в одном или нескольких файлах с тем, чтобы в дальнейшем была возможность вернуться к определённым старым версиям этих файлов. Система контроля версий является прежде всего инструментам, а инструмент призван решать некоторый класс задач. Итак, система контроля версий – это система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определенной версии. Мы хотим гибко управлять некоторым набором файлов, откатываться до определенных версий в случае необходимости. Можно отменить те или иные изменения файла, откатить его удаление, посмотреть кто что-то поменял. Как правило системы контроля версий применяются для хранения исходного кода, но это необязательно. Они могут применяться для хранения файлов совершенно любого типа. Как хранить различные версии файлов? Люди пришли к такому инструменту как системы контроля версий не сразу, да и они сами бывают очень разные. Предложенную задачу можно решить с применением старого доброго copy-paste, локальных, централизованных или распределенных систем контроля версий. В последнее время файлы являются конечным результатом для многих профессий (для примера, писательскую деятельность, научные работы и, конечно, разработку программного обеспечения). Тратится много времени и сил на разработку и поддержку этих файлов и никто не хочет, чтобы пришлось тратить еще больше времени и сил на восстановление данных потерянных в результате каких-либо изменений. Представим, что программист разрабатывает проект состоящий из одного небольшого файла (кстати, пример вполне реальный, не синтетический, встречался в реальной жизни). После выпуска первой версии проекта перед ним встает непростой выбор: необходимо исправлять проблемы о которых сообщают пользователи первой версии и, в тоже время, разрабатывать что-то новое для второй. Даже если надо просто исправлять возникающие проблемы, то велика вероятность, что после какого-либо изменения проект перестает работать, и надо определить, что было изменено, чтобы было проще локализовать проблему. Также желательно вести какой-то журнал внесенных изменений и исправлений, чтобы не делать несколько раз одну и ту же работу. В простейшем случае вышеприведенную проблему можно решить хранением нескольких копий файлов, например, один для исправления ошибок в первой версии проекта и второй для новых изменений. Так как изменения обычно не очень большие по сравнению с размером файла, то можно хранить только измененные строки используя утилиту diff и позже объединять их с помощью утилиты patch. Но что если проект состоит из нескольких тысяч файлов и над ним работает сотня человек? Если в этом случае использовать метод с хранением отдельных копий файлов (или даже только изменений), то проект застопорится очень быстро. Под версионный контроль можно поместить файлы практически любого типа. Если вы графический или веб-дизайнер и хотели бы хранить каждую версию изображения или макета — а этого вам наверняка хочется — то пользоваться системой контроля версий будет очень мудрым решением. СКВ даёт возможность возвращать отдельные файлы к прежнему виду, возвращать к прежнему состоянию весь проект, просматривать происходящие со временем изменения, определять, кто последним вносил изменения во внезапно переставший работать модуль, кто и когда внёс в код какую-то ошибку, и многое другое. Вообще, если, пользуясь СКВ, вы всё испортите или потеряете файлы, всё можно будет легко восстановить. Вдобавок, накладные расходы за всё, что вы получаете, будут очень маленькими. Локальные системы контроля версийКак уже говорилось ранее - один из примеров локальной СУВ предельно прост: многие предпочитают контролировать версии, просто копируя файлы в другой каталог (как правило добавляя текущую дату к названию каталога). Такой подход очень распространён, потому что прост, но он и чаще даёт сбои. Очень легко забыть, что ты не в том каталоге, и случайно изменить не тот файл, либо скопировать файлы не туда, куда хотел, и затереть нужные файлы. Чтобы решить эту проблему, программисты уже давно разработали локальные СКВ с простой базой данных, в которой хранятся все изменения нужных файлов Следующим шагом в развитии систем контроля версий было создание локальных систем контроля версий. Они представляли из себя простейшую базу данных, которая хранит записи обо всех изменениях в файлах. Одной из наиболее популярных СКВ такого типа является система контроля версий RCS (Revision Control System, Система контроля ревизий), которая была разработана в 1985 году (последний патч был написан в 2015 году) и хранит изменений в файлах (патчи), осуществляя контроль версий и которая до сих пор устанавливается на многие компьютеры. Даже в современной операционной системе Mac OS X утилита rcs устанавливается вместе с Developer Tools. RCS была разработана в начале 1980-х годов Вальтером Тичи (Walter F. Tichy). Набор этих изменений позволяет восстановить любое состояние файла. RCS поставляется с Linux'ом. Локальная система контроля версий хорошо решает поставленную перед ней задачу, однако ее проблемой является основное свойство — локальность. Она совершенно не преднезначена для коллективного использования. Copy-paste. Система позволяет хранить версии только одного файла, таким образом управлять несколькими файлами приходится вручную. Известный метод при применении к данной задаче может выглядеть следующим образом: будем называть файлы по шаблону filename_{version}, возможно с добавлением времени создания или изменения. Для каждого файла находящегося под контролем системы информация о версиях хранится в специальном файле с именем оригинального файла к которому в конце добавлены символы ',v'. Например для файла file.txt версии будут храниться в файле file.txt,v. Эта утилита основана на работе с наборами патчей между парами версий (патч — файл, описывающий различие между файлами). Это позволяет пересоздать любой файл на любой момент времени, последовательно накладывая патчи. Для хранения версий система использует утилиту diff. Хотя RCS соответствует минимальным требованиям к системе контроля версий она имеет следующие основные недостатки, которые также послужили стимулом для создания следующей рассматриваемой системы: Работа только с одним файлом, каждый файл должен контролироваться отдельно; Неудобный механизм одновременной работы нескольких пользователей с системой, хранилище просто блокируется пока заблокировавший его пользователь не разблокирует его; От бекапов вас никто не освобождает, вы рискуете потерять всё. Бэкап (резервная копия) — это предварительно созданная копия данных для восстановления в случае потери оригинальных данных. ... изолированность (копии не должны храниться на том же сервере, что и исходные данные; желательно иметь несколько резервных копий на разных носителях) Данный способ является очень простым, но он подвержен различным ошибкам: можно случайно изменить не тот файл, можно скопировать не из той директории (ведь именно так переносятся файлы в этой модели). Централизованные системы контроля версийСледующей основной проблемой оказалась необходимость сотрудничать с разработчиками за другими компьютерами. Чтобы решить её, были созданы централизованные системы контроля версий (ЦСКВ). В таких системах, например, CVS, Subversion и Perforce, есть центральный сервер, на котором хранятся все файлы под версионным контролем, и ряд клиентов, которые получают копии файлов из него. Много лет это было стандартом для систем контроля версий. Для организации такой системы контроля версий используется единственный сервер, который содержит все версии файлов. Клиенты, обращаясь к этому серверу, получают из этого централизованного хранилища. Применение централизованных систем контроля версий на протяжении многих лет являлась стандартом. К ним относятся CVS, Subversion, Perforce. Такими системами легко управлять из-за наличия единственного сервера. Но при этом наличие централизованного сервера приводит к возникновению единой точки отказа в виде этого самого сервера. В случае отключения этого сервера разработчики не смогут выкачивать файлы. Самым худшим сценарием является физическое уничтожение сервера (или вылет жесткого диска), он приводит к потере кодовой базы. Такой подход имеет множество преимуществ, особенно над локальными СКВ. К примеру, все знают, кто и чем занимается в проекте. У администраторов есть чёткий контроль над тем, кто и что может делать, и, конечно, администрировать ЦСКВ намного легче, чем локальные базы на каждом клиенте. Однако при таком подходе есть и несколько серьёзных недостатков. Наиболее очевидный — централизованный сервер является уязвимым местом всей системы. Если сервер выключается на час, то в течение часа разработчики не могут взаимодействовать, и никто не может сохранить новой версии своей работы. Если же повреждается диск с центральной базой данных и нет резервной копии, вы теряете абсолютно всё — всю историю проекта, разве что за исключением нескольких рабочих версий, сохранившихся на рабочих машинах пользователей. Несмотря на то, что мода на SVN прошла, иногда наблюдается обратный ход — переход от Git'а к SVN'у. Дело в том, что SVN позволяет осуществлять селективный чекаут, который подразумевает выкачку лишь некоторых файлов с сервера. Такой подход приобретает популярность при использовании монорепозиториях, о которых можно будет поговорить позже. CVSCVS (Concurrent Versions System, Система совместных версий) пока остается самой широко используемой системой, но быстро теряет свою популярность из-за ряда недостатков. Дик Грун (Dick Grune) разработал CVS в середине 1980-х. Для хранения индивидуальных файлов CVS (также как и RCS) использует файлы в RCS формате, но позволяет управлять группами файлов расположенных в директориях. Также CVS использует клиент-сервер архитектуру, в которой вся информация о версиях хранится на сервере. Использование клиент-сервер архитектуры позволяет использовать CVS даже географически распределенным командами пользователей где каждый пользователь имеет свой рабочий директорий с копией проекта. Как следует из названия пользователи могут использовать систему совместно. Возможные конфликты при изменении одного и того же файла разрешаются тем, что система позволяет вносить изменения только в самую последнюю версию файла. Таким образом всегда рекомендуется перед заливкой своих изменений обновлять свою рабочую копию файлов на случай возможных конфликтующих изменений. При обновлении система вносит изменения в рабочую копию автоматически и только в случае конфликтующих изменений в одном из мест файла требуется ручное исправление места конфликта. CVS также позволяет вести несколько линий разработки проекта с помощью ветвей (branches) разработки. Таким образом, как уже упоминалось выше, можно исправлять ошибки в первой версии проекта и параллельно разрабатывать новую функциональность. CVS использовалась большим количеством проектов, но конечно не была лишена недостатков которые позднее привели к появлению следующей рассматриваемой системы. Рассмотрим основные недостатки: Так как версии хранятся в файлах RCS нет возможности сохранять версии директорий. Стандартный способ обойти это препятствие - это сохранить какой-либо файл (например, README.txt) в директории; Перемещение, или переименование файлов не подвержено контролю версий. Стандартный способ сделать это: сначала скопировать файл, удалить старый с помощью команды cvs remove и затем добавить с его новым именем с помощью команды cvs add; SubversionSubversion (SVN) был разработан в 2000 году по инициативе фирмы CollabNet. SVN изначально разрабатывался как "лучший CVS" и основной задачей разработчиков было исправление ошибок допущенных в дизайне CVS при сохранении похожего интерфейса. SVN также как и CVS использует клиент-сервер архитектуру. Из наиболее значительных изменений по сравнению с CVS можно отметить: Атомарное внесение изменений (commit). В случае если обработка коммита была прервана не будет внесено никаких изменений. Переименование, копирование и перемещение файлов сохраняет всю историю изменений. Директории, символические ссылки и мета-данные подвержены контролю версий. Эффективное хранение изменений для бинарных файлов. Распределённые системы контроля версийИ в этой ситуации в игру вступают распределённые системы контроля версий (РСКВ). Для устранения единой точки отказа используются распределенные системы контроля версий. Они подразумевают, что клиент выкачает себе весь репозиторий целиком заместо выкачки конкретных интересующих клиента файлов. Если умрет любая копия репозитория, то это не приведет к потере кодовой базы, поскольку она может быть восстановлена с компьютера любого разработчика. Каждая копия является полным бэкапом данных. Все копии являются равноправным и могут синхронизироваться между собой. Подобный подход очень напоминает (да и является) репликацией вида master-master. К данному виду систем контроля версий относятся Mercurial, Bazaar, Darcs и Git В таких системах как Git, Mercurial, Bazaar или Darcs клиенты не просто выгружают последние версии файлов, а полностью копируют весь репозиторий. Поэтому в случае, когда "умирает" сервер, через который шла работа, любой клиентский репозиторий может быть скопирован обратно на сервер, чтобы восстановить базу данных. Каждый раз, когда клиент забирает свежую версию файлов, он создаёт себе полную копию всех данных. Кроме того, в большей части этих систем можно работать с несколькими удалёнными репозиториями, таким образом, можно одновременно работать по-разному с разными группами людей в рамках одного проекта. Так, в одном проекте можно одновременно вести несколько типов рабочих процессов, что невозможно в централизованных системах. Зачем нужны распределенные системы?Как следует из названия одна из основных идей распределенных систем — это отсутствие четко выделенного центрального хранилища версий - репозитория. В случае распределенных систем набор версий может быть полностью, или частично распределен между различными хранилищами, в том числе и удаленными. Такая модель отлично вписывается в работу распределенных команд, например, распределенной по всему миру команды разработчиков работающих над одним проектом с открытым исходным кодом. Разработчик такой команды может скачать себе всю информацию по версиям и после этого работать только на локальной машине. Как только будет достигнут результат одного из этапов работы, изменения могут быть залиты в один из центральных репозиториев или, опубликованы для просмотра на сайте разработчика, или в почтовой рассылке. Другие участники проекта, в свою очередь, смогут обновить свою копию хранилища версий новыми изменениями, или попробовать опубликованные изменения на отдельной, тестовой ветке разработки. К сожалению, без хорошей организации проекта отсутствие одного центрального хранилища может быть минусом распределенных систем. Если в случае централизованных систем всегда есть один общий репозиторий откуда можно получить последнюю версию проекта, то в случае распределенных систем нужно организационно решить какая из веток проекта будет основной. Почему распределенная система контроля версий может быть интересна кому-то, кто уже использует централизованную систему - такую как Subversion? Любая работа подразумевает принятие решений, и в большинстве случаев необходимо пробовать различные варианты: при работе с системами контроля версий для рассмотрения различных вариантов и работы над большими изменениями служат ветки разработки. И хотя это достаточно естественная концепция, пользоваться ей в Subversion достаточно непросто. Тем более, всё усложняется в случае множественных последовательных объединений с одной ветки на другую — в этом случае нужно безошибочно указывать начальные и конечные версии каждого изменения, чтобы избежать конфликтов и ошибок. Для распределенных систем контроля версий ветки разработки являются одной из основополагающих концепций — в большинстве случаев каждая копия хранилища версий является веткой разработки. Таким образом, механизм объединения изменений с одной ветки на другую в случае распределенных систем является одним из основных, что позволяет пользователям прикладывать меньше усилий при пользовании системой. Краткое описание популярных распределенных СУВ Git - распределенная система контроля версий, разработанная Линусом Торвальдсом. Изначально Git предназначалась для использования в процессе разработки ядра Linux, но позже стала использоваться и во многих других проектах — таких, как, например, X.org и Ruby on Rails, Drupal. На данный момент Git является самой быстрой распределенной системой, использующей самое компактное хранилище ревизий. Но в тоже время для пользователей, переходящих, например, с Subversion интерфейс Git может показаться сложным; Mercurial - распределенная система, написанная на языке Python с несколькими расширениями на C. Из использующих Mercurial проектов можно назвать, такие, как, Mozilla и MoinMoin. Bazaar - система разработка которой поддерживается компанией Canonical — известной своими дистрибутивом Ubuntu и сайтом httpss://launchpad.net/. Система в основном написана на языке Python и используется такими проектами, как, например, MySQL. Codeville - написанная на Python распределенная система использующая инновационный алгоритм объединения изменений (merge). Система используется, например, при разработке оригинального клиента BitTorrent. Darcs - распределенная система контроля версий написанная на Haskell используемая, например, проектом Buildbot. Monotone - система написанная на C++ и использующая SQLite как хранилище ревизий. История Git В 2005 году компания, разрабатывающая систему контроля версий BitKeeper, порвала отношения с сообществом разработчиков ядра Linux. После этого сообщество приняло решение о разработке своей собственной системы контроля версий. Основными ценностями новой системы стали: полная децентрализация, скорость, простая архитектура, хорошая поддержка нелинейной разработки. Системы контроля версий (от англ. Version Control System, VCS) (https://www.amse.ru/courses/cpp1/2010.02.10.html) При разработке более-менее крупных проектов мы можем столкнуться с рядом трудностей, например: Изменяем код, а потом хотим откатить изменения. Каждую версию можно сохранять в отдельную папку, но со временем станет сложно управляться с большим количеством файлов. Если над программой работает сразу несколько человек, было бы неплохо автоматизировать процесс объединения сделанных ими изменений. Для решения этих проблем удобно использовать системы контроля версий, например Subversion (SVN). Обычно VCS состоит из двух частей: Сервер, или репозиторий — где хранятся все исходные коды программы, а также история их изменения. Клиент. Каждый клиент имеет свою локальную копию (working copy) исходных кодов, с которой работает разработчик. В связи с тем, что разработчики работают только с локальными копиями, могут возникать трудности, когда два и более человек изменяют один и тот же файл. В VCS есть две модели, которые позволяют избегать этой проблемы: Блокировка — изменение — разблокировка. Согласно этой модели, когда кто-либо начинает работу с файлом, этот файл блокируется, и все остальные пользователи теряют возможность его редактирования. Очевидным недостатком такой модели является то, что файлы могут оказаться надолго заблокированными, что приводит к простоям в разработке проекта. Копирование — изменение — слияние. В данной модели каждый разработчик свободно редактирует свою локальную копию файлов, после чего выполняется слияние изменений. Недостаток этой модели в том, что может возникать необходимость разрешения конфликтов между изменениями файла. В SVN доступны обе модели, причём вторая является основной. В то же время для некоторых типов файлов (например, изображения) целесообразно использовать первую. Subversion (SVN) SVN является одной из клиент-серверных систем контроля версий и состоит из двух частей: Svnserve — серверная В качестве серверной части можно использовать обычный http-сервер. svn — клиентская часть Можно создать и настроить собственный SVN-сервер или использовать готовые бесплатные сервисы: code.google.com , sourceforge.net . Команды SVN Перед тем как приступить к использованию SVN, ознакомимся с некоторыми командами, которые может выполнять клиентская часть. Наиболее часто используемые разработчиками команды: svn update — обновляет содержимое локальной копии до самой последней версии из репозитория. svn commit — отправляет все изменения локальной копии в репозиторий. svn add <файл/папка> — включить файл/папку в локальную копию проекта Нередко также используются команды: svn move <файл/папка1> <папка2> — переместить файл/папку1 в папку2 svn copy <файл/папка> <папка> — скопировать файл/папку1 в папку2 svn delete <файл/папка> — удалить файл/папку из локальной копии проекта Прочие полезные команды SVN: svn list <URL> — просмотр каталога репозитория svn log <файл> --verbose — история изменения файла по ревизиям svn cat --revision <номер_ревизии> <файл> — отображение содержимого файла из данной ревизии svn diff --revision <номер_ревизии1:номер_ревизии2> <файл> — отображение изменений файла между двумя ревизиями svn status — отображение изменений в локальной копии относительно репозитория Жизненный цикл проекта на SVN Допустим, что у нас уже есть настроенный SVN-сервер, и мы хотим перенести на него проект. У нас есть папка test, в которой лежит три файла: 1.cpp 2.cpp Makefile 0) Добавляем новые файлы на сервер: svn import svn://......../repo/test test Здесь svn://......../repo/test - url-адрес проекта, test - название добавляемой папки. 1) Получаем локальную копию файлов проекта: svn checkout svn://......../repo/test project/test project/test - адрес, где будет располагаться локальная копия. После выполнения этой команды получим следующую структуру файлов: Project Test .svn 1.cpp 2.cpp Makefile Локальную копию не следует добавлять в ту папку, из которой делали import, так как при совпадении имён файлов они не будут перезаписаны. 2) Изменяем файлы Допустим, на этом шаге мы хотим сделать какие-нибудь изменения в проекте, а именно: изменить содержимое 1.cpp следующим образом: до изменений: int main(){ return 0; } после изменений: int main(){ printf(" "); return 0; } удалить файл 2.cpp Стоит обратить внимание на следующую особенность SVN: содержимое файлов проекта можно менять в любых привычных редакторах, но изменения в структуре файлов проекта следует выполнять с помощью соответствующих команд svn (add, copy, move, delete). То есть если мы просто удалим файл из папки с локальной копией - это никак не отразится на содержимом репозитория даже после успешного commit'a. 3) Фиксируем состояние При фиксации происходит отправка всех изменений в локальной копии на сервер. svn commit -m "....." -m "....." — комментарий к commit'у. При выполнении этой команды SVN узнаёт нужную ему информацию о проекте из папки .svn После каждого commit'а номер ревизии увеличивается на единицу. Номер ревизии (Revision) &mdash целое число, показывающее номер состояния проекта. Все выполненные действия можно схематически представить на рисунке: Разрешение конфликтов При работе над проектом возможны такие ситуации: Допустим, в какой-то момент времени разработчик обновляется до последней версии проекта и начинает работу над некоторыми файлами. Через какое-то время, изменив файлы, он пытается сделать commit. Однако, этот commit не удастся, если другие разработчики уже вносили изменения в те же файлы проекта и сохраняли их в репозитории. Такая ситуация называется конфликтом. У разработчика, чей commit не удался из-за конфликтов, есть два возможных варианта действий: svn revert — отменить все свои изменения svn update — забрать из репозитория новые версии файлов и, разрешив конфликты, снова попытаться сделать commit. Как разрешаются конфликты Допустим, в репозитории хранится файл main.cpp ревизии 13: int main(){ fprintf(); return 0; }
Теперь у user1 есть несколько путей разрешения конфликта: убрать чужие изменения, оставив свои не вносить свои изменения, оставив всё как есть вручную соединить все изменения в одном файле В последнем случае user1 имеет несколько файлов: main.cpp — этот файл уйдёт в репозиторий после разрешений конфликта main.cpp.mine — в этом файле хранятся изменения, сделанные user1 main.cpp.r13 — начальная версия файла без всяких изменений main.cpp.r14 — файл, попавший в репозиторий (с изменениями user2) После сведения всех изменений в main.cpp user1 пишет svn resolved main.cpp (при этом удалятся временные файлы) svn commit SVN позволяет так же объединить любую версию с любым набором других версий с помощью update и merge. Про команду merge можно прочитать, набрав в консоли команду svn help merge. Заключение В этой лекции мы рассмотрели систему контроля версий SVN, которая является централизованной (то есть у любого проекта есть одно хранилище). В настоящее время так же распространены распределённые системы управления версиями (англ. Distributed Version Control System, DVCS), в которых вся история изменений файлов хранится в локальных копиях клиентов и, при необходимости, синхронизируется. К DVCS относятся: git, Mercurial, Bazaar. Контрольные вопросы
|