управление версиями исходного кода

Что такое система контроля версий? 5 систем управления версиями с открытым исходным кодом

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

Для крупных проектов по разработке программного обеспечения системы контроля версий отслеживают множество изменений в исходном коде.

Почему так важны системы контроля версий?

Все системы контроля версий обладают следующими возможностями:

Существуют разные системы управления версиями, но какие отличительные черты делают их уникальными? Перечислим три их главные группы:

5 систем контроля версий с открытым исходным кодом

CVS является самой популярной и широко применяемой системой контроля версий на сегодняшний день. После выпуска в 1986 году она быстро стала общепринятым стандартом. CVS приобрела популярность благодаря простой системе поддержки файлов и ревизий в актуальном состоянии.

Достоинства системы контроля версий SVN

Mercurial

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

Достоинства Mercurial системы контроля версий

Bazaar

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

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

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

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

Источник

О системах контроля версий

Всем привет! Уже на следующей неделе в OTUS стартует «Супер-практикум по использованию и настройке GIT». Этому я и решил посвятить сегодняшнюю публикацию.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Введение

Системы контроля версий

Система контроля версий является прежде всего инструментам, а инструмент призван решать некоторый класс задач. Итак, система контроля версий – это система, записывающая изменения
в файл или набор файлов в течение времени и позволяющая вернуться позже к определенной версии. Мы хотим гибко управлять некоторым набором файлом, откатываться до определенных версий в случае необходимости. Можно отменить те или иные изменения файла, откатить его удаление, посмотреть кто что-то поменял. Как правило системы контроля версий применяются для хранения исходного кода, но это необязательно. Они могут применяться для хранения файлов совершенно любого типа.

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

Copy-paste

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

Данный способ является очень простым, но он подвержен различным ошибкам: можно случайно изменить не тот файл, можно скопировать не из той директории (ведь именно так переносятся файлы в этой модели).

Локальная система контроля версий

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

Одним из примеров таких систем является система контроля версий RCS, которая была разработана в 1985 году (последний патч был написан в 2015 году) и хранит изменений в файлах (патчи), осуществляя контроль версий. Набор этих изменений позволяет восстановить любое состояние файла. RCS поставляется с Linux’ом.

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

Централизованная система контроля версий

Централизованная система контроля версий предназначена для решения основной проблемы локальной системы контроля версий.

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

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

Несмотря на то, что мода на SVN прошла, иногда наблюдается обратный ход — переход от Git’а к SVN’у. Дело в том, что SVN позволяет осуществлять селективный чекаут, который подразумевает выкачку лишь некоторых файлов с сервера. Такой подход приобретает популярность при использовании монорепозиториях, о которых можно будет поговорить позже.

Распределенная система контроля версий

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

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

К данному виду систем контроля версий относятся Mercurial, Bazaar, Darcs и Git. Последняя система контроля версий и будет рассмотрена нами далее более детально.

История Git

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

Заключение

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

Источник

История систем управления версиями

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

В этой статье сравним с технической точки зрения самые известные системы управления версиями (в будущем планируем расширить список):

В VCS второго поколения появилась поддержка сети, что привело к централизованным хранилищам с «официальными» версиями проектов. Это был значительный прогресс, поскольку несколько пользователей могли одновременно работать с кодом, делая коммиты в один и тот же центральный репозиторий. Однако для коммитов требовался доступ к сети.

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

Хронология выхода VCS

Для контекста, вот график c датами появления этих инструментов:

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

SCCS (Source Code Control System): первое поколение

SCCS считается одной из первых успешных систем управления версиями. Она была разработана в 1972 году Марком Рочкиндом из Bell Labs. Система написана на C и создана для отслеживания версий исходного файла. Кроме того, она значительно облегчила поиск источников ошибок в программе. Базовая архитектура и синтаксис SCCS позволяют понять корни современных инструментов VCS.

Архитектура

Как и большинство современных систем, в SCCS есть набор команд для работы с версиями файлов:

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

Важно отметить, что все файлы отслеживаются и регистрируются отдельно. Невозможно проверить изменения в нескольких файлах в виде одного атомарного блока, как коммиты в Git. У каждого отслеживаемого файла свой файл истории, в котором хранится его история изменений. В общем случае это означает, что номера версий различных файлов в проекте обычно не совпадают друг с другом. Однако эти версии можно согласовать путём одновременного редактирования всех файлов в проекте (даже не внося в них реальные изменения) и одновременного добавления всех файлов. Это одновременно увеличит номер версии для всех файлов, сохраняя их согласованность, но обратите внимание, что это не то же самое, что включение нескольких файлов в один коммит, как в Git. В SCCS происходит индивидуальное добавление в каждый файл истории, в отличие от одного большого коммита, включающего все изменения сразу.

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

