devhub 3 - cvs

26
СИСТЕМЫ КОНТРОЛЯ ВЕРСИЙ: ЕСТЬ О ЧЁМ ПОГОВОРИТЬ Владимир Фесько CTO @ Smile Ukraine

Upload: magento-dev

Post on 05-Dec-2014

248 views

Category:

Engineering


3 download

DESCRIPTION

 

TRANSCRIPT

Page 1: DevHub 3 - CVS

СИСТЕМЫ КОНТРОЛЯ ВЕРСИЙ: ЕСТЬ О ЧЁМ ПОГОВОРИТЬ

Владимир Фесько CTO @ Smile Ukraine

Page 2: DevHub 3 - CVS

Мы рассмотрим вопрос контроля версий в проекте. Поговорим в контексте двух систем - GIT (стильно, модно, моложёжно) и SVN - это, оказывается, не менее популярная, а даже и более распространённая система контроля версий (по данным каталога свободного ПО ohloh.net). Мне довелось поработать с обеими системами, вначале с SVN, за тем и с GIT, включая миграцию проектов и околопроектных сервисов на GIT. Под околопроектными сервисами имеются ввиду

различные пре- и посткоммит хуки и системы развёртывания приложений. На основе этого опыта и мнения разработчиков нашей компании Smile я и хочу сравнить эти системы и узнать, правду ли гласит информация с сайта GIT, всяко разно расхваливая его и называя SVN пережитком прошлого.

Page 3: DevHub 3 - CVS

Использование систем контроля версий GIT и SVN в проектах с открытым исходным

кодом в каталоге ohloh.net

50 000

100 000

150 000

200 000

250 000

300 000

350 000

Авг'10 Май'11 Фев'12 Июнь'12 Окт'13 Июль'14

GIT SVN

Page 4: DevHub 3 - CVS

Цифры не лгут, SVN всегда был на шаг впереди GITа, а в последний год даже начал немного вырываться вперёд. А это значит, что SVN совсем не умер, он живее всех живых! Но, по некоторым причинам, о которых мы сегодня и

поговорим, молодая часть Интернетов считает, что SVN одного возраста с мамонтами, работает непростительно медленно, криво и совсем не мерджит. Ах да, чуть не забыл, и создаёт везде папки .svn

Page 5: DevHub 3 - CVS

Хозяйке на заметку. Я просто оставлю это здесь.

Ohloh.net, http://www.ohloh.net Бесплатный публичный каталог программ с открытым исходным кодом, построен по принципу вики. По состоянию на июль 2014 года там зарегистрировано 664,816 проектов. Это не хостинг проектов, а служба, позволяющая анализировать эти проекты. !Wayback Machine, https://archive.org/ Архив Интернета - обеспечивает долгосрочное архивирование собранного материала и бесплатный доступ к своим базам данных для широкой публики. По состоянию на октябрь 2012 года размер Архива — 10 петабайт. По состоянию на июнь 2014 года он содержит 415 миллиардов веб-страниц

Page 6: DevHub 3 - CVS

НУ ДАВАЙ, РАССКАЖИ МНЕ !

!

!

!

КАКОЙ ПЛОХОЙ SVN И КАКОЙ НЯШНЫЙ GIT

Page 7: DevHub 3 - CVS

Начнём с того, что системы разные, и построены они по разным принципам. GIT - это распределённая система, а SVN - централизованная. Это важное различие накладывает некоторые

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

сомнительную завесу унылости SVN и показать, что SVN ни чем не хуже GITа, а в некоторых местах - даже лучше, потому что он проще, а это значит, что шансы "выстрелить себе в ногу" гораздо меньше.

Page 8: DevHub 3 - CVS

Централизованные (Centralized) и распределённые (Distributed) системы

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

+ простота команд + сквозная нумерация коммитов + удобное линейное перемещение по

монолитной неизменяемой* истории + простой контроль доступа к элементам

репозитория + частичный чекаут/экспорт - очень часто нужна связь с

центральным сервером - неприлично медленный upstream - нельзя локально просмотреть историю

и создать ветку* - много наговаривают в Интернетах из-

за убогости версий до 1.5 (Июнь’08) и, частично, до 1.7 (Окт’11)

+ высокая скорость upstream + просмотр истории локально + не нужно частое подключение к

серверу + располагает к созданию локальных

веток - бóльший размер оверхеда из-за всей

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

элементам репозитория - нелепая невозможность хранить

пустые папки - хеш-нумерация коммитов - возможность перезаписи истории

(rebase, squash…)

Page 9: DevHub 3 - CVS

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

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

сложнее, чем перематывать плёнку в кассете - ты всегда знаешь, что находишься в контексте определённого состояния и ни одна душа (ну, кроме админа с root доступом к центральному репозиторию) эту историю изменить не в состоянии.

Page 10: DevHub 3 - CVS

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

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

И всеми удалёнными ветками тоже. GIT всё запоминает. И при клонировании репозитория нам всё

это приходит. Кто-то мне говорил, что SVN даёт много оверхеда. До GITа ей ой как далеко. Ну а что же с контролем? Как защитить какие-то части проекта

