*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***
Показаны сообщения с ярлыком perforce. Показать все сообщения
Показаны сообщения с ярлыком perforce. Показать все сообщения

четверг, 28 апреля 2011 г.

p4-git - работа в Perforce через git

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

  • CVS - все понятно, система не для автоматизации разработки, где все меняется каждую минуту, а для "публикации истории изменений"
  • SVN - все более менее ничего, когда в разработке есть выделенный trunk, иначе после нескольких массивных слияний веток в разных направлениях хочется застрелиться
  • RTC (Rational Team Concert) - монструозная система, удобная когда все и везде написано только на Java, и неудобный клиент в командной строке
  • ClearCase - кроме шуток, пользователям надо выдавать травы и водки, чтобы понять, как это система работает

На фоне всего этого Perforce - это реальный рай. Регулярно делаю слияния между ветками команд разработчиков, интеграцией и релизами - удобно. Также смотря с позиции ежедневных нужд разработчика - также все удобно. Только одна вещь нас немного мучала - это невозможность перебрасывать changeset'ы между физическими машинами перед commit'ом. У нас в разработке шесть основных платформ, включая Windows, поэтому каждый commit приходится проверять на всех платформах. Моя утилита p4patch решала проблему более менее, но в последних версиях появилась волшебная команда p4 shelve, которая решает эту проблему на корню.

Но что ни говори, для локальной работы, когда утопаешь в экспериментах, тестовых данных, временных копиях и т.д. - наличие распределенной системы типа git, hg, bazaar или fossil, когда можно плодить ветки по каждому чиху, сливать, удалять и т.д., реально упрощает жизнь.

Как рекоммендуют сами Perforce'овцы, можно в некотором роде срастить оба подхода, например, через git.

p4-git - скрипт, которым локальные файлы, находящиеся под контролем Perforce, дополнительно можно взять под git.

Я все настроил, как сказано. Теперь у меня в git есть ветка master, являющаяся зеркалом из репозитория Perforce, и пяток-десяток локальных веток, из которых я сливаю в master. Изменения, которые я внес через git, автоматически заливаются в Perforce командой "git p4 submit". Комадной же "git p4 rebase" можно синхронизировать ветку master с ее оригиналом в Perforce.

Кстати, я уже потерял счет тем разам, когда в hg или fossil'e я влеплял ошибку в команде комита - либо просто опечатка в сообщении, что еще можно пережить, или при повторении команд из буфера командой строки вместо diff залепишь старый комит и все. Потом приходится либо как-то хитро merge'ить, либо просто откатывать изменения, делая новый комит. А в git можно просто сказать "git commit --amend" для исправления опечатки в только что сделанном комите, или "git reset HEAD^1" для удаления последнего комита вообще. А меняя 1 на 2, 3 и т.д., можно удалить сколько угодно комитов назад.

А самое важное, что даже неверная команда "git reset HEAD^n", которая якобы удаляет n последних комитов - это не конец света. И ее можно откатить через "git reset <commit_id>", где <commit_id> - это идентификатор удаленного комита. При всех тех возможностях по работе с репозиторием, которые дает git, и которые принято считать "опасными", очень мало команд, которые реально имеют необратимые последствия. Пока вы не сделали сборку мусора командой "git repack" объекты физически не удаляются, а только меняются указатели на них, а значит практически всегда можно вернуть назад, когда напортачил.

среда, 6 января 2010 г.

Больше коммитов, хороших и разных

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

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

Когда же используется централизованная система контроля версий (SCM) многие люди не коммитят незаконченный код, ибо в подавляющем числе случаев работа ведется в ветке, которой пользуется еще кто-то. Закоммитишь сломанный код — услышишь слова радости в свой адрес из другого конца комнаты.

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

Что делать если у вас используется централизованная SCM? Просто начните использовать любую из современных распределенных систем параллельно с основной централизованной. Для начала можно вообще не вдаваться в детали хитрой интеграции локальной распределенной SCM и централизованной для автоматизированного переноса коммитов туда-сюда (например, как p4-git для Git и Perforce), а делать все просто: просто коммитить процесс работы в вашу собственную локальную распределенную систему для удобства отслеживания микро изменений, а когда все готово — делать большой коммит на сервер.