SCCS поддерживает ветви, которые хранят последовательности изменений в определённом файле. Можно произвести слияние ветви с исходной версией или с другой веткой.

Основные команды

Ниже приведён список наиболее распространенных команд SCCS.

Пример файла истории SCCS

RCS (Revision Control System): первое поколение

RCS написана в 1982 году Уолтером Тихи на языке С в качестве альтернативы системе SCCS, которая в то время не была опенсорсной.

Архитектура

У RCS много общего со своим предшественником, в том числе:

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

Основные команды

Ниже список наиболее распространённых команд RCS:

Пример файла истории RCS

CVS (Concurrent Versions System): второе поколение

CVS создана Диком Груном в 1986 году с целью добавить в систему управления версиями поддержку сети. Она также написана на C и знаменует собой рождение второго поколения инструментов VCS, благодаря которым географически рассредоточенные команды разработчиков получили возможность работать над проектами вместе.

Архитектура

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

Основные команды

Пример файла истории CVS

SVN (Subversion): второе поколение

Subversion создана в 2000 году компанией Collabnet Inc., а в настоящее время поддерживается Apache Software Foundation. Система написана на C и разработана как более надёжное централизованное решение, чем CVS.

Архитектура

Как и CVS, Subversion использует модель централизованного репозитория. Удалённым пользователям требуется сетевое подключение для коммитов в центральный репозиторий.

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

В настоящее время Subversion использует файловую систему FSFS (File System atop the File System). Здесь создаётся база данных со структурой файлов и каталогов, которые соответствуют файловой системе хоста. Уникальная особенность FSFS заключается в том, что она предназначена для отслеживания не только файлов и каталогов, но и их версий. Это файловая система с восприятием времени. Кроме того, директории являются полноценными объектами в Subversion. В систему можно коммитить пустые директории, тогда как остальные (даже Git) не замечают их.

Такая система работает только до определёного момента. Хотя дельты экономят место, но если их очень много, то на операции уходит немало времени, так как для воссоздания текущего состояния файла нужно обработать все дельты. По этой причине по умолчанию Subversion сохраняет до 1023 дельт на файл, а потом делает новую полную копию файла. Это обеспечивает хороший баланс хранения и скорости.

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

Основные команды

Пример файла истории SVN

Git: третье поколение

Систему Git разработал в 2005 году Линус Торвальдс (создатель Linux). Она написана в основном на C в сочетании с некоторыми сценариями командной строки. Отличается от VCS по функциям, гибкости и скорости. Торвальдс изначально написал систему для кодовой базы Linux, но со временем её сфера использования расширилась, и сегодня это самая популярная в мире система управлениями версиями.

Архитектура

Git является распределённой системой. Центрального репозитория не существует: все копии создаются равными, что резко отличается от VCS второго поколения, где работа основана на добавлении и извлечении файлов из центрального репозитория. Это означает, что разработчики могут обмениваться изменениями друг с другом непосредственно перед объединением своих изменений в официальную ветвь.

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

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

Основные команды

Пример блоба, дерева и коммита Git

Блоб с хэшем 37d4e6c5c48ba0d245164c4e10d5f41140cab980 :

Объект дерева с хэшем b769f35b07fbe0076dcfc36fd80c121d747ccc04 :

Коммит с хэшем dc512627287a61f6111705151f4e53f204fbda9b :

Mercurial: третье поколение

Mercurial создан в 2005 году Мэттом Макколлом и написан на Python. Он тоже разработан для хостинга кодовой базы Linux, но для этой задачи в итоге выбрали Git. Это вторая по популярности система управления версиями, хотя она используется гораздо реже.

Архитектура

Mercurial — тоже распределённая система, которая позволяет любому числу разработчиков работать со своей копией проекта независимо от других. Mercurial использует многие из тех же технологий, что и Git, в том числе сжатие и хэширование SHA-1, но делает это иначе.

Наконец, Mercurial использует ещё один тип revlog, который называется changelog, то есть журнал изменений. Это список записей, которые связывают каждый коммит со следующей информацией:

Основные команды

Пример файлов Mercurial

Журнал изменений (changelog):

Дополнительная информация об устройстве Mercurial:

Источник

Что такое VCS (система контроля версий)

Система контроля версий (от англ. Version Control System, VCS) — это место хранения кода. Как dropbox, только для разработчиков!

Она заточена именно на разработку продуктов. То есть на хранение кода, синхронизацию работы нескольких человек, создание релизов (бранчей). Но давайте я лучше расскажу на примере, чем она лучше дропбокса. Всё как всегда, история с кучей картиночек для наглядности ))

А потом я подробнее расскажу, как VCS работает — что значит «создать репозиторий», «закоммитить и смерджить изменения», и другие страшные слова. В конце мы пощупаем одну из систем VCS руками, скачаем код из открытого репозитория.

Что это такое и зачем она нужна

Допустим, что мы делаем калькулятор на Java (язык программирования). У нас есть несколько разработчиков — Вася, Петя и Иван. Через неделю нужно показывать результат заказчику, так что распределяем работу:

Вася делает сложение;

Иван — начинает умножение, но оно сложное, поэтому переедет в следующий релиз.

Исходный код калькулятора хранится в обычной папке на сетевом диске, к которому все трое имеют доступ. Разработчик копирует этот код к себе на машину, вносит изменения и проверяет. Если всё хорошо — кладет обратно. Так что код в общей папке всегда рабочий!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Итак, все забрали себе файлы из общей папки. Пока их немного:

Main.java — общая логика

GUI.java — графический интерфейс программы

С ними каждый и будет работать!

Вася закончил работу первым, проверил на своей машине — все работает, отлично! Удовлетворенно вздохнув, он выкладывает свой код в общую папку. Вася сделал отдельный класс на сложение (Sum.java), добавил кнопку в графический интерфейс (внес изменения в GUI.java) и прописал работу кнопки в Main.java.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Петя химичил-химичил, ускорял работу, оптимизировал. Но вот и он удовлетворенно вздохнул — готово! Перепроверил ещё раз — работает! Он копирует файлы со своей машины в общую директорию. Он тоже сделал отдельный класс для новой функции (вычитание — Minus.java), внес изменения в Main.java и добавил кнопку в GUI.java.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

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

— Катя, что случилось??

— Вы же сказали, что всё сделали! А в графическом интерфейсе есть только вычитание. Сложения нет!

— Как это нет? Я же добавлял!

Стали разбираться. Оказалось, что Петин файл затер изменения Васи в файлах, которые меняли оба: Main.java и GUI.java. Ведь ребята одновременно взяли исходные файлы к себе на компьютеры — у обоих была версия БЕЗ новых функций.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Вася первым закончил работу и обновил все нужные файлы в общей папке. Да, на тот момент всё работало. Но ведь Петя работал в файле, в котором ещё не было Васиных правок.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Поэтому, когда он положил документы в хранилище, Васины правки были стерты. Остался только новый файл Sum.java, ведь его Петя не трогал.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Хорошо хоть логика распределена! Если бы всё лежало в одном классе, было бы намного сложнее совместить правки Васи и Пети. А так достаточно было немного подправить файлы Main.java и GUI.java, вернув туда обработку кнопки. Ребята быстро справились с этим, а потом убедились, что в общем папке теперь лежит правильная версия кода.

Собрали митинг (жаргон — собрание, чтобы обсудить что-то):

— Как нам не допустить таких косяков в дальнейшем?

— Давайте перед тем, как сохранять файлы в хранилище, забирать оттуда последние версии! А ещё можно брать свежую версию с утра. Например, в 9 часов. А перед сохранением проверять дату изменения. Если она позже 9 утра, значит, нужно забрать измененный файл.

— Да, давайте попробуем!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Вася с Петей были довольны, ведь решение проблемы найдено! И только Иван грустит. Ведь он целую неделю работал с кодом, а теперь ему надо было синхронизировать версии. То есть объединять свои правки с изменениями коллег.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

Когда он пришел с утра, в офисе был переполох. Вася бегал по офису и причитал:

— Мои изменения пропали. А я их не сохранил!

Увидев Ваню, он подскочил к нему и затряс за грудки:

— Зачем ты стер мой код??

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

После этого изменения вносил Иван. Да, он внимательно вычитывал файлы с кодом и старался учесть и свои правки, и чужие. Но изменений слишком много, часть Васиных правок он потерял.

