`

СПЕЦИАЛЬНЫЕ
ПАРТНЕРЫ
ПРОЕКТА

Архив номеров

Как изменилось финансирование ИТ-направления в вашей организации?

Best CIO

Определение наиболее профессиональных ИТ-управленцев, лидеров и экспертов в своих отраслях

Человек года

Кто внес наибольший вклад в развитие украинского ИТ-рынка.

Продукт года

Награды «Продукт года» еженедельника «Компьютерное обозрение» за наиболее выдающиеся ИТ-товары

 

Оставлено ради обеспечения совместимости с… человеком

Статья опубликована в №3-4 (621) от 29 января

+22
голоса

Окончание

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

Итак, предыдущая часть статьи была завершена бравурным утверждением того неоспоримого факта, что не собрать Fossil из исходных текстов сложно. Но от набора в консоли команды make (и минимальной правки файла с инструкциями ей) до понимания организации собираемой программы – настоящая бездна. Даже несмотря на то, что исходные тексты Fossil более чем обозримые, при разработке программы использованы приемы, которые могут многим показаться несколько необычными.

Итак, если вы решили «поковыряться» в исходных текстах Fossil до сборки исполняемого файла (а многие, особенно имеющие за плечами опыт работы в UNIX-совместимых системах, именно так и поступят), вас ждет первая неожиданность. Программа написана весьма прозрачно, ввиду сравнительной «молодости» документирована традиционным в мире Open Source способом «код – лучшая документация», а вот где в этой «лучшей документации» можно отыскать описания команд, осуществляемых одним исполняемым файлом Fossil, – не совсем понятно. Точнее, в явном виде в исходных текстах этих описаний в привычном для программиста представлении (например, как массив указателей на текстовые строки) нет. Это связано с тем, что при разработке системы использован механизм автоматического формирования заголовочных файлов непосредственно из кода (т. е. из *.c – файлов). Реализация такого механизма – утилита makeheaders.c – распространяется также открыто, располагается в основном дереве проекта и сопровождается файлом документации makeheaders.html. Если вы решитесь посодействовать проекту, обязательно изучите эту утилиту и нюансы оформления кода, которые надо учитывать для эффективного ее применения.

Мы же пока ограничимся поиском перечня и кратких описаний всех команд программы. Для этого воспользуйтесь любым доступным вам механизмом поиска в множестве файлов по шаблону, заданному регулярными выражениями. А именно, – ищите в *.c совпадения с шаблоном **x20COMMAND (ничего загадочного в шаблоне нет – это просто строка многострочного C-комментария). Результаты покажут вам еще одну особенность внутренней организации Fossil – код большинства команд сгруппирован по признаку логической принадлежности в модули (.c-файлы) с вполне адекватными названиями. Третья особенность Fossil – помещение множества глобальных переменных, доступных из всех модулей, в «структуру-облатку» c именем g. Тип этой структуры – Global – описан в модуле main.c, начало описания в строке 47 (сказанное справедливо для версии системы f7fe15cd0cb6cc28a32cc40c13bb12b9faccd673, в первой части статьи мы упоминали о механизме нумерации версий). К слову, глобальных переменных в системе немало. Это, конечно, не очень хорошо (почему, знает любой программист), но оправдано компактностью программы.

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

Инсталляция собранной программы, как мы уже говорили, заключается в копировании единственного исполняемого файла в любой каталог файловой системы, путь к которому указан в переменной окружения PATH (чтобы беспрепятственно запускать файл средствами операционной системы). Единственный нюанс, который следует учитывать, касается «вольностей», к которым привычны пользователи ОС семейства Windows, а именно, путевые имена, содержащие пробелы. Традиционно программы, вышедшие из UNIX-мира, такие имена не очень любят, а пользователи из Windows-мира столь же традиционно не очень любят лишние сложности при описании таких имен. Поэтому если ваш остальной инструментальный набор позволяет разместить и исполняемый файл Fossil, и рабочие каталоги (о них – позднее) так, чтобы в путевом имени не было пробелов, именно так и поступите, это избавит вас от всяких возможных, но трудно предсказуемых нюансов.

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

Для более любознательных – Fossil хранит в специальной базе данных (имя файла БД – .fossil) массу сведений о проекте, шаблон записи этой базы данных детально описан в файле schema.c, а «добраться» до самой базы можно с помощью команды setting (т. е. набрав в консоли fossil setting ...). В перечне возможных аргументов setting есть и editor. Имея установленную Fossil, вы можете ознакомиться с любой командой с помощью встроенного механизма помощи, например набрав с консоли fossil help setting. Перечень всех поддерживаемых системой команд вы можете получить с помощью команды fossil commands, подмножество же команд, интересующих только разработчиков системы (необходимых для отладки и тестирования), выводится в результате выполнения команды test-commands.

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

Новый проект – это в первую очередь новый репозиторий. Создать его можно с помощью команды fossil new имя_файла_репозитория (код реализации – в модуле db.c, начало со строки 804). Вы также можете клонировать уже существующий проект, создав локальную копию его репозитория командой clone (fossil clone URL_проекта имя_локального_файла_репозитория), реализация которой находится в модуле clone.c (об адекватности имен в проекте Fossil уже упоминалось).

Теперь, когда ваш репозиторий создан (вы можете увидеть его – это будет файл с именем имя_файла_репозитория.fsl), можно начинать с ним работу. Для этого вам понадобится развернуть локальный http-сервер. Не спешите искать подходящую его реализацию, несмотря на то, что Fossil может работать со сторонними серверами, вам вполне может хватить встроенного в программу. Поэтому, не откладывая в долгий ящик, запускайте его командой fossil server имя_файла_репозитория. Да, этого более чем достаточно, чтобы получить локальный сервер, обеспечивающий веб-интерфейс к вашему пока пустому репозиторию. Если же вас по каким-то причинам не устраивает TCP порт 8080, установленный разработчиком по умолчанию, вы можете указать желаемый порт при запуске в следующих эквивалентных формах: fossil server –P порт имя_файла_репозитория, или fossil server –port порт имя_файла_репозитория.

Теперь «натравливайте» ваш браузер на адрес http://localhost:8080 и приступайте к первому этапу настройки – к конфигурированию посредством веб-интерфейса. Главное, что вы должны сделать при конфигурировании, – очевидно, создать хотя бы одного пользователя вашей Fossil-системы. Единственное существенное замечание здесь может быть только одно – по умолчанию Fossil не требует от пользователя локальной машины обязательной процедуры авторизации при обращении посредством веб-интерфейса (т. е. логина, а иначе как бы вы могли первый раз получить доступ к режиму конфигурации). Вы можете и должны изменить эту политику, если предполагается коллективное использование вашей Fossil-системы, а разрабатываемый вами проект – не учебный и имеет хоть какую-нибудь ценность. Если же вы пока только «играетесь» и только на локальной машине – поступайте, в принципе, как хотите, но помните, что расслабленность и безопасность – вещи несовместимые. По окончании конфигурирования просто «прибейте» исполняющийся процесс fossil любыми доступными средствами. Теперь вы располагаете созданным и отконфигурированным репозиторием. Но никакого наполнения он не имеет (естественно, если вы создавали новый проект, а не клонировали уже имеющийся). С этого момента начинается ваша настоящая работа с системой конфигурирования и контроля версий. И, естественно, начинается расширение базового словаря.

Первая ваша задача – создать локальное исходное дерево (см. первую часть статьи) и указать Fossil, что именно в нем будет находиться ваш проект. Для этого создайте любой каталог, переместитесь в него в вашей командной строке и выполните команду fossil open имя_файла_репозитория. Вам с ним придется встречаться в SCM постоянно, вне зависимости от системы, которую вы используете. Следующее действие – загрузка исходного дерева самыми «свежими» файлами из репозитория. Это можно осуществить выполнением следующей команды – fossil update (реализация – в модуле udate.c). На самом деле команда update в Fossil весьма развитая, но при запуске без аргументов она приводит исходное дерево в соответствие с файлами самых последних версий (именно версий, потому что в пределах одной версии возможно не порождающее новой версии «обновление» файла, для чего в системе используется специальный флаг). Если вы только что создали новенький репозиторий, внешне ничего не изменится. Но не обманывайтесь. На самом деле вы только что выполнили одну из главных процедур в SCM – загрузку файлов из репозитория в исходное дерево. Для этой процедуры предусмотрено специальное название в терминах SCM – «check out».

Итак, после выполнения двух фундаментальных команд вы можете ознакомиться с состоянием вашего проекта с помощью всего арсенала информационных команд Fossil – timeline, leaves, branches, status, changes. Но пока, естественно, узнавать вам не о чем.

Следующее действие – добавление в исходное дерево реальных файлов проекта. Создайте один файл, назовите его как вам нравится, сделайте в нем какую-нибудь запись и добавьте его в исходное дерево командой fossil add имя_файла (эта команда допускает и множественные добавления). Теперь у вас появился новый файл в исходном дереве, и это изменение надо зафиксировать в репозитории. Данная «фиксация», по сути, является загрузкой файла в репозиторий и в общем именуется «check in», а в Fossil еще и «commit». Фиксация изменений (check in, загрузка файла в репозиторий) выполняется командой fossil commit. Эта команда не только выполняет невидимую пользователю работу с репозиторием, но и оповещает об изменениях с помощью так называемых check in комментариев или сообщений.

В момент check in происходит то самое главное, что отличает процесс разработки в системе управления конфигурациями и контролем версий от традиционного подхода «файловая свалка и ручное наведение порядка». Помещенный в репозиторий файл автоматически получает уникальный номер версии. Раньше мы уже упоминали о нем – это 40-символьный идентификатор, рассчитываемый на основании содержимого файла. Вот это-то и является главным – в подобных системах файл определенной версии в репозитории является неизменяемым (immutable), и что бы мы ни делали с файлами в исходном дереве, мы всегда сможем гарантированно восстановить любую версию из репозитория. Как только мы изменяем файл, изменяется и рассчитанная по алгоритму SHA1 его контрольная сумма – идентификатор, поэтому в репозитории «убить» предыдущую версию случайной перезаписью невозможно.

Естественно, если пытаться хранить каждую версию целиком, особенно для объемных файлов, большого их количества и на протяжении долгого проекта, размеры репозитория могут стать просто астрономическими, и эффективность работы с ним снизится до нуля. Поэтому во всех SCM-системах, и fossil не является исключением, применяются механизмы хранения изменений в форме так называемых «дельт» (deltas) – сведениях о различиях между текущей версией файла в репозитории и ее обновлением, помещаемом в репозиторий механизмом check in. В Fossil механизм «дельт» также интегрирован в систему, не требует сторонних программ и достаточно эффективен, при этом может работать как с символьными файлами, так и с бинарными (для сугубо символьных файлов дельты всегда являются символьными файлами).

Попробуйте изменить ваш единственный файл проекта в исходном дереве и снова выполнить check in командой fossil commit.

Теперь давайте разберемся с ветвлениями (branches) и слияниями (merges). Эти два термина также относятся к основным элементам SCM-лексикона. Ветвления – это не версии, а скорее параллельно отрабатываемые варианты. Разработчику могут приходить в голову разные идеи, он может пытаться создать один модуль с помощью разных алгоритмов (или это могут делать несколько разработчиков) в надежде «селектировать» лучшее, варианты могут добавлять или, напротив, сокращать функциональность. В мире «файловых свалок» роль ветвлений играют отдельные каталоги, в которые в какой-то момент «сбрасывается» исходный текст, например модуля, и в каждом каталоге «обыгрываются» разные варианты его исполнения. Что важно понимать о ветвлении, кроме указанной аналогии (вполне, к слову, удачной)? Исключительно важно понимать и не забывать, что ветвление (и это подчеркивается его названием) – отдельная ветвь проектного процесса, в которой, соответственно, история проекта (информация об отличиях между версиями, «дельты») хранится отдельно. Потому что без этого трудно будет понять и определение слияния.

Ему можно дать много толкований, в том числе и очень умных, но мы ограничимся самым простым и, тем не менее, более чем достаточно точным. Итак, мы знаем, что в ветвлении хранятся своя альтернативная информация о версиях и свои «дельты». Слияние (merge) же является процессом применения «дельт» из одной ветви проектного процесса к файлам другой ветви. С первого раза это может показаться непонятным, но на самом деле в такой процедуре есть смысл, особенно при коллективной работе. Естественно, суть слияния такова, что оно может привести к совершенно неработоспособным результатам, поэтому после ветвления – слияния (само собой разумеется, что обе процедуры оперируют исключительно данными в репозитории) необходимо «освежить» исходное дерево операцией check out (fossil update), проверить результирующий код проекта на соответствие различным критериям (например, программа должна транслироваться и собираться без ошибок), и только после этого «зафиксировать» результат процедурой check in.

По сути, это почти что все. Точнее, даже этого уровня достаточно для того, чтобы ощутить преимущества SCM-подхода (пусть только в части контроля версий) даже при индивидуальной профессиональной работе.

Оставшиеся же детали касаются коллективной работы. Для помещения плодов ваших трудов в репозиторий другого участника проекта используется команда fossil push. Аналогично в ваш репозиторий можно включить изменения, зафиксированные в репозитории вашего коллеги, командой fossil pull. Только не надо забывать, что сейчас речь идет именно о работе с репозиториями, но вы уже знаете о процедуре check out, позволяющей загрузить измененные файлы в исходное дерево командой fossil update.

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

+22
голоса

Напечатать Отправить другу

Читайте также

 
 
IDC
Реклама

  •  Home  •  Рынок  •  ИТ-директор  •  CloudComputing  •  Hard  •  Soft  •  Сети  •  Безопасность  •  Наука  •  IoT