Pull to refresh

Системы контроля версий: Fossil, часть I

Version control systems *
Tutorial
Приветствую вас, коллеги!

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

За годы участия в open source разработках мне довелось пользоваться CVS, Subversion и Git, но для личных и связанных с работой проектов системы контроля версий не использовал, пока по случайной ссылке не познакомился с Fossil. Сразу зацепило то, что надо всего лишь скачать и скопировать в подходящее место один — единственный исполняемый файл. Если это так просто, почему бы не попробовать? Понравилось также, что весь репозиторий — это тоже один файл (SQLite база данных), который можно просто скопировать, чтобы забрать домой или установить на другой компьютер на работе. Мне вообще по душе минималистский подход — может, именно поэтому рука не подымалась ставить для коллектива из 3-4 человек или для личного использования что-то типа Subversion.

Как оказалось, Fossil — вполне «взрослая» система, не уступающая по основным функциональным возможностям своим более известным конкурентам. В качестве солидного бонуса мы имеем здесь web-интерфейс, систему отслеживания ошибок (Bug Tracking) и Wiki, причем уведомления об ошибках и wiki-страницы находятся в том же репозитории, где и файлы проекта и тоже находятся под управлением системы контроля версий, т.е. их изменения также отслеживаются. В процессе эксплуатации и по мере изучения документации выявились еще мелкие, но приятные «вкусности», которые добавили убежденности в правильности сделанного выбора. Сразу хочу подчеркнуть: правильности для меня. У всех разные требования, разные привычки, кому-то больше подойдет что-то другое. Для меня Fossil — вполне подходящее, если не сказать больше, решение.

Установка Fossil
Итак, заходим на http://www.fossil-scm.org/download.html и скачиваем пакет, соответствующий нашей операционной системе. Распаковываем находящийся там исполняемый файл куда-нибудь, откуда потом его будет удобнее запустить, желательно — в каталог, доступный по SET PATH. Все, система готова к работе.

Создание и настройка репозитория
Дальше, для определенности, мы будем исходить из предположения, что у нас стоит Windows. Также, для определенности, будем считать, что все наши репозитории будут храниться в отдельном каталоге c:\fossil, хотя, конечно, можно и не выделять для них какого-то отдельного места, а размещать непосредственно рядом с файлами, которые мы отдаем под управление Fossil. Далее, предположим, что у нас есть проект Castle, исходники которого, находящиеся в c:\projects\castle\source\, мы хотим поставить под контроль Fossil — мы будем называть их рабочими файлами, а каталог source — рабочим каталогом. И создаем, наконец, для этих исходников пустой репозиторий castle.fossil:

fossil new c:\fossil\castle.fossil

Fossil создаст файл castle.fossil и сообщит нам имя администратора ( обычно это имя пользователя, под которым вы вошли в ОС ) и пароль. Fossil вообще довольно «разговорчив» и его сообщения надо читать, там может содержаться важная информация. Как вы уже поняли, все это происходит в консоли, так что для использования Fossil желательно иметь навыки работы с командной строкой, а так же быть знакомым с английским языком — может, я плохо искал, но никаких упоминаний об интернационализации не нашел.
Следующий шаг — переходим в каталог c:\projects\castle и открываем созданный репозиторий:

c:
cd \projects\castle
fossil open c:\fossil\castle.fossil

Большинство операций Fossil производятся над открытым репозиторием, поэтому это следует сделать сразу после создания. А вот закрывать его (fossil close) вряд ли имеет смысл — разве что после завершения проекта. Команда открытия fossil open создает в текущем каталоге служебный файл базы данных, его имя может зависеть от версии Fossil и от ОС — под Windows это _FOSSIL_. В этом файле хранится информация об открытом репозитории и отслеживаются изменения в файлах. Обратите внимание, что перед тем, как открыть репозиторий, я перешел в каталог, родительский по отношению к рабочему. Это важно: репозиторий должен быть открыт или в рабочем каталоге, или в одном из родительских ( на любом уровне дерева ), иначе Fossil откажется добавлять файлы из рабочего каталога в репозиторий.
Вообще-то fossil open не только создает служебный файл, но и проверяет соответствие между файлами в рабочем каталоге и в репозитории, и если какой-либо файл из репозитория отсутствует в рабочем каталоге, или отличается от него, то перезаписывает файл в рабочий каталог из репозитория ( после предупреждения all/yes/no ). Но поскольку наш репозиторий пока пуст, ничего такого не происходит.