— Код теперь не работает! Ты вообще проверял приложение, закончив синхронизацию?

— Нет, я только свою часть посмотрел.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Вася покачал головой:

— Но ведь при сохранении на общий диск можно допустить ошибку! По самым разным причинам:

Разработчик начинающий, чаще допускает ошибки.

Случайно что-то пропустил — если нужно «объединить» много файлов, что-то обязательно пропустишь.

Посчитал, что этот код не нужен — что он устарел или что твоя новая логика делает то же самое, а на самом деле не совсем.

И тогда приложение вообще перестанет работать. Как у нас сейчас.

— Хм. Да, пожалуй, ты прав. Нужно тестировать итоговый вариант!

— И сохранять версии. Может, перенесем наш код в Dropbox, чтобы не терять изменения?

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

Через пару дней ребята снова собрали митинг:

— Ну как вам в дропбоксе?

— Уже лучше. По крайней мере, не потеряем правки!

Петя расстроенно пожимает плечами:

— Да, только мы с Васей одновременно вносили изменения в Main.java, создалась конфликтующая версия. И пришлось вручную их объединять. А класс то уже подрос! И глазками сравнивать 100 строк очень невесело. Всегда есть шанс допустить ошибку.

— Ну, можно же подойти к тому, кто создал конфликт и уточнить у него, что он менял.

— Хорошая идея, давайте попробуем!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Попробовали. Через несколько дней снова митинг:

— Да всё зашибись, работаем!

— А почему код из дропбокса не работает?

— Как не работает. Мы вчера с Васей синхронизировались!

— А ты попробуй его запустить.

Посмотрели все вместе — и правда не работает. Какая-то ошибка в Main.java. Стали разбираться:

— Так, тут не хватает обработки исключения.

— Ой, подождите, я же её добавлял!

— Но ты мне не говорил о ней, когда мы объединяли правки.

— Может, еще что забыл? Ну уж давай лучше проверим глазами.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Посидели, выверили конфликтные версии. Потратили час времени всей команды из-за пустяка. Обидно!

— Слушайте, может, это можно как-то попроще делать, а? Чтобы человека не спрашивать «что ты менял»?

— Можно использовать программу сравнения файлов. Я вроде слышал о таких. AraxisMerge, например!

— Ой, точно! В IDEA же можно сравнивать твой код с клипбордом (сохраненным в Ctrl + C значении). Давайте использовать его!

Начали сравнивать файлы через программу — жизнь пошла веселее. Но через пару дней Иван снова собрал митинг:

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

— Да? И что за программы?

— Системы контроля версий называются. Вот SVN, например. Давайте попробуем его?

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Попробовали. Работает! Еще и часть правок сама синхронизирует, даже если Вася с Петей снова не поделили один файл. Как она это делает? Давайте разбираться!

Как VCS работает

Подготовительная работа

Это те действия, которые нужно сделать один раз.

1. Создать репозиторий

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

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

А потом Вася берет код из дропбокса, и кладет его в VCS специальной командой. В разных системах контроля версии разные названия у команды, но суть одна — создать репозиторий, в котором будет храниться код.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Всё! Теперь у нас есть общее хранилище данных! С ним дальше и будем работать.

2. Скачать проект из репозитория

Теперь команде нужно получить проект из репозитория. Можно, конечно, и из дропбокса скачать, пока там актуальная версия, но давайте уже жить по-правильному!

Поэтому Петя, Вася и Иван удаляют то, что было у них было на локальных компьютерах. И забирают данные из репозитория, клонируя его. В Mercurial (один из вариантов VCS) эта команда так и называется — clone. В других системах она зовется иначе, но смысл всё тот же — клонировать (копировать) то, что лежит в репозитории, к себе на компьютер!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

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

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Ежедневная работа

А это те действия, которые вы будете использовать часто.

1. Обновить проект, забрать последнюю версию из репозитория

Приходя утром на работу, нужно обновить проект на своем компьютере. Вдруг после твоего ухода кто-то вносил изменения?

Так, Вася обновил проект утром и увидел, что Ваня изменил файлы Main.java и GUI.java. Отлично, теперь у Васи актуальная версия на машине. Можно приступать к работе!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

