21 September 2010

Использование git во Flash разработке

Git
Я давно уже начал писать эту статью, но меня опередили (8.
Основная задумка была объяснить братьям флэшерам как работать с git. В статье я попытался описать свой личный опыт, а не просто перечислить очевидные плюсы git. Поэтому она будет полезна всем.

В первую очередь буду рад дополнениям и исправлениям. И конечно же вопросам.

Что такое git


git — это распределенная система контроля версий. Отличается от SVN отсутствием необходимости в центральном репозитории (который все же хорошо было бы держать) и легкостью работы с ветками (branch). Изначально я решил попробовать его в работе прочитав эту статью, что всем рекомендую.

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


Почему git


Все мы понимаем, что использовать систему контроля версий жизненно необходимо. git в повседневном использовании показал себя очень хорошо и позволил решить ряд проблем. Приведу основные плюсы и «фишки».
  1. Распределенность
    Создать репозиторий в локальной папке можно просто написав
  2. Наличие стабильного клиента
    Процесс разработки без ветвлений выглядит примерно так: версия… разработка… версия… разработка…
    Видно, что в каждый момент времени наличие стабильной версии, на которой можно поправить баги и зарелизить, не гарантировано. А точнее, получается так, что исправить некий выловленный баг можно только закончив разработку текущей версии. Простые ветки в git позволяют в любое время достать версию любого предыдущего релиза и работать с ней не мешая идущей разработке. Исправить баги в отдельной ветке, смержить в предыдущий релиз и в текущую разработку.
  3. Удобство использования
    git хранит все свои данные в одном каталоге, а не плодит повсюду папки .svn. Переключить проект с одной ветки на другую можно всего одной командой или парой кликов в клиенте. При этом содержимое папки проекта заменяется новым, которое соответствует выбранной ветке. Для разных веток не нужно создавать новые папки или проекты. В большинстве случаев, Flash Builder сам обновит все классы и перекомпилит зависимости.
  4. Нет необходимости в постоянном конекте к центральному хранилищу
    Как я уже сказал, все комиты сохраняются локально и становятся частью общего репозитория только тогда, когда непосредственно пушатся в него. Это сложно вообразить, но порой получается так, что нет доступа в интернет, а работать нужно. Или вы как обычно забыли настроить VPN к рабочему репозиторию. Радует скорость комитов и ощущение полного контроля над локальной копией.
  5. Удобные частичные комиты
    Непосредственно перед комитом помечаются файлы, которые в него войдут с помощью git add. При этом существует возможность в отдельный комит внести часть изменений в файле, а не файл целиком.
  6. Возможность припрятать изменения.
    В git есть интересная возможность — припрятать (stash) незакомиченные файлы и потом достать их снова. Иногда бывает полезно таким образом переносить или временно откатывать изменения, например, я часто забываю переключать ветки.
  7. Наличие графических клиентов.
    Для git не такой уж и большой выбор графических клиентов. Мне больше всего понравился GUI клиент SmartGit. Он кроссплатформенный и для некоммерческого использования доступен бесплатно. Обладает всеми нужными функцими, но все же иногда бывает нужно залезть в Terminal и выполнить пару команд git. Хорошо бы в них примерно разбираться. Для Винды есть TortoiseGit, на Маке я пользовался некоторое время GitX, но тогда он был уж сильно хуже, чем SmartGit. Для Eclipse (то есть для Flash Builder) есть плагин EGit, который давно мне чем-то не понравился. Надо будет вернуться к нему еще раз, тем более он только что обновился. Возможно, это не фишка клиента, а часть дистрибутива git, но тем не менее, хочется упомянуть еще классное отображение веток. В сложном проекте выглядит как карта метро Нью Йорка. Люблю я такие абстрактные картиночки.

TODO или что еще нужно проверить


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

Пока же я предлагал GitHub как интересный вариант хранения проектов с разграничением доступа. Но, понимаете ли, корпоративная секурность итд (хотя код воруют направо и налево и без этого). Сам я использую его для своих личных проектов. Удобненько.

Установка и настройка


Git. Mac / Linux


Для начала нужно установить сам git. Линуксоиды без сомнения разберутся и сами, а скорее всего он у них уже установлен. Маководы могут скачать дистрибутив с официального сайта или установить через MacPorts. Как ставить MacPorts тоже разобраться труда не составляет.

В MacPorts открываем Terminal и вводим.
sudo port

Скорее всего не через админский акаунт ничего установить не разрешит, так что вызываем через sudo и вводим пароль. Дальше смотрим какие есть репозитории начинающиеся с git.
list git*

На экране появится что-то типа
git-core                       @1.7.2.1        devel/git-core
GitX                           @0.7.1          devel/GitX

GitX — это GUI клиент, о котором я уже писал. Нас же интересует git-core. Чтобы установить его, нужно написать
install git-core

Проверить правильность установки можно набрав в консоли git --version.

Для доступа к удаленным репозиториям Вам понадобится SSH ключ. Сгенерить его на Mac не составляет никаких проблем.

Git. Windows

Для Windows существует порт msysgit. Качаем последнюю версию и устанавливаем.
Git изначально какбы чужероден для Windows. С этим могут быть связаны некоторые проблемы. Например, мы какое-то время не могли заставить его работать с удаленными репозиториями. Ругался на SSH ключ. Спасибо GitHub'у за решение этой проблемы. Так вот, не пытайтесь сгенерить ключ с помощью Putty. Чтобы сгенерить правильный ключ нужно:
  1. Запустить Git Bash console из Start -> Programs -> Git
  2. Выполнить ssh-keygen -t rsa -C "your@email.com", чтобы сгенерить ключ


GUI клиент

Теперь ставим мой любимый SmartGit. Очень приятно, что он кроссплатформенный.

Во время установки SmartGit, если не найдет файл .gitconfig, спросит имя и e-mail, которые будут использоваться в информации о комитах.

Переносы строк

При работе с git репозиторием с разных операционных систем, рано или поздно (лучше рано) сталкиваешься с проблемой переносов строк. Сообщество так и не пришло к единому мнению, но GitHub рекомендует следующие настройки:
  1. Создавать репозиторий лучше не с Windows машины
  2. На Linux и Mac установить параметр core.autocrlf в значение input
  3. На Windows установить параметр core.autocrlf в значение true

Это делается либо командой git config --global core.autocrlf true либо редактированием .gitconfig. Туда нужно добавить
[core]
autocrlf = true

При этих настройках пользователи Mac будут работать с LF переносами строк и комитить LF в репозиторий, а пользователи Windows будут работать с привычными CRLF, но комитить LF.

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

Перевод существующего проекта


Данный способ предполагает полную потерю истории SVN. Начало, так сказать, с чистого листа.

Сделайте svn export проекта, чтобы избавиться от .svn папок. Или в корне проекта выполните команду find ./ -name ".svn" | xargs rm -Rf

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

В каталоге с будущим git репозиторием рекомендую сразу создать файл .gitignore со следующим содержимым:
bin
bin-debug
bin-release

Это скажет git не включать в репозиторий скомпилированные бинарники проекта.

Далее запускаем SmartGit, выбираем Open an existing or create a new local Git working tree и указываем папку с проектом. SmartGit создаст в ней новый репозиторий.

Сразу же нужно найти в списке файл .gitignore, выделить его, нажать кнопку Stage и Commit. Первый Commit Message пусть будет что-то вроде «initial commit». Теперь, если зарефрешить текущее состояние каталога, исчезнут все файлы упомянутые в .gitignore. Они вам не нужны. Выделяем все остальные файлы, Stage, Commit, в окне комита отметьте галочку Amend foregoing commit..., тем самым вместо нового комита вы добавите текущие изменение к последнему (возможно, вы увидите множество сообщений CRLF will be replaced by LF in… — это означает, что git следуя настройкам меняет концы строк файлов, которые добавляются в репозиторий, на правильный LF).

Поздравляю, теперь у вас есть свой git репозиторий.

Если вы вдруг создали репозиторий до того, как выставить правильные настройки переносов строк, то следуйте инструкции GitHub и выполните следующий скрипт:
# Remove everything from the index
$ git rm --cached -r .


# Re-add all the deleted files to the index
# You should get lots of messages like: «warning: CRLF will be replaced by LF in <file>.»
$ git diff --cached --name-only -z | xargs -0 git add

# Commit
$ git commit -m «Fix CRLF»

# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
$ git ls-files -z | xargs -0 rm
$ git checkout .

Если вы удаляли проект из Flash Builder, сейчас самое время добавить его заново (через File -> Import -> Flash Builder Project) и убедиться, что все работает. Возможно, придется сделать некоторые изменения, например в путях импорта и конфигах, если вы переносили проекты в одну папку. После сделанных изменений не забудьте их закомитить.

Работа с проектом


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

Раз уж мы используем git, будем на полную пользоваться его основной фишкой — ветками. Итак, все проекты у меня состоят из набора веток с разными функциями и строго определенным алгоритмом работы с ними.
  • master — основная ветка содержит только релизные версии, которые сейчас онлайн. Они помечены тэгами (tag) с датой заливки. От мало информативных номеров версий я отказался. Если вдруг что-то ломается на боевом сервере, мы без проблем переключаемся на master, делаем с него ветку, фиксим баг и мержим обратно (плюс еще в другие ветки, чтобы потом заного тот же баг не фиксить)
  • develop — основная девелоперская ветка. Отражает стабильное состояние разработки, которое когда-то в будущем уйдет в релиз и будет смержено в master.
  • dev-* — ветки для отдельных фич. Многие из них локальные и в главный репозиторий не попадают. В них ведется разработка конкретных новых фич игры. Это могут быть совсем небольшие изменения на один-два комита, а может быть огромный патч, который разрастается на месяц  и более.
  • fix-* — локальные ветки срочных фиксов. Обычно появляются от  master, реже от develop. Сразу мержатся в нужные места.
  • release — временная ветка для релиза, которая вольется в master и будет удалена. В нужный момент бранчится с develop, и в нее вносятся необходимые правки перед заливкой.

Алгоритм работы следующий:
  • Практически для каждого изменения заводится своя девелоперская ветка, которые либо в итоге будут смержены в develop, либо удалены за ненадобностью.
  • Ветки более-менее больших изменений идут в центральный репозиторий, мелкие обычно остаются локально у разработчиков.
  • Слияние больших фичей я стараюсь контролировать, просматривая проделанные изменения. Очень удобно на данном этапе отсекать всякий говнокод.
  • Во время подготовки к релизу, создается ветка release, которая потом мержится в master. В ней делаются временные изменения, которые нигде больше не нужны, например «нам в этом релизе нужно спрятать эту кнопку, потому что функционал еще не готов». На этом этапе лучше больших багов не иметь, потому что тогда придется делать отдельную ветку с фиксами этих багов и постоянно переключаться между ней и release.
  • После заливки, release мержится в master и удаляется. Текущее состояние master помечается тэгом с датой заливки.
  • Разработка продолжается.

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

Проблемы, с которыми я столкнулся


Конечно, не все так идеально, как вы могли подумать. На пути к просвещению мне все же пришлось понаступать на грабли, о которых я напишу ниже. Возможно, эта информации кому-то пригодится.
  1. Сопротивление админов
    Я несколько раз пытался объяснить зачем нам еще одна система контроля версий, ведь вроде бы есть отличная SVN. Админы жаловались, что git сложно интегрировать в существующую систему раздачи прав и разграничения доступа к ресурсам в сети. Это дело так с мертвой точки и не сдвинулось, пришлось мне «центральный репозиторий держать у себя локально».
  2. Обучение коллег
    Коллег пришлось заставить перейти на новую систему контроля версий, понять чем оно отличается от привычного SVN и научиться пользоваться новым софтом. Ничего сложного на самом деле, но нужно быть готовым к последующим постоянным вопросам.
  3. Проблема переносов строк
    О проблеме и ее решении я уже писал выше, но так как это конкретно выносило мой мозг какое-то время, я не мог об этом не написать в разделе «проблемы». Очень важно пофиксить переносы строк в самом начале проекта, когда существует только одна ветка. Потом это обернется в солидную головную боль.
  4. Руки из ж…
    Что касается юниксоподобных систем и командной строки, тут у меня руки растут явно не из того места. Будучи какое-то время центральным репозиторием на Маке, мне постоянно пришлось сталкиваться со следующими проблемами, связанными с тем, что я с самого начала все правильно не настроил: залоченный файлы и владельцы файлов.Каким-то образом файлы git репозитория становились залоченными так, что никак, даже из самого-самого рута разлочиваться не хотели. Гугл подсказал скрипт, который рекурсивно разлочивает файлы в каталоге.После пуша ко мне от коллег разработчиков, некоторые файлы переходили под владение nobody, что приводило к полной неработоспособности репозитория. Приходилось каталогу каждый раз рекурсивно выставлять права, типа, sudo chmod -R 777 /users/valyard/Work/work/Panda/.git/

    В итоге я написал скрипт, который делал эти две вещи на всех проектах, и запускал его время от времени.
  5. Внимательнее смотрите что идет в репозиторий, а что нет
    Разумеется, скомпилированные бинарники и графические ассеты нужно сразу добавить в .gitignore. У нас в проекте есть ant скрипт для сборки барахла и он немного отличается на разных машинах. Возможно, его стоило тоже туда добавить, но я просто сделал два разных скрипта: для винды и для мака.
  6. Надоедливые файлы проекта
    Почему-то Flash Builder время от времени в метаданных проекта считает своим долгом перенести половину строк сверху вниз, чем он не делает ничего полезного, зато раздражает git при отображении изменений. Но, все же, не комитить файлы проекта я считаю плохой идеей.
  7. Проблема генерации SSH ключей на WIndows
  8. Нелюбовь флэшеров к консоли
    Как выяснилось, флэшеры не любят работать в консоли. А GUI клиенты предоставляют лишь малую часть функционала git. Порой приходится лезть в командную строку, чтобы выполнить какую-то операцию посложнее.

Полезные советы


Пара слов в конце.
  1. Убедитесь, что Вы понимаете отличия git от svn.
  2. Постарайтесь донести это до начальства.
  3. Найдите человека, который сможет грамотно настроить главный git репозиторий.
  4. Постарайтесь все же использовать один и тот же IDE в команде, тогда можно комитить файлы проекта.
  5. Разделите проект на несколько репозиториев.
  6. Делайте комиты и мержи чаще, все-таки даже такой классный инструмент как git не может автоматически смержить две ветки с двухмесячной историей комитов. Придется посидеть вручную потыкать кнопочки.
  7. Не повторяйте моих ошибок.
  8. Не слушайте тех, кто ругает git.

Полезные ссылки



Итог


Но все же все минусы были перекрыты огромными плюсами. Были моменты, когда я готов был поцеловать себя в зад за то, что все-таки перевел проект на git, чего и Вам желаю (конечно, не поцеловать меня в зад, а перевести проект на git)!

P.S. Вопросы.


  1. Как и кто у вас контролирует слияние с основной веткой (master) и есть ли механизм разграничения полномочий для выполнения подобных операций?
    Контролирует главный флэшер на проекте. В моих проектах это делаю я. На уровне git я не знаю есть ли какие-то разграничения по доступным операциям.
Tags:gitflashSmartGit
Hubs: Git
+36
5.4k 104
Comments 97
SEO-специалист
December 7, 202064,900 ₽Нетология
iOS-разработчик с нуля
December 7, 202070,740 ₽Нетология
Python для работы с данными
December 7, 202031,500 ₽Нетология
UX-дизайнер
December 7, 202047,940 ₽Нетология
Top of the last 24 hours