от изменений, например? В SVN - проще простого. С точностью до файла. А в GIT? Можно лишь частично, нужно писать server-side hook, который будет проверять что там в коммите меняется и реджектить его, если лезем туда, куда не следует.

Page 11: DevHub 3 - CVS

Но зато скорость записи в удалённый репозиторий у GIT в разы и разы больше. Я пробовал делать чекаут второй маженты (в моём докладе должно было быть что-то про вторую маженту - вот оно), чекаут второй маженты из гита и свн занимал приблизительно одинаковое время - т.е. результат разнился не более чем на 20%. Но вот push всего проекта в чистый репозиторий… В GIT

- соизмеримо с checkout - в SVN - я не дождался. Терпение кончилось на каком-то модуле в районе буквы D. Это действительно крайне неприятно и долго в SVN -

сделать коммит кучи мелких файлов. Вот первое адекватное правило при выборе системы

контроля версий - если нужно часто коммитить много файлов - используйте GIT - это будет быстрее.

Page 12: DevHub 3 - CVS

Про SVN вообще многие отзываются негативно и не хотят на нём работать, по нескольким причинам - первая - не рекомендуют старшие товарищи, столкнувшиеся с SVN и по тем или иным причинам не взлюбившие эту систему. Если они работали со старым SVN’ом до версии 1.7 или даже

до 1.5 - то я их понимаю - там проблем было гораздо больше. Но было это от 3-х до 6-ти лет назад, а детская травма всё не

даёт покоя. Отсюда еще одно правило - если проект на SVN - то

работайте с версией 1.7. В ней уже решены многие проблемы и замазаны слабые места. Уже только одна папка .svn в корне проекта! Чекаут проекта стал еще быстрее! А вообще, чего только стоит возможность частичного чекаута и экспорта ресурсов из репозитория? Попробуйте подправить часть большого проекта в ГИТ - придётся выкачивать весь репозиторий целиком! Даже самая мелкая правка в походных условиях потребует от нас наличия полного репозитория проекта.

Page 13: DevHub 3 - CVS

SVN и GIT: первоначальная настройка

# Настройка идентификации git:$ git config --global user.name "Volodymyr Fesko" git:$ git config --global user.email [email protected] !# Правильная обработка line-endings в репозитории git:$ git config core.autocrlf native !# Игнор мониторинга разрешений на файлы # Для изменения разрешений используем git update-index --chmod=+x foo.bar git:$ git config core.filemode false !# Используем .gitattributes вместе с .gitignore для настройки репозитория !# Правильная обработка line-endings в репозитории # svn:eol-style=native в auto-props # http://www.mediawiki.org/wiki/Subversion/auto-props

Page 14: DevHub 3 - CVS

SVN и GIT workflow: новый репозиторий

# Создаём репозиторий svn:$ svnadmin create /home/me/svn-repo !# Импортируем файлы проекта svn:$ svn import /home/me/project-files \ file:///home/me/svn-repo/trunk -m "Initial commit" svn:$ svn co file:///home/me/svn-repo /home/me/project !# Создаём репозиторий git:$ cd /home/me/project-files git:$ git init !# Импортируем файлы проекта git:$ git add . git:$ git commit -m "Initial commit"

Page 15: DevHub 3 - CVS

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

файлов в репозитории с последующим коммитом - командой copy. Но есть большая, принципиальная разница в том, какие

параметры передавать этой команде. В SVN ветки создаются всегда на сервере, причём одинаково

быстро вне зависимости от размера репозитория - здесь они по скорости не проигрывают веткам в GIT. Для создания ветки мы должны сказать SVN, чтобы она

выполнила копирования на сервере, а не внутри рабочей копии. Для этот перед папкой, из котороый мы создаём ветку (а это

не обязательно должен быть корень транка, это может быть любое поддерево), перед этим путём нужно использовать либо полный путь к репозиторию https://, например, или же простой символ - крышечку.

Page 16: DevHub 3 - CVS

При переключении веток - то же самое, либо полный адрес, либо крышечка. Время от времени подмешиваем в нашу ветку изменения из транка, а затем, когда уже всё готово, сливаем изменения из ветки в транк с ключем reintegrate. Это обязательное условие обратного объединения ветки feature с транком, т.к. начиная с версии 1.5 в SVN появился трекинг мерджей, который по сути просто запоминает какие ревизии куда были смерджены. До версии 1.5 нам приходилось явно указывать набор ревизий для мерджа веток, чтобы не сливать одни и те же изменения по два раза. Теперь SVN трекает это самостоятельно. Если мы мерджим транк в нашу feature ветку, при этом

разрешая конфликты, то при обратном мердже в транк мы потеряем эти разрешения, т.к. мердж с разрешёнными конфликтами - это отдельный коммит и он будет записан в mergeinfo и пропущен при объединений ветки feature и транка.

Page 17: DevHub 3 - CVS

SVN и GIT workflow: ветки