В SVN команда обновления называется «update», в Mercurial — «pull». Она сверяет код на твоем компьютере с кодом в репозитории. Если в репозитории появились новые файлы, она их скачает. Если какие-то файлы были удалены — удалит и с твоей машины тоже. А если что-то менялось, обновит код на локальном компьютере.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Тут может возникнуть вопрос — в чем отличие от clone? Можно же просто клонировать проект каждый раз, да и всё! Зачем отдельная команда?

Клонирование репозитория производится с нуля. А когда разработчики работают с кодом, у них обычно есть какие-то локальные изменения. Когда начал работу, но ещё не закончил. Но при этом хочешь обновить проект, чтобы конфликтов было меньше.

Если бы использовалось клонирование, то пришлось бы переносить все свои изменения в «новый» репозиторий вручную. А это совсем не то, что нам нужно. Обновление не затронет новые файлы, которые есть только у вас на компьютере.

А еще обновление — это быстрее. Обновиться могли 5 файликов из 1000, зачем выкачивать всё?

2. Внести изменения в репозиторий

Вася работает над улучшением сложения. Он придумал, как ускорить его работу. А заодно, раз уж взялся за рефакторинг (жаргон — улучшение системы, от англ. refactor), обновил и основной класс Main.java.

Перед началом работы он обновил проект на локальном (своём) компьютере, забрав из репозитория актуальные версии. А теперь готов сохранить в репозиторий свои изменения. Это делается одной или двумя командами — зависит от той VCS, которую вы используете в работе.

1 команда — commit

Пример системы — SVN.

Сделав изменения, Вася коммитит их. Вводит команду «commit» — и все изменения улетают на сервер. Всё просто и удобно.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

2 команды — commit + push

Примеры системы — Mercurial, Git.

Сделав изменения, Вася коммитит их. Вводит команду «commit» — изменения сохранены как коммит. Но на сервер они НЕ уходят!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Чтобы изменения пошли на сервер, их надо «запушить». То есть ввести команду «push».

Это удобно, потому что можно сделать несколько разных коммитов, но не отправлять их в репозиторий. Например, потому что уже code freeze и тестировщики занимаются регрессией. Или если задача большая и может много всего сломать. Поэтому её надо сначала довести до ума, а потом уже пушить в общий репозиторий, иначе у всей команды развалится сборка!

При этом держать изменения локально тоже не слишком удобно. Поэтому можно спокойно делать коммиты, а потом уже пушить, когда готов. Или когда интернет появился =) Для коммитов он не нужен.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Итого

Когда разработчик сохраняет код в общем хранилище, он говорит:

Смотря в какой системе он работает. После этих слов вы уверены — код изменен, можно обновить его на своей машине и тестировать!

3. Разрешить конфликты (merge)

Вася добавил вычисление процентов, а Петя — деление. Перед работой они обновили свои локальные сборки, получив с сервера версию 3 файлов Main.java и Gui.java.

Для простоты восприятия нарисуем в репозитории только эти файлы и Minus.java, чтобы показать тот код, который ребята трогать не будут.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Вася закончил первым. Проверив свой код, он отправил изменения на сервер. Он:

Добавил новый файл Percent.java

Обновил Main.java (версию 3)

Обновил Gui.java (версию 3)

При отправке на сервер были созданы версии:

Percent.java — версия 1

Main.java — версия 4

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Петя закончил чуть позже. Он:

Добавил новый файл Division.java

Обновил Main.java (версию 3, ведь они с Васей скачивали файлы одновременно)

Обновил Gui.java (версию 3)

Готово, можно коммитить! При отправке на сервер были созданы версии:

Division.java — версия 1

Main.java — версия 4

Но стойте, Петя обновляет файлы, которые были изменены с момента обновления кода на локальной машине! Конфликт!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Часть конфликтов система может решить сама, ей достаточно лишь сказать «merge». И в данном случае этого будет достаточно, ведь ребята писали совершенно разный код, а в Main.java и Gui.java добавляли новые строчки, не трогая старые. Они никак не пересекаются по своим правкам. Поэтому система «сливает» изменения — добавляет в версию 4 Петины строчки.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Но что делать, если они изменяли один и тот же код? Такой конфликт может решить только человек. Система контроля версий подсвечивает Пете Васины правки и он должен принять решение, что делать дальше. Система предлагает несколько вариантов:

Оставить Васин код, затерев Петины правки — если Петя посмотрит Васны изменения и поймет, что те лучше

Затереть Васины правки, взяв версию Петра — если он посчитает, что сам все учел

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

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