Мне приходится работать параллельно с разными SCM, и они преимущественно централизованные (SVN, Perforce, ClearCase), и преимущественно правила коммитов и слияний между ветками очень жесткие и детально прописанные. А про создание собственных веток я уж и не говорю. Но это не мешает мне локально использовать git, в котором в дополнение к официальным веткам сидит десяток моих собственных, коммиты и слияние в которых я делаю десятки раз в день.

Я стараюсь коммитить как можно чаще. Например, добавил новый target в Makefile — коммит, добил новый тест (пусть даже он пока не компилируется толком) — коммит, заставил тест компилироваться — точно коммит, ну а заставил тест работать — стопудово коммит. Решил попробовать новый метод линковки проекта и для этого подкорячить Makefile — создал новую ветку, поигрался, слил результаты с основной веткой и удалил временную. Конец рабочего дня и пора лететь на купание дочки — коммит, даже если исходники представляют собой поле боя, так как завтра тебя с утра могут неожиданно перебросить на Умань чинить срочный баг, и потом уже точно не вспомнить, что там к чему.

Также желательно, чтобы коммиты были логически изолированы. Например, в запале ты исправил сетевую подсистему и добавил кнопку в UI — не стоит объединять все это в один коммит, так как может случиться, что вы заходите эту новую кнопку в параллельной версии, и если это отдельный коммит, то перенести его можно будет простым слиянием или cherry-pick'ом. Наличие staging area (индекса) в git позволяет легко коммитить выборочно (причем даже файл по кускам). Для Mercurial я нашел более менее похожую возможность в TortoiseHG, когда при коммите можно отметить файлы, которые в него включаются.

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

Лирическое отступление. С некоторого времени у меня даже всякие самопальные скрипты в UNIXе (а у кого их нет?) и конфигурационные файлы типа .profile, .Xdefaults или .vimrc живут под контролем git'а. Другой пример: скачал я новый gdb-7.0. Развернул, скомпилил. При работе он начал иногда падать на определенных машинах с ошибкой. Интернет сказал, что это известный баг и есть патч. Так вот: сначала сразу после разворачивания оригинального архива дерево исходников gdb помещается в git (git init && git add * && git commit -m "Original gdb-7.0."), а только затем делается патч и тоже коммитится в git. Для чего? Чтобы понимать, что изменено, когда и почему.

Еще одно лирическое отступление. Ни что так помогает понять, насколько "нужен" тебе некий домашний хлам, как его датирование. Записал DVD с бэкапом — кроме названия диска еще надо надписать дату записи. Собрал документы по сданному проекту в архивую папку — поставил дату. Потом, через N лет, этот стикер с датой однозначно решит судьбу предмета и, возможно, определит его в помойку, освободив место в шкафу. В компьютере все это далается еще проще. Ну а история изменений/версий только приятно автоматизируют процесс.

Культура повсеместного использования контроля версий крайне позитивна. А распределенные системы (типа Git, Mercurial или Bazaar) позволяют приобщиться к прекрасному даже если все вокруг вас не хотят (пока!) принять эту культуру.

Посты по теме:

четверг, 21 мая 2009 г.

Какую распределенную систему контроля версий выбрать: Git, Bazaar или Mercurial?

Последние две недели занимаюсь вялотекущим сравнением трех распределенных систем контроля версий: Git, Bazaar и Mercurial.

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

Исторически Git для меня самая родная система, так как пользуюсь ей дольше всего. Поэтому пост будет во многом Git'оцентричный.

С Bazaar познакомился благодаря отличному блогу "Базарный день".

Mercurial пришлось попробовать, так как это православно (причем весьма заслуженно).

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

О колокольне, с которой я смотрю на предмет. Я ищу систему не для дома (собственные проекты у меня сидят на разных системах, и все нормально), а для поддержки системы на нескольких видах UNIX плюс еще и Windows. Примерное количество файлов в ветке проекта около шести тысяч. Объем ~250 мегов (увы, есть некоторое количество двоичных файлов). Объем репозитория особо не волнует, если речь идет о разумных цифрах.

Git

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