Перед тем, как добавить файлы в репозиторий, я бы посоветовал кое-что предварительно настроить. Это можно сделать двумя способами.
1) Из консоли при помощи команды fossil settings:

fossil settings crnl-glob '*'
fossil settings encoding-glob '*'

Установка crnl-glob в '*' (любое) отключает проверку символов конца строки, encoding-glob — проверку кодировки ваших файлов. Если это не сделать, а в ваших файлах используется стандартная для Windows последовательность CRNL или кодировка, отличная от UTF-8, то Fossil выдаст предупреждение и будет требовать подтверждения при операции commit. Кроме того, желательно указать список масок файлов, которые могут присутствовать в вашем рабочем каталоге, но не должны быть включены в репозиторий — объектные модули, исполняемые файлы и пр., например:

fossil settings ignore-glob '*.o,*.obj,*.exe,*.bak,*.log'

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

2) Второй способ установки параметров — с помощью графического интерфейса:

fossil ui

В результате исполнения этой команды будет запущен встроенный в Fossil web-сервер, в данном случае локальный, ( порт по умолчанию — 8080, можно указать другой опцией --port ) и броузер — на URL 127.0.0.1:8080. Для установки параметров откроем пункт меню admin, потом settings и меняем там crnl-glob, encoding-glob и ignore-glob. Заодно можно зайти в admin / configuration — установить название проекта и в admin / users — поменять свой пароль.

Ну и, наконец, добавляем файлы командой add и отправляем в репозиторий командой commit:

fossil add source
fossil commit -m "Initial commit"

Add может добавлять как отдельные файлы, так и каталоги, можно использовать и маску файлов. Команда
fossil add .
добавляет все файлы из текущего каталога и подкаталоги.

Теперь, когда репозиторий открыт и файлы в него добавлены, т.е., поставлены под управление Fossil, можно, собственно, продолжить работу над проектом. Пишем программы, статьи, книги, при каждом важном изменении отправляем его в репозиторий — делаем commit, сопровождая его осмысленным комментарием:

fossil commit -m "Another brick in the wall"

Вот еще несколько команд для удаления/перемещения/добавления файлов:

fossil rm source\wall\brick.c
Удаляем brick.c из репозитория. При этом все предыдущие версии этого файла в репозитории остаются, он просто помечается как удаленный и его дальнейшие изменения в репозитории не фиксируются. Из рабочего каталога этот файл не удаляется — если необходимо, мы должны это сделать сами.

fossil mv source\bridge\item* source\wall\
Перемещаем файлы с маской item* из одного каталога в другой. Учтите, что Fossil сам не перемещает файлы в рабочем каталоге, нам надо сделать это руками.

fossil addremove
Добавляем в репозиторий файлы из рабочего каталога, отсутствующие в репозитории ( т.е., список которых выдает команда fossil extras ) и удаляем из репозитория файлы, предварительно удаленные из рабочего каталога.

И несколько команд, предоставляющих информацию о репозитории и отдельных файлах:

fossil ls source\wall
Выводим список файлов из каталога source\wall, находящихся в репозитории, параметр -v добавляет колонку с состоянием файла (EDITED, UNCHANGED), параметр --age — время последнего commit для каждого файла.

fossil status
Смотрим текущее состояние репозитория.

fossil changes
Выводим список файлов, измененных со времени последнего commit.

fossil extras
Выводим список «лишних» файлов — тех, что присутствуют в рабочем каталоге, но не включены в репозиторий.

Команды для работы с версиями файлов — просмотр изменений, возврат

fossil timeline
fossil timeline after 2014-09-01
fossil timeline before 2014-07-15
Выводим историю изменений репозитория, параметр -v добавляет в вывод список файлов, затронутых каждым изменением. С помощью -t можно указать, какого рода изменения следует выводить: -t ci — в файлах, -t e — в событиях, -t t — в tickets, -t w — в wiki.