Но, разумеется, конфликты все равно бывают. Разработчики делают сложные задачи, на которые уходит день-два. Они затрагивают одни и те же файлы. В итоге, вливая свои изменения в репозиторий, они получают кучу конфликтов, и нужно просмотреть каждый — правильно ли система объединила файлы? Не нужно ли ручное вмешательство?

Особая боль — глобальный рефакторинг, когда затрагивается МНОГО файлов. Обновление версии библиотеки, переезд с ant на gradle, или просто выкашивание легаси кода. Нельзя коммитить его по кусочкам, иначе у всей команды развалится сборка.

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

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

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

Тестировщик будет сильно реже попадать в конфликтные ситуации, просто потому, что пишет меньше кода. Иногда вообще не пишет, иногда пополняет автотесты. Но с разработкой при этом почти не пересекается. Однако выучить merge все равно придется, пригодится!

4. Создать бранч (ветку)

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

— Что делать будем? Не коммитить до показа?

— У меня уже готовы новые изменения. Давайте закоммичу, я точно ничего не сломал.

Катя хватается за голову:

— Ой, давайте без этого, а? Мне потом опять краснеть перед заказчиками!

Тут вмешивается Иван:

— А давайте бранчеваться!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Все оглянулись на него:

Иван стал рисовать на доске:

— Бранч — это отдельная ветка в коде. Вот смотрите, мы сейчас работаем в trunk-е, основной ветке.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Когда мы только-только добавили наш код на сервер, у нас появилась «точка возврата» — сохраненная версия кода, к которой мы можем обратиться в любой момент.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Потом Вася закоммитил изменения по улучшению классов — появилась версия 1 кода.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Потом он добавил проценты — появилась версия кода 2.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

При этом в самой VCS сохранены все версии, и мы всегда можем:

Посмотреть изменения в версии 1

Сравнить файлы из версии 1 и версии 2 — система наглядно покажет, где они совпадают, а где отличаются

Откатиться на прошлую версию, если версия 2 была ошибкой.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Потом Петя добавил деление — появилась версия 3.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Теперь, если я захочу закоммитить изменения, они по-прежнему пойдут в основную ветку. Бранч при этом трогать НЕ будут (изменения идут в ту ветку, в которой я сейчас нахожусь. В этом примере мы создали branch, но работать продолжаем с trunk, основной веткой)

Так что мы можем смело коммитить новый код в trunk. А для показа использовать branch, который будет оставаться стабильным даже тогда, когда в основной ветке всё падает из-за кучи ошибок.

С бранчами мы всегда будем иметь работающий код!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

— Подожди, подожди! А зачем эти сложности? Мы ведь всегда может просто откатиться на нужную версию! Например, на версию 2. И никаких бранчей делать не надо!

— Это верно. Но тогда тебе нужно будет всегда помнить, в какой точке у тебя «всё работает и тут есть все нужные функции». А если делать говорящие названия бранчей, обратиться к ним намного проще. К тому же иногда надо вносить изменения именно в тот код, который на продакшене (то есть у заказчика).

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

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Заказчику нужно исправление ошибки, но он не готов ставить новую версию — ведь ее надо тестировать, а цикл тестирования занимает неделю. А баг то нужно исправить здесь и сейчас! Получается, нам надо:

Обновиться на версию 3

Исправить баг локально (на своей машине, а не в репозитории)

Никуда это не коммитить = потерять эти исправления

Собрать сборку локально и отдать заказчику

Не забыть скопипастить эти исправления в актуальную версию кода 33 и закоммитить (сохранить)

Что-то не очень весело. А если нужно будет снова дорабатывать код? Искать разработчика, у которого на компьютере сохранены изменения? Или скопировать их и выложить на дропбокс? А зачем тогда использовать систему контроля версий?

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Именно для этого мы и бранчуемся! Чтобы всегда иметь возможность не просто вернуться к какому-то коду, но и вносить в него изменения. Вот смотрите, когда Заказчик нашел баг, мы исправили его в бранче, а потом смерджили в транк.

Смерджили — так называют слияние веток. Это когда мы внесли изменения в branch и хотим продублировать их в основной ветке кода (trunk). Мы ведь объединяем разные версии кода, там наверняка есть конфликты, а разрешение конфликтов это merge, отсюда и название!

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Если Заказчик захочет добавить новую кнопочку или как-то еще изменить свою версию кода — без проблем. Снова вносим изменения в нужный бранч + в основную ветку.