Теперь по делу.

Что мне очень нравится в Git — это наличие staging системы (промежуточное звено между рабочими файлами и репозиторием). Очень удобно, когда можно подготовить для комита не весь файл, а только его часть.

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

Очень подкупает невообразимо мощная команда rebase, которой можно сделать с историей проекта все (в том числе и испортить). То есть Git не возводит в религию неприкосновенность истории. Механизм для ее модификации дается, но вот ответственность за результат перекладывается на пользователя. Никто не запретит тебе простым ключиком "--amend" подправить синтаксическую ошибку в тексте последнего комита (да и любого другого комита) или удалить любой комит из истории, но вот надо тебе или нет — вопрос персонального подхода к работе. Из личного опыта как занимающего выпуском релизов скажу, что порой очень нужно иметь возможность менять историю, увы. В Perforce мне из-за этого приходится делать много ручной работы.

Под занавес — есть приятный бонус в виде качественного публичного хостинга github.com.

Из минусов, трогающих меня — это просто омерзительный порт под Windows. Я пользуюсь версией, построенной на MinGW. Пока непобежденным глюком для меня является тот факт, что по какой-то причине некоторые базовые утилиты UNIX, входящие в состав дистрибутива Git под Windows, при старте пытаются, видимо, определить наличие всех логических дисков (C:, D: и т.д.) в системе. Хорошо, когда нет сетевых дисков, а вот когда они есть, то такой опрос занимает раздражающие 2-3 секунды при каждом запуске (причина была выявлена путем анализа сетевого трафика, так как сначала я думал, что у меня вирус). На домашнем компьютере все отлично — там нет сетевых дисков.

Но несмотря на все препоны, с помощью git-p4 я наладил для некоторых наших разработчиков, работающих часто в офлайне, неплохой механизм интеграции с централизованным Perforce. Человек синхронизируется, будучи онлайн, и обновляет локальный репозиторий Git. Потом спокойно работает в офлайне через Git, а затем опять в онлайне засылает все сделанное из Git в Perforce.

Bazaar

Классная система. Работает с полоборота из коробки, но только там, где есть Питон, поэтому на некоторых наших вынужденных UNIXах меня ждал облом.

Пока я не нашел особых смысловых изъянов, мешающих мне работать.

Очень мне нравится подход, когда каждая ветка как таковая живет в отдельном каталоге, то есть имеет свой набор рабочих файлов (хотя может и не иметь).

Как-то с ходу не нашел бесплатного хостинга для Bazaar.

Mercurial

Снова Питон, поэтому автоматически все шоколадно на системах, где он есть, но грустно, где его нет.

Из хороших бонусов есть факт, что Google сделал поддержку хостинга для этой системы. Как написано в их отчете о том, почему они выбрали именно Mercurial, а не Git, как я понял, говорится, что основные причины в более простой интеграции Mercurial в систему http-сервисов (Git тоже умеет через http, но медленнее), и логическая близость синтаксиса команд Mercurial к Subversion (тут, конечно, Git ой как далеко).
В целом, для себя я решил пока так: если для дома для семьи или там где Windows да Linux, то это без сомнения Bazaar или Mercurial (можно монетку подкинуть), а вот все-таки для применения на множестве разнородных систем и там где надо уметь управлять историей, то пока Git.

среда, 11 марта 2009 г.

"Легкая" интеграция Perforce в Visual Studio

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

Например, в Perforce, как и во многих других системах контроля версий это решается выставлением атрибута read-only по умолчанию на все локальные файлы, находящиеся под контролем версий. Это позволяет исключить “случайное” изменение. Если надо изменить файл, то он помечается как рабочий (в Perforce "p4 edit имя_файла"). После этого с файла снимается флаг read-only, и Perforce добавляет его список "открытых" файлов. Теперь, когда вы хотите узнать, какие файлы у вас сейчас на редактировании, то команда Perforce "p4 opened" моментально выдаст список без глобального сканирования изменений. Также "p4 diff" столь же мгновенно отобразит сами изменения. По началу, такой подход может напрягать, и я часто слышу жалобы типа проще открыть сразу весь проект по маске через p4 edit ..., поработать спокойно, а уже под занавес сделать полное сканирование изменений для определений реально измененных файлов и только их отправить на сервер командой "p4 submit".

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