fossil finfo source\wall\brick.c
По умолчанию — выводим историю изменений файла brick.c. Если задан параметр -s — то краткую информацию о файле, если -p — выводится содержимое файла, а если вдобавок к -p задан еще и идентификатор версии ( -r VERSION ), то выводится заданная версия файла.

Идентификатор версии файла — важное понятие, о котором следует рассказать подробнее, он используется во многих командах, где требуется что-то сделать с конкретной ревизией файла или всего репозитория. Существуют следующие способы идентификации версии:
  • SHA-1 хэш
  • имя метки (tag)
  • timestamp — дата и время создания
  • выделенные имена: tip, current, next, previous или prev

Каждый элемент в репозитории Fossil — и версии файлов, и tickets, и wiki-страницы и пр. — имеют уникальный идентификатор, 40-значный хэш, вычисленный по SHA-1. Поскольку вводить все 40 знаков в команде не очень удобно, можно ограничиться несколькими ( не менее 4 ) первыми его знаками. Итак, первый способ идентификации версии файла — начальный фрагмент хэша. Другой способ — дата и время создания файла записанное в одном из форматов: YYYY-MM-DD, YYYY-MM-DD HH:MM, YYYY-MM-DD HH:MM:SS. Подробнее смотрите здесь.

fossil diff source\wall\brick.c
fossil diff --from VERSION1 --to VERSION2 source\wall\brick.c
fossil diff --from previous --to current source\wall\brick.c
Выводим в консоль разницу (diff) между разными версиями указанного файла. Здесь VERSION1 и VERSION2 — идентификаторы версий, в соответствии с описанием, приведенным чуть выше — к команде fossil finfo. Если они не указаны, то выводится разница между последней версией из репозитория и файлом в рабочем каталоге. Если установлен Tcl/Tk ( он обычно стоит в Linux-системах, но есть порт и для Windows ), то можно воспользоваться опцией -tk — в этом случае для показа отличий будут использованы встроеннные графические средства, основанные на Tcl/Tk. Если у вас есть GUI программа для графического представления разницы между текстовыми файлами ( я в Windows использую examdiff.exe ), то можно предварительно установить ее в качестве значения параметра Fossil diff-command с помощью web-интерфейса или команды fossil settings diff-command — тогда эта программа будет вызываться при выполнении fossil diff.

fossil gdiff
То же, что fossil diff, только для вывода отличий используется программа, прописанная как значение параметра Fossil gdiff-command.

fossil tag add TAGNAME VERSION
fossil tag cancel TAGNAME VERSION
Добавляем (add) или убираем (cancel) метку (tag) указанной версии репозитория. Эту метку можно рассматривать как алиас идентификатора версии и использовать в соответствующих командах вместо идентификатора, желательно с префиксом tag:. Обычно метки ставят на наиболее значимые, этапные версии проекта.

fossil revert
fossil revert source\wall\brick.c
fossil revert -r VERSION source\wall\brick.c
Возвращаем в рабочий каталог заданную версию файла ( или все файлы, если имя файла не указано ). Если версия (-r VERSION) не указана, то берется последняя — та, что попала в репозиторий во время последнего commit. Идентификатор версии указывается в соответствии с правилами, описанными выше ( к команде fossil finfo ).

fossil undo
Отменяем изменения в рабочем каталоге, сделанные командой revert, merge или update ( две последние мы будем рассматривать позже, во второй части ).

Ну и, конечно, help — как же без нее:
fossil help
fossil help add
Help без аргументов выводит список команд, а с названием команды в качестве аргумента ( например, add, как в примере ) — описание этой команды.

Не могу удержаться, чтобы не рассказать еще об одной команде — fossil all. Она производит указанное действие со всеми открытыми репозиториями:
fossil all list
fossil all changes
fossil all extras
fossil all pull
fossil all push
fossil all sync
list — выводит список репозиториев, changes — список измененных файлов во всех репозиториях и т.д.

Web-интерфейс, tickets, wiki
Я уже упоминал о web-интерфейсе Fossil, запускаемом командой fossil ui, когда рассказывал о настройке репозитория. Выглядит это примерно так:


Кроме просмотра и изменения настроек (Admin) здесь можно посмотреть историю проекта (Timeline), список файлов (Files) и каждый файл в отдельности, структуру веток проекта (Branches), метки (Tags), поработать с Bug Tracking системой (Tickets) и с Wiki — документацией.

Просматривая историю (Timeline), вы можете выбрать любую версию, щелкнув по ее идентификатору ( хэш-код в квадратных скобках ), а там — посмотреть спиок файлов на тот момент, список измененных файлов, отличия от предыдущей версии для каждого файла ( щелкнув по [diff] ), можете скачать zip- или tar- архив этой версии, отредактировать ее представление в истории, в т.ч. подкрасить, и т.д.

Хотел бы вкратце остановиться еще на использовании Tickets и Wiki. Tickets — в данном случае это слово, наверное, будет правильно перевести как «карточки» — способ реализации системы отслеживания ошибок, Bug Tracking, хотя эти карточки, вообще говоря, можно использовать не только для сообщений об ошибках, но и для планирования работы над проектом. Итак, выбираем Tickets, далее — New ticket и заполняем карточку — краткое содержание, тип, номер версии, к которой относится эта запись, степень критичности, email и подробное описание, в котором можно использовать wiki-разметку, а значит, ссылаться на любые объекты в репозитории по их идентификатору — другие карточки, wiki-страницы, версии файлов. Кстати, эта возможность использования идентификаторов как ссылок представляется мне очень ценной, поскольку она повышает связность информации в репозитории, способствует максимальной интеграции всех частей проекта. Будучи введенным, Ticket появляется и в списке All tickets, и в Timeline. Его теперь можно открыть, добавить дополнительные замечания, наложить резолюцию ( fixed, rejected, Unable_To_Reproduce, Works_As_Designed, и др. ). Если ticket закрыт, то при commit соответствующего исправления желательно указать в квадратных скобках идентификатор этой карточки, тогда в истории версий в соответствующей строчке будет ссылка на ticket.

Перед тем, как начать пользоваться Wiki, желательно указать название проекта, если это еще не сделано: Admin / Configuration — заполняем поле Project Name и жмем кнопку Apply Changes. Выбираем Wiki, жмем на Castle project home page ( мы назвали проект Castle ) и редактируем эту страницу. Правила используемой wiki-разметки смотрим в Formatting Rules. Пользуемся Preview Your Changes, для сохранения жмем Apply These Changes. Если все нормально, то созданный текст должен появиться на главной странице (Home) под строчкой меню. Напомню, что изменения в wiki-страницах фиксируются системой контроля версий и появляются в Timeline.
Помимо обычных именованных Fossil позволяет создавать wiki-страницы, привязанные ко времени, они называтся events (события) и появляются в Timeline. Создать такое событие можно, выбрав Wiki и, далее, Create a new event. Вводим время, к которому привязываем событие, Timeline Comment — строчку для Timeline, выбираем цвет и редактируем Page Content — т.е., собственно, содержимое страницы. В документации Fossil рекомендуется использовать events как
  • Вехи проекта (Milestones) — например, основные релизы
  • Записи в блоге разработчиков, описывающие текущее состояние проекта, дорожные карты дальнейшего развития
  • Контрольные точки проекта
  • Новости, имеющие отношение к проекту
  • Объявления.


Заключение
Итак, в первой части обзора было рассмотрено использование Fossil в однопользовательском режиме на одном рабочем месте. Мы научились создавать репозиторий,
fossil new c:\fossil\castle.fossil
открывать, настраивать и пополнять его,
c:
cd \projects\castle
fossil open c:\fossil\castle.fossil

fossil settings crnl-glob '*'
fossil settings encoding-glob '*'
fossil settings ignore-glob '*.o,*.obj,*.exe,*.bak,*.log'

fossil add source
fossil commit -m "Initial commit"
использовать консольные команды и web-интерфейс Fossil в работе над проектом.

В следующей части будем переносить репозиторий на другое рабочее место, чтобы, например, использовать его на работе и дома, и изучим работу в многопользовательском режиме.
Tags:
Hubs:
Total votes 50: ↑45 and ↓5 +40
Views 36K
Comments Comments 77