# Создаём ветку svn:$ svn cp ^/trunk ^/branches/feature-1 !# Переключаемся в ветку svn:$ svn sw ^/branches/feature-1 !# Подтягиваем изменения из транка в свою ветку - время от времени # А также непосредственно перед интеграцией ветки обратно в транк svn:$ svn merge ^/trunk !# Мерджим ветку обратно в транк. КОГДА УЖЕ ВСЁ В НЕЙ ГОТОВО! После этого работать в feature-1 НЕЛЬЗЯ. Только если её удалить и заново отпочковать от транка - иначе потеряете всю работу по разрешению конфликтов при мердже в транк svn:$ svn sw ^/trunk svn:$ svn merge --reintegrate ^/branches/feature-1 svn:$ svn delete ^/branches/feature-1 !# P.S. Создать ветку на сервере, константа по времени - правильно svn cp ^/trunk ^/branches/feature-1 # Скопировать содержимое и закоммитить - долго, неправильно svn cp trunk branches/feature-1

Page 18: DevHub 3 - CVS

SVN и GIT workflow: ветки

# Создаём ветку и переключаемся в неё git:$ git checkout -b feature-1 !# Подтягиваем изменения из master в свою ветку - время от времени # А также непосредственно перед интеграцией ветки обратно в master # Rebase делаем только для локальных веток. После push на origin - только merge, чтобы коммиты не менялись git:$ git rebase master git:$ git merge master !# Мерджим ветку обратно в master git:$ git checkout master git:$ git merge feature-1 !# Push изменений git:$ git push origin master

Page 19: DevHub 3 - CVS

Самым слабым место в GIT я считаю возможность переписывать историю, делая rebase или sqaush коммитов. Этим можно пользоваться в локальном репозитории, но

никак не в удалённом - если с вами на проекте работают еще разработчики, то после пуша изменений ни в коем случае не нужно делать rebase, т.к. это изменит все коммиты вашей ветки после точки её отпочкования от основной и, если кто-то их уже использовал как родительские или изменил их (не дай Бог), то мы рискуем нарваться на сложности, которых можно было просто избежать, потеряем лишнее время. Не бойтесь, что мердж создаст вам лишний коммит, а

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

Page 20: DevHub 3 - CVS

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

контроля версий до и после действий типа коммита. На пре-коммит хуки обычно вешаются код снифферы и

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

формата коммит сообщения и поиска в нём номера тикета в багтрекере. Это простые баш скрипты, которые запускаются

системой в нужные моменты.

Page 21: DevHub 3 - CVS

SVN и GIT: хуки (перечислены шаблоны и примеры)

# Хуки - это скрипты в папке hooks, делятся на pre- и post-action # SVN /home/me/svn-repo/hooks: post-commit.tmpl post-lock.tmpl post-revprop-change.tmpl post-unlock.tmpl pre-commit.tmpl pre-lock.tmpl pre-revprop-change.tmpl pre-unlock.tmpl start-commit.tmpl !# GIT /home/me/project-files/.git/hooks: applypatch-msg.sample commit-msg.sample post-update.sample pre-applypatch.sample pre-commit.sample pre-push.sample pre-rebase.sample prepare-commit-msg.sample update.sample

Page 22: DevHub 3 - CVS

И вторая классная штука - это внешние компоненты - submodules в терминах GIT и externals в SVN. Это возможность собрать наш проект из отдельных кирпичиков, переиспользовать код модулей из других репозиториев - в общем, очень клёвая фича. В SVN она проста до безобразия, а вот в GIT есть нюансы,

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

svn:externals  при помощи svn:propset. Указываем имя подпапки, в которую необходимо выдернуть внешний ресурс, делаем svn up - и всё, внешний код уже у нас. В GIT у нас два варианта - submodules и subtree merge. Сабмодули штука неповоротливая - целый внешний репозиторий включаем в проект, нет возможности взять лишь какую-то его папку. С сабтри мерджем чуть лучше ситуация, и обновляется он сам, но в настройке посложнее будет. Опять же в ГИТе всё сложнее, чем должно быть.

Page 23: DevHub 3 - CVS

SVN и GIT: внешние компоненты

# svn:externals - чрезвычайно просто svn:$ svn propset svn:externals 'foobar http://repo.url/tags/1.0' . svn:$ svn up Updating '.': !Fetching external item into 'foobar': A foobar/class.php ... !# GIT # Вариант 1: subtree merge https://help.github.com/articles/working-with-subtree-merge - сложнее, но можно использовать компоненты репозитория !# Вариант 2: submodules git:$ submodule add git://github.com/chneukirchen/rack.git foobar - проще, но берём репозиторий целиком - нужно обновлять вручную и клонировать с --recursive !http://git-scm.com/book/en/Git-Tools-Submodules

Page 24: DevHub 3 - CVS

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

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

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

Page 25: DevHub 3 - CVS

Облачный хостинг систем контроля версий: CloudForge для GIT и SVN

Page 26: DevHub 3 - CVS

СИСТЕМЫ КОНТРОЛЯ ВЕРСИЙ: ЕСТЬ О ЧЁМ ПОГОВОРИТЬ

Владимир Фесько CTO @ Smile Ukraine

!vlfesko.com

[email protected]

Пока всё =) Спасибо!