Perforce предоставляет специальный плагин для Visual Studio, который призван облегчить процесс работы с файлами, находящимися под контролем версий. Вы просто работаете в среде, и когда нужно изменить какой-то файл (например, вы просто начали что-то набивать в окне редактора), то студия сама предложить вам открыть файл для редактирования. Вы скажете "Да", и файл открывается для работы. В жизни же все обычно отключают этот надоедливый запрос, разрешая по умолчанию открывать файлы без запроса. И мы снова приходим к варианту, когда имеется огромное количество открытых файлов, а изменены только несколько. Поэтому я предпочитаю не ставить этот плагин, а открыть файлы вручную.

Конечно, работая в студии, не всегда удобно постоянно лазить в командную строку для "p4 edit ...". Хочется делать это прямо из меню. Способ есть, и никакой шибко умный плагин не нужен.

Идем в меню Tools, затем в "External tool...". Далее создаем кнопкой "Add" элементы "&P4 Edit" (Arguments: "edit $(ItemPath)"), "&P4 Revert" (Arguments: "revert $(ItemPath)"), "&P4 Diff" (Arguments: "diff $(ItemPath)") по аналогии с картинкой.

Теперь для открытия за запись файла из текущего окна редактирования надо выбрать в меню Tools->P4 Edit, для отката изменений — Tools->P4 Revert, а для просмотра изменений — Tools->P4 Diff.

Вывод этих команд сохраняется в окне Output.

По вкусу можно добавить аналогичным образом любую команду из арсенала командного клиента Perforce p4, но именно эти обычно нужны в 99% случаев. Я обычно назначаю горячие клавиши на эти пункты меню. Для остального можно уже слазить в командную строку или в графический клиент Perforce (P4V или P4Win).

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

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

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

Лично предпочитаю "разговаривать" с Perforce через командную строку, ибо в командной строке можно сделать все, и удобно, когда надо выполнить много рутинных однотипных операций. Но есть один случай, когда именно графический клиент становится настоящим спасением. Это случай слияний изменений и разрешения конфликтов. Проблемы начинаются, когда ты хочешь зафиксировать на сервере свои изменения, а там уже кто-то "потрогал" твои файлы. Это называется конфликт, и его надо разрешать. Делать это в обычном текстовом редакторе, особенно когда конфликтуют сотни пересекающихся строк, практически нереально. Очень медленно, и вероятность ошибки огромна. В Perforce есть удивительная графическая программа для сравнения и слияния изменений. Обычно, если конфликтующие строки не пересекаются, Perforce сам автоматически смешает в правильном порядке. Если же есть пересекающиеся конфликты, то тут уже нужен человек для понимания, что выкинуть, а что оставить.

Утилита слияния в Perforce предоставляет для этого очень удобный сервис. На уровне строк можно выбирать нужные для включения в слияние. В окне одновременно отображаются три исходника: твой текущий, твой базовый, на основе которого ты делал изменения, и текущий из репозитория, с которым и возникает конфликт. А под этим всем внизу отображается результат слияния. Все подсвечивается разными цветами, максимально облегчая выбор правильного варинта. Я даже не знаю, как это может быть еще лучше сделано. Даже изобилующие конфликтами слияния между целыми ветками (например, из рабочей ветки в основную, где уже успели исправить порядочно ошибок) у нас делаются за несколько часов.

Приятно, что графический клиент Perforce P4V существует не только под Windows (в отличие от старого P4Win). Он есть под Linux, Solaris, FreeBSD и Mac. Если надо работать сразу под несколькими системам, можно запустить у себя на машине X-сервер, и видеть клиентов со всех платформ одновременно. P4V использует Qt, посему выглядит почти одинаково на всех системах.

Кстати, выскажу свое субъективное мнение на тему контроля версий. Если бы мне продавали исходники чего-то сложного, то для меня было бы очень важным критерием среди прочих наличие не только вылизанной для продажи "последней супер версии", но и всей истории разработки, в формате какой-нибудь системы контроля версий и баг-трекинга.