Веток может быть много. И обычно чем старше продукт, тем больше веток — релиз 1, релиз 2. релиз 52.

Есть программы, которые позволяют взглянуть на дерево изменений, отрисовывая все ветки, номера коммитов и их описание. Именно в таком стиле, как показано выше =) В реальности дерево будет выглядеть примерно вот так (картинка из интернета):

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

А иногда и ещё сложнее!

— А как посмотреть, в какой ветке ты находишься?

— О, для этого есть специальная команда. Например, в Mercurial это «hg sum»: она показывает информацию о том, где ты находишься. Вот пример ее вызова:

В данном примере «parent» — это номер коммита. Мы ведь можем вернуться на любой коммит в коде. Вдруг мы сейчас не на последнем, не на актуальном? Можно проверить. Тут мы находимся на версии 3. После двоеточия идет уникальный номер ревизии, ID кода.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

Потом мы видим сообщение, с которым был сделан коммит. В данном случае разработчик написал «Try to fix bug with device».

И, наконец, параметр «branch»! Если там значение default — мы находимся в основной ветке. То есть мы сейчас в trunk-е. Если бы были не в нём, тут было бы название бранча. При создании бранча разработчик даёт ему имя. Оно и отображается в этом пункте.

управление версиями исходного кода. Смотреть фото управление версиями исходного кода. Смотреть картинку управление версиями исходного кода. Картинка про управление версиями исходного кода. Фото управление версиями исходного кода

— Круто! Давайте тогда делать ветку!

Для Git создали интерактивную «игрушку», чтобы посмотреть на то, как происходит ветвление — https://learngitbranching.js.org

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

Итого

Система контроля версий (от англ. Version Control System, VCS) — это dropbox для кода.

Популярные VCS и отличия между ними

Наиболее популярные — это:

SVN — простая, но там очень сложно мерджиться

Mercurial (он же HG), Git — намного больше возможностей (эти системы похожи по функционалу)

SVN — очень простая система, одна из первых. Сделал — закоммитил. Всё! Для небольшого проекта её вполне достаточно. Вы можете делать разные ветки и мерджить хоть туда, хоть сюда. Но у неё так себе работает автомитический мерджа, на моей практике приходилось каждый файлик брать и копипастить изменения в основную ветку, это было проще, чем смерджить.

Главные трудности в svn — всегда нужна сеть, и он может быть очень мммееееддддленный. Ну и с ветками работать не так удобно, в svn это просто директории. Хотя для новичков «папки» svn обычно интуитивнее.

А в целом, svn просто другая система (он работает просто как файловая система) со своими преимуществами и недостатками. Его легко поставить на windows (не тянет за собой треть линукса), он безопасен (все что закоммичено — сохранено навеки, удалить нельзя ничего, никакого rebase), легко сделать checkout одной маленькой части проекта и работать только с ней (а это позволяет модный монорепо без костылей), можно мешать ревизии отдельных файлов в папке проекта и мерджить отдельные файлы произвольным образом. Права доступа к отдельным частям проекта — легко. svn работает с бинарными данными и даже (теоретически) как-то мерджит. Легко аутентификацию по сертификату. Встроенный WebDAV с минимальными усилиями: можно смонтировать как диск в Windows для тех, кому нужен доступ только для чтения, или просто бросить ссылку для браузера (какие-нибудь дизайнеры так могут любоваться картинками из svn или скрипт может получать последние бинарные данные для управления коллайдером).

Mercurial и Git — распределенная система контроля версий. Внесение изменений двухступенчатое — сначала коммит, потом push. Это удобно, если вы работаете без интернета, или делаете мелкие коммиты, но не хотите ломать основной код пока не доделаете большую задачу. Тут есть и автоматическое слияние разных бранчей. Больше возможностей дают системы.

У любой системы контроля версий есть «консольный интерфейс». То есть общаться с ними можно напрямую через консоль, вводя туда команды. Склонировать репозиторий, обновить его, добавить новый файл, удалить старый, смерджить изменения, создать бранч. Всё это делается с помощью команд.

Но любой графический интерфейс как работает? Вы потыкали мышкой, а система Tortoise составила консольную команду из вашего «тык-тык», её и применила.

Что такое API — подробнее о том, что скрывается за интерфейсом.

Вот некоторые базовые команды и форма их записи в разных VCS:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *