<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2343702891633188276</id><updated>2011-12-23T09:47:14.247Z</updated><category term='справка'/><category term='для опытных'/><category term='для начинающих'/><category term='qbzr'/><category term='блоги'/><category term='внутренности'/><category term='команды'/><category term='bzr-svn'/><category term='плагины'/><category term='общее'/><category term='концепции'/><category term='настройки'/><category term='протоколы'/><category term='особенности'/><category term='анонсы'/><category term='рецепты'/><category term='советы'/><category term='оглавление'/><category term='исправление ошибок'/><title type='text'>Базарный день</title><subtitle type='html'>Эффективная работа с распределенной системой контроля версий Bazaar VCS (bzr): советы, рецепты, трюки</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>41</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-1231516678588243330</id><published>2011-08-14T19:40:00.000+01:00</published><updated>2011-08-14T19:40:50.847+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='для опытных'/><category scheme='http://www.blogger.com/atom/ns#' term='внутренности'/><title type='text'>Inside .bzr: что внутри служебного каталога .bzr: Часть 2: shared repository</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
В &lt;a href="http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-1.html"&gt;первой части&lt;/a&gt; мы рассмотрели как внутри выглядит ветка и отметили, что у самостоятельных веток (standalone branch) репозиторий свой. Посмотрим, что изменится при работе с shared repository.&lt;br /&gt;
&lt;a href="http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-2-shared-repository.html"&gt;(Далее)&lt;/a&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Копия ветки без использования shared repository&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Но для начала давайте проанализируем, что происходит при создании копии самостоятельной ветки.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside&amp;gt;bzr branch &amp;nbsp;branch copy&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Branched 1 revision(s).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Заходим в копию нашей первой ветки и смотрим вывод &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr info -v&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\copy&amp;gt;bzr info -v&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Standalone tree (format: 2a)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; branch root: .&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Related branches:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; parent branch: C:/work/bzr-day/Inside/branch&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Format:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;control: Meta directory format 1&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; working tree: Working tree format 6&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; branch: Branch format 7&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; repository: Repository format 2a - rich roots, group compression and chk inventories&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Интересными для нас являются следующие секции: Related branches и Format.&lt;br /&gt;
&lt;br /&gt;
Секция Related branches показывает нам путь к родительской ветке (т.е. к нашей первой ветке). Как уже отмечалось ранее в 1й части, эти данные хранятся в конфигурационном файле .bzr/branch/branch.conf в чем легко можно убедиться:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;parent_location = ../branch/&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(Путь сохранен в относительном виде, относительно корневого каталога ветки-копии).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Секция Format показывает, что у текущей ветки есть свой репозиторий. В этом также легко убедиться, заглянув в /bzr/repository. Имя пакетированного файла в клонированном репозитории скорее всего будет отличаться от первого репозитория, поскольку bzr осуществил не просто копирование репозитория, а еще и выполнил перепаковку данных.&lt;/div&gt;
&lt;blockquote&gt;
Кстати говоря, если мы просто скопируем каталог с оригинальной веткой как новый каталог, то получим вполне рабочую новую ветку, но очевидно, что при этом значение parent_location в branch.conf останется старым.&lt;/blockquote&gt;
&lt;div&gt;
Для только что созданных веток, с малой историей, время клонирования репозитория будет сравнительно невелико, да и занимаемый размер весьма мал. Однако с течением времени репозиторий будет расти, и подобное дублирование репозиториев окажется весьма накладным.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Поэтому для оптимизации времени создания новой ветки и для уменьшения требуемого дискового пространства для копий веток, рекомендуется использовать разделяемый/общий репозиторий (shared repository). Как следует из названия он служит общим хранилищем для нескольких веток (располагающихся внутри).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Анатомия shared repository&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Создадим новый общий репозиторий и посмотрим, что находится внутри его служебного каталога.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside&amp;gt;bzr init-repo shared-repo&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Shared repository with trees (format: 2a)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; shared repository: shared-repo&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Мы создали общий репозиторий, в котором по умолчанию для веток будут создаваться рабочее дерево (Shared repository with trees). Для работы с ветками на локальном компьютере это ожидаемая конфигурация.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Заглянем внутрь .bzr:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branch-lock/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;repository/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branch-format&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;readme&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Как мы видим в отличие от ветки, в общем репозитории присутствует только компонент .bzr/repository, другие служебные файлы и каталоги на своих местах. Что нам покажет bzr info -v:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\shared-repo\.bzr&amp;gt;bzr info -v&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Shared repository with trees (format: 2a)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; shared repository: C:/work/bzr-day/Inside/shared-repo&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Format:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;control: Meta directory format 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; repository: Repository format 2a - rich roots, group compression and chk inventories&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Create working tree for new branches inside the repository.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Repository:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 revisions&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Хотя этот общий репозиторий пока пустой (0 revisions), однако внутри каталога .bzr/repository есть на что посмотреть:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;indices/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;lock/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;obsolete_packs/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;packs/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;upload/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;format&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pack-names&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shared-storage&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Очень похоже на содержимое .bzr/repository для обычной ветки, но добавился файл&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;shared-storage&lt;/b&gt;&lt;/span&gt; (нулевой длины). Этот файл является маркером общего репозитория. Если его удалить, то наш объект перестанет быть shared repository.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Ветки внутри общего репозитория&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Теперь посмотрим, что происходит при клонировании ветки внутрь общего репозитория:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\shared-repo&amp;gt;bzr branch ../branch a_branch&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Branched 1 revision(s).&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Посмотрим внутрь служебного каталога новой копии a_branch:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branch/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branch-lock/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;checkout/&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branch-format&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;readme&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Как мы видим компонент .bzr/repository отсутствует. Что нам покажет bzr info -v:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\shared-repo\a_branch&amp;gt;bzr info -v&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Repository tree (format: 2a)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; shared repository: C:/work/bzr-day/Inside/shared-repo&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; repository branch: .&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Related branches:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; parent branch: C:/work/bzr-day/Inside/branch&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Format:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;control: Meta directory format 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; working tree: Working tree format 6&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; branch: Branch format 7&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; repository: Repository format 2a - rich roots, group compression and chk inventories&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Тем не менее, мы видим, что в секции форматов компонент repository присутствует. А в секции Location появилось упоминание shared repository. Наша новая ветка автоматически использует общий репозиторий вместо создания своего собственного. Если мы посмотрим внутрь .bzr/repository общего репозитория, то увидим, что туда добавлен новый пакетированный файл для нашей ветки.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Если мы посмотрим на branch.conf нашей новой ветки, то не увидим там никаких упоминаний общего репозитория и его расположения. И вообще нигде нет таких упоминаний. В том числе в структурах самого общего репозитория нет никаких указаний на расположение нашей ветки.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Bazaar осуществляет поиск общего репозитория для ветки просто просматривая все родительские каталоги вверх по дереву файловой системы пока не найдет один.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Из этого следует два вывода:&lt;/div&gt;
&lt;div&gt;
&lt;ol style="text-align: left;"&gt;
&lt;li&gt;Вы можете как угодно перемещать ветки внутри общего репозитория, внутрь подкаталогов, между подкаталогами, просто переименовывать ветки/каталоги -- и всё будет работать.&lt;/li&gt;
&lt;li&gt;Если вы просто скопируете или перенесете ветку из общего репозитория наружу, в другой каталог, то работа с такой веткой станет невозможна, поскольку bzr не сможет найти требуемый общий репозиторий. Вместо этого вам нужно использовать команду bzr branch, которая позаботится о том, чтобы восстановить репозиторий для ветки, если нужно.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Теперь посмотрим, что происходит при создании новой копии ветки внутри общего репозитория:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\shared-repo&amp;gt;bzr branch a_branch a_copy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Branched 1 revision(s).&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Новая ветка a_copy также использует общий репозиторий для хранения ревизий. Как следствие время создания новой ветки будет заметно меньше для веток с большой историей. В остальном новая копия работает точно также.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Дополнительные сведения про общие репозитории&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;1. Общий репозиторий ничего не знает про ветки внутри него&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Общий репозиторий является максимально общим хранилищем для ревизий. Настолько, что он ничего не знает о содержащихся внутри ветках. Их там даже может и не быть. С другой стороны &amp;nbsp;вы можете иметь внутри репозитория ветки не имеющие ни одной общей ревизии, не имеющие общей истории, и все будет работать, поскольку каждая ревизия имеет внутри себя указатель на последнюю зафиксированную ревизию (файл last-revision).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;2. Общий репозиторий на сервере&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Если у вас есть центральный сервер, &amp;nbsp;на котором вы храните свои ветки, то в большинстве случаев имеет смысл заводить общий репозиторий и на сервере, для получения тех же преимуществ: экономия места и ускорение клонирования веток. Однако чаще всего на сервере вашим веткам не нужно иметь рабочее дерево (компонент .bzr/checkout). Поэтому на сервере общий репозиторий имеет смысл создавать с опцией --no-trees:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside&amp;gt;bzr init-repo --no-trees shared-no-trees&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Shared repository (format: 2a)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; shared repository: shared-no-trees&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;C:\work\bzr-day\Inside\shared-no-trees&amp;gt;bzr info -v&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Shared repository (format: 2a)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Location:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; shared repository: .&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Format:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;control: Meta directory format 1&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; repository: Repository format 2a - rich roots, group compression and chk inventories&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Repository:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0 revisions&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
При данной опции внутри каталога .bzr/repository создается дополнительный файл-флаг нулевой длины &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;no-working-trees&lt;/span&gt;&lt;/b&gt;. Этот флаг влияет только на создание новых веток. В существующих ветках вы всегда можете создать или удалить рабочее дерево при помощи команд &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr checkout&lt;/span&gt; и &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr remove-tree&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
В существующем общем репозитории можно переключаться между режимами --no-trees и --trees при помощи команд:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --with-no-trees&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --with-trees&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;i&gt;3. Переход от самостоятельной ветки к использованию общего репозитория и обратно&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Если мы скопируем обычным образом (как просто каталог с файлами) нашу оригинальную самостоятельную ветку внутрь общего репозитория, то она все так же останется веткой со своим собственным репозиторием и не перейдет автоматически на использование общего репозитория. Но мы можем попросить bzr сделать это для нас при помощи команды&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --use-shared&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Это полезная команда еще и в тех случаях, когда у нас была просто самостоятельная ветка или две, а потом мы решили, что неплохо было бы, чтобы эта ветка или две были внутри общего репозитория. Тогда мы просто создаем в родительском каталоге общий репозиторий, и для всех веток запускаем команду&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --use-shared&lt;/span&gt;.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Существует и обратное преобразование: ветку, использующую общий репозиторий мы можем превратить в ветку со своим собственным репозиторием командой&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --standalone&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Также, если вам нужно создать копию ветки извне внутри вашего общего репозитория и вы хотите, чтобы новая копия не использовала этот общий репозиторий, то вместо двух команд&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr branch URL a_copy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr reconfigure --stadalone a_copy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
целесообразно использовать одну команду:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bzr branch --standalone URL a_copy&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Особенно, если формат ветки и общего репозитория не совпадают.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;i&gt;4. Замечание касательно форматов репозиториев&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Лучше всего если все ваши ветки используют один и тот же формат. Тем более, что формат в bzr не менялся уже 2 года.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Если же ваши ветки используют разные форматы, то учтите, что при клонировании ветки извне внутрь общего репозитория, копия ветки будет автоматически сконвертирована в формат вашего общего репозитория.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Поэтому я настоятельно рекомендую вам держать все свои рабочие ветки в одинаковом формате.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-1231516678588243330?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/1231516678588243330/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-2-shared-repository.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1231516678588243330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1231516678588243330'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-2-shared-repository.html' title='Inside .bzr: что внутри служебного каталога .bzr: Часть 2: shared repository'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-1858507915153799523</id><published>2011-08-08T10:14:00.001+01:00</published><updated>2011-08-08T10:48:15.658+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='для опытных'/><category scheme='http://www.blogger.com/atom/ns#' term='внутренности'/><title type='text'>Inside .bzr: что внутри служебного каталога .bzr. Часть 1: просто ветка</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
В своей книге&amp;nbsp;&lt;a href="http://www.ericsink.com/vcbe/"&gt;Version Control by Example&lt;/a&gt; &lt;a href="http://www.ericsink.com/"&gt;Эрик Синк (Eric Sink)&lt;/a&gt;&amp;nbsp;&lt;a href="http://www.ericsink.com/vcbe/html/internals.html"&gt;пишет&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;Version control tools are more like cars than clocks.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;Clock users have no need to know how a clock works behind the dials. We just want to know what time it is. Those who understand the inner workings of a clock can’t tell time any more skillfully than the rest of us.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;Version control tools are more like cars. Lots of people, including me, use cars without knowing much about how they work. However, people who really understand cars tend to get better performance out of them.&lt;/span&gt;&lt;/blockquote&gt;
Мне нравится это сравнение. В самом деле, если вы понимаете как внутри системы вертятся колесики, вы сможете более осознано управлять ею.&lt;br /&gt;
&lt;br /&gt;
В документации к bzr вопросам внутреннего устройства системы уделяется меньше внимания, чем могло быть. Отчасти потому что разработчики bzr исходили из посылки, что для успешного использования bzr знания о внутреннем устройстве необязательны (в отличие от git, где без знания как устроен репозиторий &amp;nbsp;вы не имеете права использовать его).&lt;br /&gt;
&lt;br /&gt;
Предлагаю рассмотреть внутреннее устройство служебного каталога .bzr, и что там живет внутри, это даст вам понимание о разнице между веткой, разделяемом репозитории (shared repository) и различным типам checkouts.&lt;br /&gt;
(&lt;a href="http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-1.html"&gt;Далее&lt;/a&gt;) &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;blockquote&gt;
Кстати, внутрь служебных каталогов типа .bzr заглядывать не поощряется, тем более, менять там что-то, ибо это может быть чревато фатальными последствиями. Однако в ходе этой статьи мы будем внимательно смотреть и изучать в отдельно созданных ветках и репозиториях, так что ничего не бойтесь.&lt;/blockquote&gt;
&lt;div style="text-align: left;"&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;Обычная ветка&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Начнем с объекта, создаваемого по умолчанию командой bzr init -- это обычная ветка.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside&amp;gt;bzr init branch&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Created a standalone tree (format: 2a)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside&amp;gt;cd branch&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы исследуемый объект не был совсем пустым, добавим файл и каталог и зафиксируем их в виде новой ревизии.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;bzr mkdir spam&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;added spam&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;echo &amp;gt; eggs&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;bzr add&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;adding eggs&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;bzr st&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;added:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; eggs&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; spam/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch&amp;gt;bzr ci -m "initial revision"&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Committing to: C:/work/bzr-day/Inside/branch/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;added eggs&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;added spam&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Committed revision 1.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Заходим внутрь каталога .bzr и что мы там видим:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch-lock/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;checkout/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;repository/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch-format&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;README&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Четыре каталога и 2 файла.&lt;br /&gt;
&lt;br /&gt;
Посмотрим, что нам предлагает прочитать в нем файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;README&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;This is a Bazaar control directory.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Do not change any files in this directory.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;See http://bazaar.canonical.com/ for more information about Bazaar.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Нам опять рассказывают о том, что ничего не надо менять здесь. Мы и не собираемся ничего менять, но должен заметить, что в некоторых очень особенных ситуациях кое-что менять внутри .bzr нужно уметь. Если вы не умеете -- не меняйте.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Посмотрим второй файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch-format&lt;/span&gt;:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Bazaar-NG meta directory, format 1&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Это не просто текстовый файл, это идентификатор формата служебного каталога. Порча этого файла приведет к невозможности работы с данной веткой. Если в результате сбоя диска или других неприятностей вы потеряете этот файл в вашем рабочем проекте, то можете восстановить его простым копированием из нормальной ветки. Этот формат не менялся уже очень давно, и я сильно сомневаюсь у вас есть активные ветки в архаичных форматах.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Из 4х каталогов &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch-lock&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;checkout&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;repository&lt;/span&gt; интересными для нас будут только &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;checkout&lt;/span&gt; и &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;repository&lt;/span&gt;, каталог &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch-lock&lt;/span&gt; предназначен для блокировок совместного доступа и в мирное время он пуст.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b style="background-color: white;"&gt;Историческое отступление&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;Файл branch-format и каталог&amp;nbsp;branch-lock имеют такое название с доисторических времен, когда Bazaar только зарождалась. Для обратной совместимости с древними форматами они оставлены без изменений.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;В остальных каталогах файл-маркер формата называется просто format, а каталог для блокировок -- lock.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: white;"&gt;Файлы-маркеры форматов (format) нужны bzr для того, чтобы знать как правильно работать с соответствующим объектом. На вопрос "зачем базару сто тысяч миллионов форматов" я отвечу в другой статье.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;Продолжаем.&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Каталоги branch, checkout, repository соответствуют 3м базовым объектам в bzr: ветке, рабочей копии и репозиторию. Собственно каталог .bzr, содержащий их, является контейнером и называется control directory. Все эти 4 объекта и их форматы отображаются в выводе команды &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr info -v&lt;/span&gt;:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch\.bzr&amp;gt;bzr info -v&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Standalone tree (format: 2a)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Location:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; branch root: C:/work/bzr-day/Inside/branch&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Format:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;control: Meta directory format 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; working tree: Working tree format 6&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; branch: Branch format 7&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; repository: Repository format 2a - rich roots, group compression and chk inventories&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Секция, озаглавленная Format, показывает нам форматы для всех 4х объектов. Эти форматы, как я уже сказал, идентифицируются файлами format в соответствующих подкаталогах.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b&gt;Компонент (каталог) branch&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Компонент branch содержит указатель на последнюю ревизию в данной ветке, а также теги в данной ветке. Кроме того он содержит конфигурационный файл, специфичный для данной ветки.&lt;br /&gt;
&lt;br /&gt;
Посмотрим внутрь &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;.bzr/branch&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;lock/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch.conf&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;format&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;last-revision&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;tags&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Каталог &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;lock&lt;/span&gt; неинтересен -- он для блокировок.&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;format&lt;/span&gt; содержит маркер формата компонента:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Bazaar Branch Format 7 (needs bzr 1.6)&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
(В выводе команды bzr info мы видели строку&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;Branch format 7&lt;/span&gt; -- совпадает).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;last-revision&lt;/b&gt;&lt;/span&gt; -- это тоже маркер. Собственно это -- указатель на последнюю ревизию в данной ветке (так называемый tip). Содержимое файла -- это пара &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;revno revid&lt;/span&gt;:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;1 ru_bzr@googlegroups.com-20110806154658-b9b3oat6e8tzsibe&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Первое число -- это номер последней ревизии, а строка -- это уникальный идентификатор ревизии. Если мы посмотрим журнал для последней зафиксированной ревизии, то увидим эти же данные:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch\.bzr\branch&amp;gt;bzr log --show-ids -r-1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;------------------------------------------------------------&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="background-color: #cccccc; font-family: 'Courier New',Courier,monospace;"&gt;revno: 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="background-color: #cccccc;"&gt;revision-id: ru_bzr@googlegroups.com-20110806154658-b9b3oat6e8tzsibe&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;committer: Базарный день &lt;ru_bzr@googlegroups.com&gt;&lt;/ru_bzr@googlegroups.com&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;branch nick: branch&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;timestamp: Sat 2011-08-06 18:46:58 +0300&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;message:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; initial revision&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Самой ревизии в .bzr/branch мы не видим -- ревизии хранятся в .bzr/repository.&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;tags&lt;/b&gt;&lt;/span&gt; -- это хранилище для тегов ветки. Пока мы не создали ни одного тега этот файл пустой. При добавлении тегов командой &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr tag&lt;/span&gt; в этот файл будут добавляться данные о тегах, в виде словаря где ключ -- это имя тега, а значение -- это идентификатор ревизии, на которую указывает тег. Сам словарь кодируется при помощи &lt;a href="http://ru.wikipedia.org/wiki/Bencode"&gt;Bencode&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;branch.conf&lt;/b&gt;&lt;/span&gt; наиболее интересен с точки зрения пользователя. Это файл конфигурации для текущей ветки. В нем могут храниться любые настройки и параметры, которые нужны для ветки. В частности, там хранятся пути/URL к связанным веткам: parent_location (для pull/missing/merge), push_location (для push), submit_location (для merge/send). Кроме того, плагин QBzr использует branch.conf для сохранения данных о коммитах, или кодировке файлов (qdiff/qannotate/qcat/qviewer). Этот файл должен иметь кодировку UTF-8, и в принципе если вам нужно, то его можно редактировать вручную, или менять параметры в нем с помощью команды &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr config&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Наиболее важно то, что для простых веток содержимое этого файла некритично для работы. А вот в случае bound branch / heavyweight checkout или stacked branch в файле branch.conf содержится важная информация, поэтому порча этого файла может нарушить нормальную работу. Подробнее об этом мы поговорим позднее.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Компонент (каталог) checkout&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
Компонент checkout хранит служебную информацию, необходимую для работы с рабочим деревом (working tree). Если ветка не имеет рабочего дерева (например, на сервере), то компонент будет отсутствовать.&lt;br /&gt;
&lt;br /&gt;
Посмотрим внутрь &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;.bzr/checkout&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;lock/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;shelf/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;conflicts&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;dirstate&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;format&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;views&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Назначение каталога &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;lock&lt;/b&gt;&lt;/span&gt; и файла &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;format&lt;/b&gt;&lt;/span&gt; -- аналогичное рассмотренным ранее.&lt;br /&gt;
&lt;br /&gt;
Каталог&lt;b&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;shelf&lt;/span&gt;&lt;/b&gt; предназначен для работы функциональности &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;shelve / unshelve&lt;/span&gt; -- именно там хранятся те правки, которые вы отобрали в команде &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;shelve&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;dirstate&lt;/b&gt;&lt;/span&gt; хранит информацию о файлах и каталогах в вашем рабочем дереве: о последней зафиксированной ревизии каждого элемента, об изменениях и т.д. Этот файл достаточно важен для нормальной работы, при его порче единственное, что можно сделать -- это создать рабочее дерева заново и скопировать туда последние незафиксированные изменения (если нужно).&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;conflicts&lt;/b&gt;&lt;/span&gt; как следует из его названия хранит информацию о текущих конфликтах требующих решения.&lt;br /&gt;
&lt;br /&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;views&lt;/b&gt;&lt;/span&gt; хранит информацию о настроенных видах (см. команду bzr view).&lt;br /&gt;
&lt;br /&gt;
Кроме этих файлов и каталогов в .bzr/checkout еще могут быть созданы следующие файлы и каталоги:&lt;br /&gt;
&lt;br /&gt;
файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;merge-hashes&lt;/b&gt;&lt;/span&gt; создается в результате merge и служит для отслеживания факта модификаций файлов после merge, используется командой revert для определения того, безопасно ли делать revert конкретному файлу или там могут находиться пользовательские изменения.&lt;br /&gt;
&lt;br /&gt;
два каталога &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;limbo&lt;/span&gt; и &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;pending-deletions&lt;/span&gt; -- это коротко живущие каталоги, создаваемые во время выполнения команд pull, push, merge. Эти каталоги не должны существовать после нормального завершения команд. Однако при сбоях в работе указанных команд эти каталоги остаются на диске и мешают дальнейшей работе. Единственный способ исправить сложившуюся ситуацию -- это нужно просто их удалить, особенно если они пустые.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Компонент (каталог) repository&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
Компонент repository -- это собственно хранилище истории: ревизий, текстов файлов в каждой ревизии, состояния рабочего дерева для каждой ревизии, а также подписей к ревизиям. Самостоятельные ветки имеют собственный репозиторий, ветки же создаваемые внутри shared repository используют репозиторий общего хранилища. Об этой особенности&amp;nbsp;&lt;a href="http://bzr-day.blogspot.com/2009/12/bzr_13.html"&gt;мы говорили ранее&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Начиная с bzr версии 1.0 основным форматом репозитория стал так-называемый pack-based формат. Краткое техническое описание формата можно прочитать в &lt;a href="http://doc.bazaar.canonical.com/bzr.2.3/developers/index.html"&gt;документации для разработчиков&lt;/a&gt; bzr:&amp;nbsp;&lt;a href="http://doc.bazaar.canonical.com/bzr.2.3/developers/packrepo.html#technical-notes"&gt;http://doc.bazaar.canonical.com/bzr.2.3/developers/packrepo.html#technical-notes&lt;/a&gt;. Также начиная с bzr 2.0 основным форматом репозитория стала улучшенная версия описанного формата 2a (CHKGroupCompress, CHK = Content Hash Key), которая улучшила сжатие данных в репозитории и позволила ускорить операции по сохранению и извлечению данных. В документации разработчиков есть только некоторые мысли касательно дизайна нового формата:&amp;nbsp;&lt;a href="http://doc.bazaar.canonical.com/bzr.2.3/developers/groupcompress-design.html"&gt;http://doc.bazaar.canonical.com/bzr.2.3/developers/groupcompress-design.html&lt;/a&gt;,&amp;nbsp;для нас же главное, что в формате 2a добавился еще один индекс. См. далее.&lt;br /&gt;
&lt;br /&gt;
Посмотрим внутрь &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;.bzr/repository&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;indices/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;lock/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;obsolete_packs/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;packs/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;upload/&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;format&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;pack-names&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Назначение каталога&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;lock&lt;/b&gt;&lt;/span&gt;&amp;nbsp;и файла&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;format&lt;/b&gt;&lt;/span&gt;&amp;nbsp;-- аналогичное рассмотренным ранее.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Файл &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;pack-names&lt;/b&gt;&lt;/span&gt; содержит список пакетированных (pack) файлов. Этот список содержит базовые имена файлов в каталогах &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;packs&lt;/span&gt; и&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt; indices&lt;/span&gt;. Если посмотреть этот файл в текстовом редакторе, то можно увидеть, что он закодирован (сжат для экономии места). Для просмотра его в читаемом виде можно применить скрытую команду &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr dump-btree&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch\.bzr\repository&amp;gt;bzr dump-btree pack-names&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;(('42d1a7283aac1a3d35f93593af36b836',), '162 161 238 72 183', None)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Показанные данные все равно имеют свои особенности, как мы видим, для нас же главное -- это первый элемент:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836&lt;/span&gt;. Это имя пакетированного файла и индексов к нему.&lt;br /&gt;
&lt;br /&gt;
Посмотрим внутрь каталога &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;packs&lt;/b&gt;&lt;/span&gt;: там находится единственный файл&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.pack&lt;/span&gt; и как мы можем видеть его имя файла соответствует информации из &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;pack-names&lt;/span&gt; + расширение.&lt;br /&gt;
&lt;br /&gt;
Отличительная деталь: имена пакетированных файлов совпадают с md5 суммой для их содержимого. Этот факт рекомендуется использовать для проверки целостности пакетированных файлов.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;C:\work\bzr-day\Inside\branch\.bzr\repository\packs&amp;gt;md5sum 42d1a7283aac1a3d35f93593af36b836.pack&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836 *42d1a7283aac1a3d35f93593af36b836.pack&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Сами пакетированные файлы содержат много блоков различной информации в сжатом виде (zlib + CHKGroupCompress) и для извлечения конкретной информации bzr использует индексы для определения того, где именно в файле лежат нужные данные.&lt;br /&gt;
&lt;br /&gt;
Индексы хранятся в каталоге&lt;b&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;indices&lt;/span&gt;&lt;/b&gt;. Посмотрим:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.cix&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.iix&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.rix&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.six&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;42d1a7283aac1a3d35f93593af36b836.tix&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Опять же имена файлов-индексов соответствуют имени пакетированного файла. Расширения файлов-индексов соответствуют различной информации, которую bzr собирается извлекать.&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;cix -- индексы для восстановления данных, закодированных по алгоритму CHKGroupCompress.&lt;/li&gt;
&lt;li&gt;tix -- индексы для извлечения содержимого файлов в рабочем дереве.&lt;/li&gt;
&lt;li&gt;rix -- индексы для извлечения данных о ревизиях.&lt;/li&gt;
&lt;li&gt;iix -- индексы для извлечения инвентаря ревизий (списка файлов и каталогов в конкретной ревизии + указание на содержимое файлов). Это аналог файлов dirstate из компонента checkout.&lt;/li&gt;
&lt;li&gt;six -- индексы для извлечения gpg-подписей к ревизиям (если таковые имеются).&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Индексы также закодированы, для их просмотра в раскодированном виде нужно использовать команду &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr dump-btree&lt;/span&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Каталоги &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;upload&lt;/span&gt; и &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;obsolete_packs&lt;/span&gt; имеют вспомогательный характер.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
В каталоге &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;upload&lt;/b&gt;&lt;/span&gt; создаются новые пакетированные файлы с временным именем, после чего переименовываются согласно их md5 и переносятся в каталог &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;packs&lt;/span&gt;. После успешного окончания операций каталог &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;upload&lt;/span&gt; должен быть пуст. Если в результате сбоя там остаются какие-то файлы, то их нужно удалять.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Каталог&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;b&gt;obsolete_packs&lt;/b&gt;&lt;/span&gt;&amp;nbsp;служит в качестве мусорки. Туда переносятся ненужные более пакетированные файлы и их индексы после перепаковки мелких пакетированных файлов в более крупные.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Bazaar при каждой новой ревизии создает один новый пакетированный файл. Каждый пакетированный файл записывается только один раз и туда больше ничего не дописывается. Это сделано чтобы гарантировать целостность данных. Однако, при таком подходе количество пакетированных файлов будет очень большим, что плохо скажется как на скорости работы, так и на используемом дисковом пространстве. Поэтому каждые 10/100/1000/10000/.... (10 в n-й степени) ревизий bzr автоматически осуществляет переупаковку мелких файлов в более крупные. По окончанию операции старые файлы не удаляются сразу, а сначала переносятся в каталог obsolete_packs, на случай если их нужно будет восстановить.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Переупаковку репозитория можно делать и вручную, запустив команду &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;bzr pack&lt;/span&gt;. Это имеет смысл периодически делать для репозиториев на центральном сервере, чтобы все работало максимально оптимально.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
После успешной перепаковки файлы из каталога&amp;nbsp;obsolete_packs&amp;nbsp;можно удалить. Команда bzr pack имеет ключ --clean-obsolete-packs однако его использование предваряется предупреждением, что в случае сбоя диска во время выполнения этой операции могут быть потеряны файлы. Более безопасным способом на Linux будет сделать что-то вроде &lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;sync &amp;amp;&amp;amp; sync&lt;/span&gt; и затем удалить файлы вручную.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Следует отметить, что bzr сам удалит файлы из obsolete_packs при следующей перепаковке (автоматической или ручной). Поэтому если дискового пространства у вас достаточно, то можно этим не заморачиваться.&lt;br /&gt;
&lt;br /&gt;
Однако для целей сравнения размеров репозиториев (с другими DVCS например) имеет смысл вручную перепаковаться и удалить файлы из obsolete_packs. Так результат будет более оптимальный.&lt;/div&gt;
&lt;br /&gt;
Автоматическая перепаковка иногда может быть нежелательной, в новых версиях bzr работают над тем, чтобы сделать ее настраиваемой.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Заключение&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Мы рассмотрели внутреннее устройство служебного каталога .bzr для базового объекта -- ветки. В последующих частях мы рассмотрим внутренее устройство других объектов -- shared repository, bound branch, stacked branch, lightweight checkout и увидим, что все они строятся из рассмотренных блоков в нужных комбинациях.&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-1858507915153799523?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/1858507915153799523/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-1.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1858507915153799523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1858507915153799523'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2011/08/inside-bzr-bzr-1.html' title='Inside .bzr: что внутри служебного каталога .bzr. Часть 1: просто ветка'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-252053332757891316</id><published>2011-08-05T16:43:00.001+01:00</published><updated>2011-08-25T12:08:58.843+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Bazaar уверенно удерживает третье место</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Ни для кого ни секрет, что bzr &lt;i&gt;не является &lt;/i&gt;самой-пресамой популярной DVCS по состоянию на 2011 год. По моим личным наблюдениям первое место уверенно держит git, я думаю не в последнюю очередь благодаря GitHub.&lt;br /&gt;
&lt;br /&gt;
На блогах Microsoft опубликованы &lt;a href="http://blogs.msdn.com/b/codeplex/archive/2011/07/11/survey-results-open-source-developer-preferences-june-2011.aspx"&gt;результаты опроса (через Twitter)&lt;/a&gt; предпочтений разработчиков Open Source проектов. Насколько эта выборка репрезентативна -- вопрос спорный. Однако она достаточно хорошо на качественном уровне показывает тенденции: git &amp;gt; hg &amp;gt; bzr.&lt;br /&gt;
&lt;br /&gt;
Выбрав цифры только для тройки git/hg/bzr и беспощадно усредняя их можно прийти к такой средней температуре по больнице:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;git ~77%&lt;/li&gt;
&lt;li&gt;hg ~18%&lt;/li&gt;
&lt;li&gt;bzr &amp;lt; 5%&lt;/li&gt;
&lt;/ul&gt;
Почему все еще имеет смысл использовать bzr? может спросить кто-то.&lt;br /&gt;
&lt;br /&gt;
С моей точки зрения причины к этому могут быть следующие:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt; вы и ваша команда более чем удовлетворены работой bzr и у вас нет причин менять проверенного коня. (По моему личному мнению каждая система из тройки имеет свои недостатки, с которыми придется мириться)&lt;/li&gt;
&lt;li&gt;Вы предпочитаете работать &lt;a href="http://bzr-day.blogspot.com/2010/01/blog-post.html"&gt;в централизованном стиле&lt;/a&gt; не теряя плюсов DVCS &lt;/li&gt;
&lt;li&gt;вам нравится GUI интерфейс к bzr -- QBzr и/или Bazaar Explorer, и вы не хотите их потерять при переходе на другую систему. Я не раз и не два получал отзывы от различных людей, даже от (увы) бывших пользователей bzr о том, что QBzr очень хорош. И я с этим согласен&lt;/li&gt;
&lt;li&gt;вам нравится использовать &lt;a href="https://launchpad.net/"&gt;Launchpad&lt;/a&gt; для хостинга своих открытых проектов.&lt;/li&gt;
&lt;li&gt;вы используете bzr для работы с svn через bzr-svn. Плюшки в виде QBzr/Explorer прилагаются и здесь.&lt;/li&gt;
&lt;/ul&gt;
Собственно других веских причин я затрудняюсь назвать. Я строго убежден, что лучшая DVCS еще не написана, и что у hg просто нет шансов подняться до более-менее паритета с git. Хотя на Windows платформе у hg много преимуществ, учитывая, что git на Windows -- это весьма тяжкое испытание.&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-252053332757891316?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/252053332757891316/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2011/08/bazaar.html#comment-form' title='Комментарии: 8'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/252053332757891316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/252053332757891316'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2011/08/bazaar.html' title='Bazaar уверенно удерживает третье место'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5202582340673412091</id><published>2010-04-06T20:05:00.035+01:00</published><updated>2010-04-06T23:35:52.417+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><title type='text'>Использование bzr-externals или компонентный подход</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;При работе над крупными проектами часто возникает потребность выделить часть проекта в отдельный подпроект, как самостоятельную сущность. Такой подпроект может представлять собой некоторую библиотеку, которая используется в разных проектах. Для работы с составными проектами, которые включают в себя дополнительные библиотеки, в bzr задумана функция под названием nested trees (в git для этого есть submodules, а в hg — subrepos). К сожалению разработка функции nested trees пока не завершена, поэтому вместо нее можно использовать плагины bzr-externals или bzr-scmproj. Я попросил автора плагина bzr-externals Евгения Тарасенко рассказать про работу с плагином. В данной статье описывается работа с плагином версии 1.3.&lt;/blockquote&gt;&lt;/div&gt;&lt;i&gt;Автор: Евгений Тарасенко&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Если ваш проект использует общие библиотеки или  компоненты, то самым правильным решением будет подключить их как вложенные  подпроекты (или компоненты), а не тупо копировать внутрь проекта.&lt;br /&gt;
&lt;br /&gt;
В Bazaar работа с общими компонентами пока еще не доведена  до ума, поэтому пришлось написать небольшой плагин &lt;a href="https://launchpad.net/bzr-externals"&gt;bzr-externals&lt;/a&gt;. Надо отметить, что существует еще один похожий плагин &lt;a href="https://launchpad.net/bzr-scmproj"&gt;bzr-scmproj&lt;/a&gt;, но в отличие от первого, в нем для работы с  компонентами используются отдельные команды, а это означает, что работа возможна  только из консоли и такие инструменты как Bazaar Explorer, QBzr и TortoizeBzr остаются не у дел.&lt;br /&gt;
&lt;br /&gt;
Основная же идея bzr-externals — использование только стандартных команд, чтобы пользователю не нужно было делать лишних телодвижений для работы с компонентами.&lt;br /&gt;
&lt;br /&gt;
Итак, нам понадобится плагин bzr-externals, который можно скачать с &lt;a href="http://launchpad.net/bzr-externals" target="_blank"&gt;http://launchpad.net/bzr-externals&lt;/a&gt; или взять прямо из репозитория lp:bzr-externals, о том как  это сделать можно узнать из &lt;a href="http://bzr-day.blogspot.com/2009/04/bzr.html"&gt;этой статьи&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Проектом может быть любая ветка. Для добавления нового компонента в проект как внешней  ссылки нам все же понадобится консоль, но так как это делается только один раз, то я  думаю ничего страшного. Формат команды добавления компонента следующий:&lt;/div&gt;&lt;pre&gt;bzr externals-add URL  DIRECTORY [--revision REVISIONSPEC]
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Здесь URL может  быть относительным, так же как и в svn:externals. Например, следующие команды делают почти одно и тоже, но разными способами, не считая использования конкретной ревизии в первом варианте (eadd — встроенный псевдоним команды):&lt;/div&gt;&lt;pre&gt;bzr eadd bzr://example.com/repos/common/foo  common/foo -r revno:100
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Если доступ к хранилищу возможен по разным протоколам (например, http или bzr+http), то для компонента имя протокола можно опустить, будет использоваться тот же протокол, по которому вы получите главный проект&lt;/div&gt;&lt;pre&gt;bzr eadd //example.com/repos/common/foo  common/foo
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Если ваш проект хостится на разных серверах, но с одинаковой структурой каталогов, то имя сервера также можно опустить, будет использовать сервер главного проекта&lt;/div&gt;&lt;pre&gt;bzr eadd /repos/common/foo  common/foo
&lt;/pre&gt;И наконец возможен доступ относительно каталога главного проекта в репозитории&lt;br /&gt;
&lt;pre&gt;bzr eadd ../../common/foo  common/foo
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Каталог, в котором должен размещаться компонент, DIRECTORY указывается относительно корня проекта. Если такого компонента еще нет в рабочей папке проекта, то будет выполнен branch/checkout, в зависимости от типа главного проекта, иначе pull/update.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;REVISIONSPEC — необязательный параметр, и должен использоваться, только если вам  нужна конкретная версия компонента.&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;В результате выполнения команды externals-add будет добавлен  компонент в рабочую директорию, а также в корне проекта появятся конфигурационные  файлы:&lt;/div&gt;&lt;pre&gt;.bzrmeta/externals
.bzrmeta/externals-snapshot
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Первый файл используется для хранения параметров  всех компонентов и может быть отредактирован пользователем; например, чтобы привязать компонент к конкретной версии или просто удалить компонент из проекта. Второй файл создается автоматически при каждом commit в проекте и предназначен для создания "снимка" используемых ревизий компонентов,  чтобы впоследствии, при откате на какую-либо ревизию, можно было точно  восстановить все дерево проекта (чего, кстати, не умеет делать subversion).&lt;br /&gt;
&lt;br /&gt;
Формат обоих конфигурационных файлов одинаков и  незатейлив:&lt;/div&gt;&lt;pre&gt;URL DIRECTORY REVISIONSPEC
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Итак, компонент добавлен в ваш проект, и теперь,  казалось бы, надо описать, как нам работать с ним, но тут вступает в силу главный принцип плагина – никаких дополнительных команд. Поэтому всё, что вы  делаете с основным проектом, будет повторяться и для всех компонентов. Вот список поддерживаемых команд для версии 1.3:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;; font-size: 10pt;"&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span lang="EN-US"&gt;branch&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt; [--&lt;/span&gt;&lt;span lang="EN-US" style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;revision&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;checkout&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt; [--&lt;/span&gt;&lt;span lang="EN-US" style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;revision&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;commit&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;pull&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;push&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;update&lt;/span&gt;&lt;span style="font-family: &amp;quot;Lucida Console&amp;quot;;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Однако, если вам все же не хватает этих команд, то  есть два пути: первый — просто зайти в директорию с компонентом и делать с ним  что угодно, так как по сути это обыкновенная ветка &lt;span lang="EN-US"&gt;Bazaar&lt;/span&gt;.  И второй путь — использовать вторую дополнительную команду &lt;span lang="EN-US"&gt;externals&lt;/span&gt;-&lt;span lang="EN-US"&gt;cmd&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;или кратко &lt;span lang="EN-US"&gt;ecmd&lt;/span&gt;, чтобы выполнить любую команду &lt;span lang="EN-US"&gt;Bazaar&lt;/span&gt;&lt;span lang="EN-US"&gt; &lt;/span&gt;для всех компонентов проекта и для самого проекта  тоже. Например, посмотреть последнюю ревизию для всех:&lt;/div&gt;&lt;pre&gt;bzr ecmd -- log -r -1
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Работа с Bazaar может быть организована различными способами, в том числе с использованием feature branch, когда сначала делается локальная копия удаленного репозитория, а уже от нее делается ветка для конкретной фичи, плагин поддерживает и такой режим работы.&lt;br /&gt;
&lt;br /&gt;
Рассмотрение плагина подошло к концу,  дополнительную информацию можно получить с помощью:&lt;/div&gt;&lt;pre&gt;bzr help externals
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5202582340673412091?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5202582340673412091/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/04/bzr-externals.html#comment-form' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5202582340673412091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5202582340673412091'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/04/bzr-externals.html' title='Использование bzr-externals или компонентный подход'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-2541350383262817453</id><published>2010-03-24T12:53:00.002Z</published><updated>2010-03-24T13:09:54.333Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='советы'/><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><title type='text'>Командная строка и bzr: "ленивые" опции</title><content type='html'>&lt;div style="text-align: justify;"&gt;Следующий совет может оказаться полезным для тех, кто использует &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr&lt;/span&gt; из командной строки на постоянной основе или даже время от времени. Как вы помните, многие команды &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr &lt;/span&gt;имеют встроенные псевдонимы, а также пользователь может задавать свои собственные &lt;a href="http://bzr-day.blogspot.com/2009/11/bzr-aliases.html"&gt;пользовательские псевдонимы&lt;/a&gt; при помощи команды &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;alias&lt;/span&gt;. Так вместо &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;status &lt;/span&gt;можно использовать &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;st&lt;/span&gt;, а вместо &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;commit &lt;/span&gt;— &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ci&lt;/span&gt;. Однако эти самые команды зачастую имеют обширный набор опций для тонкого управления поведением каждой команды. Все эти опции имеют основную форму вида &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--имяопции&lt;/span&gt;, и могут иметь короткую форму вида &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-X &lt;/span&gt;где &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;X &lt;/span&gt;— это одна буква латинского алфавита. Для того, чтобы узнать какая короткая форма у определенной опции, просматривайте &lt;a href="http://bzr-day.blogspot.com/2009/11/bzr.html"&gt;информацию об использовании команды&lt;/a&gt;. Например, опция &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--revision&lt;/span&gt; имеет короткую форму &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-r&lt;/span&gt; (о чем вы наверняка знаете).&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Однако это еще не всё. Движок, используемый для обработки опций и аргументов команд &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr&lt;/span&gt; позволяет использовать сокращенную запись для основной формы. Сокращать допускается до того состояния пока &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr &lt;/span&gt;сможет однозначно понять, что вы имеете ввиду, обычно достаточно оставить 2-3 первых буквы. Например, опцию &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--revision&lt;/span&gt; можно сокращать до &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--rev&lt;/span&gt;, а опцию&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; --force&lt;/span&gt; до &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--fo.&lt;/span&gt; Тогда &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pull --remember&lt;/span&gt; можно вызывать как &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pull --rem&lt;/span&gt;, а &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;push --overwrite&lt;/span&gt; как &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;push --over&lt;/span&gt;, и т.д. И поскольку не все опции имеют короткую форму из одной буквы, то часто бывает полезно знать эту возможность.&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Причем если вы чересчур сильно сократите опцию и &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr &lt;/span&gt;не сможет понять какую из двух похожих по сокращению опций надо использовать, то вы увидите соответствующее сообщение об ошибке:&lt;/div&gt;&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;C:\work\bzr-day\options-for-lazy&amp;gt;bzr pull --re lp:foo&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;bzr: ERROR: ambiguous option: --re (--remember, --revision?)&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;В данном случае bzr не смог понять какую именно опцию вы имели ввиду: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--remember &lt;/span&gt;или &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--revision&lt;/span&gt;.&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Механизм поддержки сокращений для опций работает для всех опций самой команды, но не работает для глобальных опций самого &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr&lt;/span&gt;, таких как &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--no-plugins&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--no-aliases&lt;/span&gt; и т.п. Полный список глобальных опций можно увидеть запустив команду &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;bzr help global-options&lt;/span&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-2541350383262817453?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/2541350383262817453/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/03/bzr.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2541350383262817453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2541350383262817453'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/03/bzr.html' title='Командная строка и bzr: &quot;ленивые&quot; опции'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-1847183718112259234</id><published>2010-03-21T11:47:00.004Z</published><updated>2010-03-21T12:08:06.408Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='настройки'/><title type='text'>Использование внешнего редактора для команды bzr shelve</title><content type='html'>&lt;div style="text-align: justify;"&gt;Одной из очень полезных функций в bzr является пара команд &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shelve/unshelve&lt;/span&gt;. Эти команды позволяют временно удалить из рабочих файлов часть изменений, чтобы зафиксировать остальные изменения без них. Часто это бывает нужно для логического разделения разных правок. Например, вы начали реализовывать новую функцию в своей программе и попутно обнаружили и исправили старый баг. Имеет смысл зафиксировать исправление ошибки отдельно и затем продолжить работу над новой функцией. В этом случае помогает &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shelve/unshelve&lt;/span&gt;.&lt;/div&gt;&lt;blockquote&gt;Подобная функциональность присутствует в других системах контроля версий. Так, в git для этого используется команда &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;stash&lt;/span&gt;, а в hg для этого используется расширение &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shelve&lt;/span&gt;.&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;Подробный рассказ об использовании shelve/unshelve заслуживает отдельной статьи. Вкратце процесс отбора изменений для удаления их "на полочку" выглядит следующим образом:&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;вы запускаете команду shelve, опционально указывая список файлов, в которых нужно отобрать изменения.&lt;/li&gt;
&lt;li&gt;для каждого файла с изменениями bzr вам показывает отдельные блоки изменений (diff hunks), аналогично тому как блоками показывает изменения команда diff.&lt;/li&gt;
&lt;li&gt;для каждого блока вы указываете: хотите ли вы убрать это изменение "на полочку" либо оставить в рабочей копии.&lt;/li&gt;
&lt;li&gt;после того, как вы ответите на вопрос по каждому блоку каждого файла с изменениями, отобранные изменения удаляются из рабочей копии и сохраняются в специальном хранилище ("на полочке").&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Подробнее об использовании shelve смотрите справку по этой команде.&lt;br /&gt;
&lt;br /&gt;
Одним из неудобств при использовании shelve является гранулярность отбора изменений. Вы не можете так просто удалить одну строку с изменениями из целого блока (hunks). Вам приходится или убирать весь блок или оставлять весь блок. Что &lt;i&gt;было&lt;/i&gt; не очень удобно.&lt;br /&gt;
&lt;br /&gt;
Однако, к нашей радости, в bzr 2.1.0 у shelve появилась новая функция: теперь можно использовать внешний редактор для правки и отбора изменений. В качестве редактора имеет смысл использовать программу для просмотра и редактирования изменений в 2х файлах. Например, vimdiff, WinMerge и проч.&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы использовать внешний редактор в команде shelve его следует предварительно задать в файле конфигурации bazaar.conf. Для этого в секции &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;[DEFAULT]&lt;/span&gt; добавьте строку вида:&lt;/div&gt;&lt;pre&gt;change_editor = vimdiff -fo @new_path @old_path
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Здесь: @new_path @old_path — это специальные параметры, вместо которых в реальности bzr будет подставлять полный путь к редактируемому файлу (@new_path) и полный путь к файлу с последним зафиксированным состоянием (@old_path).&lt;br /&gt;
&lt;br /&gt;
Так, например, я для использования WinMerge указал следующую строку в bazaar.conf:&lt;/div&gt;&lt;pre&gt;change_editor = '"C:/Program Files/WinMerge/WinMergeU.exe" @old_path @new_path'
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;После того, как вы настроите change_editor, при вызовах shelve в строке выбора для каждого блока изменений вам будет доступен дополнительный выбор ("e"). По нажатию на клавишу "e" (editor) будет запущена указанная вами программа для редактирования текущего файла. Ваша задача: отредактировать @new_path до состояния, в котором вы хотите, чтобы он был на диске. Команда shelve сама определит какие изменения нужно убрать из текущей рабочей копии конкретного файла, чтобы в итоге получилось то, что вы хотите.&lt;br /&gt;
&lt;br /&gt;
Приятной работы!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-1847183718112259234?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/1847183718112259234/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/03/bzr-shelve.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1847183718112259234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1847183718112259234'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/03/bzr-shelve.html' title='Использование внешнего редактора для команды bzr shelve'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-2626781088552156871</id><published>2010-02-18T09:01:00.004Z</published><updated>2010-02-18T09:04:40.797Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><category scheme='http://www.blogger.com/atom/ns#' term='блоги'/><title type='text'>Использование плагина bzr-pipeline для "вечных" локальных правок</title><content type='html'>&lt;a href="http://softwaremaniacs.org/about/"&gt;Иван Сагалаев&lt;/a&gt; описал один из вариантов работы с плагином &lt;a href="https://launchpad.net/bzr-pipeline"&gt;bzr-pipeline&lt;/a&gt;. Иван &lt;a href="http://softwaremaniacs.org/blog/2010/02/18/local-patches-in-bzr-pipeline"&gt;пишет&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;...хочу поделиться bzr-специфичным решением одной практической ситуации, возникающей при групповой работе над проектом.  &lt;br /&gt;
Работая над общим кодом на локальной машине, иногда бывает нужно делать в нём строго локальные правки: пути к файлам, адреса серверов, отладочное логирование. При этом эти правки никогда не должны попадать в основной бранч проекта. &lt;br /&gt;
Часть из них можно и нужно вынести в отдельные локальные конфигурационные файлы, которые просто заигнорировать. Но вот с упомянутым отладочным логированием так не получится — это произвольный код, временно раскиданный по файлам. Ещё один пример такой правки — полное вырезание куска кода, который не критичен для работы, но не даёт проекту завестись с локальном окружении.&lt;br /&gt;
В bzr для этой проблемы мне известны два решения: одно прямое, другое — более удобное, с помощью плагина &lt;a href="http://wiki.bazaar.canonical.com/BzrPipeline" rel="nofollow"&gt;bzr-pipeline&lt;/a&gt;. Беда только в том, что в его документации описан несколько другой юзкейс, и я с первого раза вообще не понял, как оно мне поможет. Потом разобрался и решил восполнить пробел.&lt;/blockquote&gt;Читать целиком: &lt;a href="http://softwaremaniacs.org/blog/2010/02/18/local-patches-in-bzr-pipeline/#more"&gt;http://softwaremaniacs.org/blog/2010/02/18/local-patches-in-bzr-pipeline&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-2626781088552156871?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/2626781088552156871/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bzr-pipeline.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2626781088552156871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2626781088552156871'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bzr-pipeline.html' title='Использование плагина bzr-pipeline для &quot;вечных&quot; локальных правок'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-6044508282482439918</id><published>2010-02-17T13:53:00.004Z</published><updated>2010-04-16T13:01:15.561+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='анонсы'/><title type='text'>Новая стабильная версия Bazaar 2.1.0</title><content type='html'>&lt;div style="text-align: justify;"&gt;Спустя полгода после выпуска стабильного релиза bzr 2.0.0 разработчики Bazaar представляют новую стабильную версию Bazaar 2.1.0 (февраль 2010 года).&lt;br /&gt;
&lt;br /&gt;
Новая версия содержит в себе много разных улучшений и исправлений дефектов, однако ничего революционного (вроде нового формата репозитория) не несёт. Список отдельных улучшений просто огромен (более 200 пунктов), поэтому рассмотрим только ключевые и заметные для пользователей моменты.&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Значительно уменьшено потребление памяти для выполнения операций (уменьшение почти в два раза). Это значит, что с ветками с большой историей работать будет быстрее и комфортнее.&lt;/li&gt;
&lt;li&gt;Добавлен новый хук для объединения файлов. Теперь становится возможным для файлов разных типов определять различные алгоритмы объединения изменений. Для использования этой возможности необходимо будет написать соответствущий плагин.&lt;br /&gt;
&lt;blockquote&gt;В качестве примера такого плагина вместе с bzr поставляется плагин &lt;a href="http://bazaar.launchpad.net/%7Ebzr-pqm/bzr/2.1/files/head%3A/bzrlib/plugins/news_merge/"&gt;news_merge&lt;/a&gt;, который должен облегчить процесс объединения изменений в файле NEWS в исходном коде самого bzr. (Файл NEWS в bzr редактируется очень часто, поэтому конфликты возникают очень часто).&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;В файле .bzrignore теперь можно задавать шаблоны для отключения игнорирования специфичных файлов. Для этого используйте восклицательный знак (!) в начале шаблона.&lt;br /&gt;
&lt;blockquote&gt;Например, игнорируем все файлы кроме *.py: &lt;br /&gt;
&lt;pre&gt;* 
!*.py&lt;/pre&gt;&lt;/blockquote&gt;&lt;/li&gt;
&lt;li&gt;Функция shelve: теперь имеется возможность использовать внешний редактор для редактирования изменений, которые должны быть отложены "на полочку". Для этого нужно указать редактор в файле конфигурации как опцию &lt;tt&gt;change_editor&lt;/tt&gt;, например: &lt;br /&gt;
&lt;pre&gt;change_editor = vimdiff -fo @new_path @old_path
&lt;/pre&gt;здесь &lt;tt&gt;@new_path&lt;/tt&gt; и &lt;tt&gt;@old_path&lt;/tt&gt; специальные макросы для подстановки пути к текущей версии файла и зафиксированной его версии.   &lt;/li&gt;
&lt;li&gt;Новая опция &lt;tt&gt;unshelve --preview&lt;/tt&gt; для просмотра отложенных изменений&lt;/li&gt;
&lt;li&gt;Для checkout теперь можно сделать &lt;tt&gt;switch --revision&lt;/tt&gt;, &lt;tt&gt;update --revision&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;При указании ревизии опцией &lt;tt&gt;--revision (-r)&lt;/tt&gt; теперь можно использовать более простой синтаксис в стиле "делай то, что я имею в виду" (&lt;a href="http://en.wikipedia.org/wiki/DWIM"&gt;DWIM&lt;/a&gt;). Т.е. вместо &lt;tt&gt;-r tag:foo&lt;/tt&gt; можно использовать просто &lt;tt&gt;-r foo&lt;/tt&gt;, а вместо &lt;tt&gt;-r date:today&lt;/tt&gt; просто &lt;tt&gt;-r today&lt;/tt&gt;. Префиксы по прежнему можно использовать, и они могут понадобиться в случаях, когда bzr не сможет угадать правильный вариант (например тег 1.1.1 может совпадать с номером ревизии 1.1.1).&lt;/li&gt;
&lt;li&gt;На Windows в командной строке поддерживаются маски для имен файлов, как на Linux. Раньше такая поддержка существовала в специфичном виде только для команды bzr add, теперь же она реализована в общем виде для всех команд. Поэтому теперь для добавления маски *.obj в файл .bzrignore командой &lt;tt&gt;bzr ignore&lt;/tt&gt; вам нужно позаботиться о том, чтобы аргумент *.obj был взят в кавычки.&lt;/li&gt;
&lt;li&gt;Поддержка знака тильды (~) как домашнего каталога пользователя в URL вида &lt;tt&gt;bzr+ssh://host/~&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Появился новый раздел в документации: &lt;a href="http://doc.bazaar.canonical.com/bzr.dev/en/admin-guide/index.html"&gt;Bazaar System Administrator’s Guide&amp;nbsp;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Значительно переработана &lt;a href="http://doc.bazaar.canonical.com/plugins/en/"&gt;документация по плагинам&lt;/a&gt;. Кроме основных сведений также содержит автоматически сгенерированную документацию по всем публичным плагинам.&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Кроме изменений в самом bzr множество изменений в сопутствующих инструментах и плагинах. Так GUI для bzr Bazaar Explorer меньше чем за 9 месяцев доросло до версии 1.0, с чем мы и поздравляем его автора Йена Клэтворси (Ian Clatworthy).&lt;br /&gt;
&lt;br /&gt;
Разработчики bzr объявили, что предыдущая стабильная версия bzr 2.0 (текущий релиз по состоянию на февраль 2010 — это &lt;a href="https://launchpad.net/bzr/2.0/2.0.4"&gt;2.0.4&lt;/a&gt;) будет поддерживаться и далее, но настоятельно рекомендуют переходить на 2.1. Серия 2.1 будет поддерживаться в течение года (как минимум), она же будет включена в дистрибутив Ubuntu Lucid.&lt;br /&gt;
&lt;br /&gt;
Сморите также:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="https://launchpad.net/bzr/+announcement/5157"&gt;Bazaar 2.1.0 Released&amp;nbsp;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bazaarvcs.wordpress.com/2010/01/18/bazaar-2-1-2/"&gt;Bazaar 2.1, coming through&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/09/bazaar-20.html"&gt;Bazaar 2.0 и новый формат репозитория по умолчанию&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-6044508282482439918?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/6044508282482439918/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bazaar-210.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6044508282482439918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6044508282482439918'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bazaar-210.html' title='Новая стабильная версия Bazaar 2.1.0'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5517582850037951877</id><published>2010-02-07T05:49:00.001Z</published><updated>2010-02-07T05:52:36.659Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='особенности'/><title type='text'>Уникальные идентификаторы файлов в bzr</title><content type='html'>&lt;div style="text-align: justify;"&gt;Как я уже упоминал в статье &lt;a href="http://bzr-day.blogspot.com/2009/12/bzr_13.html"&gt;"одна ветка = один каталог"&lt;/a&gt; bzr унаследовал из baz такую особенность как уникальные идентификаторы файлов. В этой статье рассмотрим идентификаторы подробнее.&lt;br /&gt;
&lt;blockquote&gt;В примерах использовался bzr версии 2.1. &lt;/blockquote&gt;&lt;/div&gt;&lt;h2&gt;Для чего нужны идентификаторы файлов&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Для каждого файла, каталога или симлинка Bazaar использует внутри некий уникальный идентификатор, аналогично уникальным идентификаторам ревизий. Присвоение каждому версионированному объекту идентификатора упрощает отслеживание переименований/перемещений файлов и каталогов. Таким образом операция получения журнала ревизий для одного файла, а также операция объединения изменений в разных ветках, — эти операции работаю гораздо эффективнее поскольку им не требуется отслеживать все прошлые переименования. Чтобы получить копию файла из прошлой ревизии через команду &lt;br /&gt;
&lt;pre&gt;bzr cat -rN file&lt;/pre&gt;вам не нужно задумываться о том,&amp;nbsp; были ли переименования и какое имя было у файла в той ревизии: bzr использует идентификатор файла и сам найдет нужные данные.&lt;br /&gt;
&lt;br /&gt;
Уникальные идентификаторы назначаются в момент добавления файлов/каталогов под контроль версий командой &lt;tt&gt;add&lt;/tt&gt; и затем в течении жизни файлов/каталогов уже не меняются.&lt;br /&gt;
&lt;br /&gt;
Уникальные идентификаторы файлов можно посмотреть с помощью команды &lt;tt&gt;bzr ls --show-ids&lt;/tt&gt;:&lt;br /&gt;
&lt;pre&gt;$ bzr ls --show-ids
bar.txt    bar.txt-20100207052407-e0zzku5zxmzfsso8-1
foo/       foo-20100207052337-rv090vn2o3x0m720-1&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;Проблемы с идентификаторами файлов&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;В теории от использования уникальных идентификаторов для файлов система должна получать сплошные плюсы и никаких проблем. К сожалению, на практике это не так.&lt;br /&gt;
&lt;br /&gt;
Текущая реализация идентификаторов файлов в bzr страдает следующими недостатками:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Один и тот же файл добавленный в разных ветках одного и того же проекта будет иметь разный идентификатор. Что при последующем объединении веток приведет к проблеме: bzr будет считать эти два файла абсолютно разными. В результате вы получите конфликт объединения и вам придется выбрать какой файл оставить, а какой удалить (и соответственно потерять историю изменений). Изменения между версиями из разных веток придется объединять вручную.&lt;/li&gt;
&lt;li&gt;Если вы отмените контроль версий для файла командой &lt;tt&gt;bzr remove file&lt;/tt&gt; а затем передумаете и снова добавите его командой &lt;tt&gt;bzr add file&lt;/tt&gt;, то команда &lt;tt&gt;add&lt;/tt&gt; назначит файлу новый уникальный идентификатор, соответственно история файла прервется и начнется с нуля.&lt;/li&gt;
&lt;li&gt;Текущая реализация уникальных идентификаторов в bzr препятствует реализации функции создания копий файлов (аналогично &lt;tt&gt;svn copy&lt;/tt&gt; или &lt;tt&gt;hg copy&lt;/tt&gt;).&lt;/li&gt;
&lt;/ol&gt;Озвученные недостатки являются неприятными, но не критическими. Большинство проектов эти недостатки может и не заметить. Однако замалчивать их в этом блоге я не буду.&lt;br /&gt;
&lt;br /&gt;
В теории эти недостатки можно преодолеть, и главные разработчики bzr даже имеют &lt;a href="http://wiki.bazaar.canonical.com/DraftSpecs/PathTokens"&gt;определенные планы на этот счёт&lt;/a&gt;. Но по состоянию на версию bzr 2.1 эти планы еще не реализованы и сложно сказать когда они все-таки будут реализованы.&lt;br /&gt;
&lt;br /&gt;
Проблемы 1 и 2 из списка выше возможно решить в текущей версии bzr с помощью определенных техник.&lt;/div&gt;&lt;h2&gt;Использование bzr add --file-ids-from&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Поскольку bzr назначает уникальный идентификатор во время выполнения команды bzr add, то для &lt;i&gt;частичного&lt;/i&gt; преодоления проблемы номер 1 из списка выше (один и тот же файл добавленный в разных ветках будет иметь разные идентификаторы) можно воспользоваться опцией &lt;tt&gt;--file-ids-from&lt;/tt&gt; команды &lt;tt&gt;add&lt;/tt&gt;. Эта опция в качестве своего аргумента принимает путь к другой ветке и для всех новых файлов, имена которых совпадают с именами файлов в той другой ветке, используются уникальные идентификаторы из другой ветки. Таким образом можно избежать расхождения идентификаторов.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\file-ids&amp;gt;bzr init a

C:\work\bzr-day\file-ids&amp;gt;bzr mkdir a/foo
added a/foo

C:\work\bzr-day\file-ids&amp;gt;bzr commit -m1 a
Committing to: C:/work/bzr-day/file-ids/a/
added foo
Committed revision 1.

C:\work\bzr-day\file-ids&amp;gt;echo &amp;gt; a/bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr add a
adding bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr ls a --show-ids
a/bar.txt    bar.txt-20100207052407-e0zzku5zxmzfsso8-1
a/foo/       foo-20100207052337-rv090vn2o3x0m720-1&lt;/pre&gt;&lt;br /&gt;
Теперь создадим копию ветки а для ревизии 1 и также попробуем добавить файл bar.txt:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\file-ids&amp;gt;bzr branch a b
Branched 1 revision(s).

C:\work\bzr-day\file-ids&amp;gt;echo &amp;gt; b/bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr add b
adding bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr ls b --show-ids
b/bar.txt    bar.txt-20100207052932-m88m6b14qvdroa2s-1
b/foo/       foo-20100207052337-rv090vn2o3x0m720-1&lt;/pre&gt;&lt;br /&gt;
Как мы видим уникальные идентификаторы для файла bar.txt в разных ветках различаются.&lt;br /&gt;
&lt;br /&gt;
Повторим те же действия, но файл будем добавлять с опцией --file-ids-from:&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\file-ids&amp;gt;bzr branch a c
Branched 1 revision(s).

C:\work\bzr-day\file-ids&amp;gt;echo &amp;gt; c/bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr add c --file-ids-from a
adding bar.txt w/ file id from bar.txt

C:\work\bzr-day\file-ids&amp;gt;bzr ls c --show-ids
c/bar.txt    bar.txt-20100207052407-e0zzku5zxmzfsso8-1
c/foo/       foo-20100207052337-rv090vn2o3x0m720-1&lt;/pre&gt;&lt;br /&gt;
Теперь файл bar.txt добавлен с тем же самым уникальным идентификатором.&lt;/div&gt;&lt;h2&gt;Восстановление контроля версий для файла после команды bzr remove&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Выше указывалось, что вторым недостатком уникальных идентификаторов является то, что файл удаленный из-под контроля версий командой &lt;tt&gt;bzr remove&lt;/tt&gt; при последующем добавлении командой &lt;tt&gt;bzr add&lt;/tt&gt; получит новый уникальный идентификатор. Как следствие для такого файла прервется история. Если вы не хотите терять историю, то вместо использования &lt;tt&gt;bzr add&lt;/tt&gt; для восстановления файла вам необходимо использовать команду &lt;tt&gt;bzr revert&lt;/tt&gt;. В этом случае файл будет восстановлен в последнем зафиксированном состоянии с правильным уникальным идентификатором.&lt;br /&gt;
&lt;br /&gt;
Даже если вы удалили файл несколько ревизий назад, то используйте команду &lt;tt&gt;bzr revert -rN file&lt;/tt&gt;, где N — это номер ревизии, предшествующей удалению файла.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5517582850037951877?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5517582850037951877/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bzr.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5517582850037951877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5517582850037951877'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/02/bzr.html' title='Уникальные идентификаторы файлов в bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-2771139047305419480</id><published>2010-01-15T15:48:00.001Z</published><updated>2010-01-25T12:39:47.053Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Работа с bzr в централизованном стиле</title><content type='html'>&lt;blockquote&gt;Наш читатель и автор плагина &lt;a href="https://launchpad.net/bzr-externals"&gt;bzr-externals&lt;/a&gt; &lt;a href="https://launchpad.net/%7Eeugene-tarasenko"&gt;Евгений Тарасенко&lt;/a&gt; рассказывает о работе с Bazaar в централизованном стиле (а-ля svn). Передаю ему слово.&lt;br /&gt;
&lt;/blockquote&gt;&lt;h2&gt;Централизованный стиль&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;В данной статье я хотел бы обратить внимание на еще один вариант организации работы с системой контроля версий Bazaar, о котором часто забывают в пылу погони за ветками и DVCS. Я говорю о централизованном стиле работы, который используется в Subversion, но в отличии от последнего Bazaar предоставляет намного более гибкий и главное понятный инструмент разработчику. Так в нашем распоряжении оказываются: понятная история ветвлений (попробуйте bzr qlog), локальные фиксации, откат и много других приятных мелочей. Также не стоит забывать что Bazaar расширяемая система и если вам там чего-то не хватает, то можно попробовать написать это самому!&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Итак, чем хорош централизованный стиль:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;во-первых, вся работа ведется в одной директории что очень актуально для многих IDE, которые забывают про мелкие настройки при переходе в другой каталог&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;во-вторых, если вы используете С++ компилятор то количество дополнительных файлов просто съест ваше время и место на жестком диске при каждом новом построении, а при работе с ветками неизбежно придется компилировать и отлаживать сначала ветку, а после слияния и trunk&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;ну и в-третьих, иногда бывает нужно зафиксировать небольшое изменение (одну ревизию) и тут у вас просто меньше лишних телодвижений в отличии от стилей с feature branch или с переключением веток.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Про TortoiseBzr&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Для начала, я хотел бы обратить внимание на тот факт, что при установке Bazaar под Windows по умолчанию отключен модуль TortoiseBzr, скорее всего это связано с его некоторой задумчивостью при обновлении статуса иконок файлов, частенько бывает нужно пару раз F5 нажать, чтобы он сообразил что к чему. Поэтому если вы любитель работы из проводника проверьте, что он у вас установлен.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Базовый набор команд&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Поскольку Bazaar поддерживает различные &lt;a href="http://bzr-day.blogspot.com/2009/11/bzr-aliases.html"&gt;псевдонимы (алиасы) для команд&lt;/a&gt;, то вы можете выбрать для себя наиболее удобный вариант использования:&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;tt&gt;checkout, co, qgetnew&lt;/tt&gt; — извлечь рабочую копию&lt;br /&gt;
&lt;tt&gt;commit, ci, qcommit, qci&lt;/tt&gt; — фиксировать изменения&lt;br /&gt;
&lt;tt&gt;update, up, qupdate, qup&lt;/tt&gt; — обновить рабочую копию&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Я думаю, общая идея понятна, хочу только отметить что префикс "q" обозначает команды с GUI интерфейсом, предоставляемые плагином &lt;a href="https://launchpad.net/qbzr"&gt;QBzr&lt;/a&gt;.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Извлечение проекта из хранилища&lt;/h3&gt;Команда:&lt;br /&gt;
&lt;tt&gt;bzr checkout bzr://server/project/trunk project&lt;/tt&gt;&lt;br /&gt;
или из контекстного меню проводника: 'Bazaar Checkout/Branch…'&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xbBcXgfHrHY/S0sgNqfejFI/AAAAAAAAACc/9iyRUnXKF2g/s1600-h/qgetnew.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_xbBcXgfHrHY/S0sgNqfejFI/AAAAAAAAACc/9iyRUnXKF2g/s640/qgetnew.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Как вы можете заметить, интерфейс диалога частично переведен, но используемая терминология может ввести в ступор начинающего пользователя, тем не менее, нам нужен пункт "Создать рабочую копию".&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Внесение изменений&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;После внесения локальных изменений (непосредственно программирования) у нас есть два пути.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;&lt;b&gt;Путь первый.&lt;/b&gt; Если ваши локальные изменения невелики, то вы можете их сразу отправить в хранилище, также как это делает Subversion. Для этого сначала обновляем нашу рабочую копию до последней ревизии находящейся в хранилище:&lt;br /&gt;
&lt;/div&gt;&lt;pre&gt;bzr update
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Обратите внимание что слияние ваших изменений и новых ревизий из хранилища произойдет автоматически, без дополнительного bzr merge, что в большинстве случаев является оправданным при правильном распределении задач между разработчиками, иначе придется редактировать конфликты.&lt;br /&gt;
&lt;br /&gt;
И фиксируем наши изменения в хранилище:&lt;br /&gt;
&lt;/div&gt;&lt;pre&gt;bzr qcommit
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Путь второй.&lt;/b&gt; Если же ваши изменения более значительны и разработка займет какое-то время, что обычно и бывает, то в процесс разработки добавляется новая команда фиксации промежуточных локальных изменений:&lt;br /&gt;
&lt;/div&gt;&lt;pre&gt;bzr qcommit --local
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;либо через контекстное меню 'Bazaar Commit…' и выбором пункта 'Локальная фиксация'&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_xbBcXgfHrHY/S0siXo6sYkI/AAAAAAAAACk/f5gmD4zxw2M/s1600-h/qci-local.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_xbBcXgfHrHY/S0siXo6sYkI/AAAAAAAAACk/f5gmD4zxw2M/s640/qci-local.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Команда выполняется столько раз, сколько требует логика разработчика, обычно стараются делать одно функциональное изменение = одна фиксация, но это уже из области best practice.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;После окончания разработки и последней локальной фиксации, действуем по схеме 1:&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
bzr update&lt;br /&gt;
&lt;br /&gt;
И вот тут происходит самое интересное, запустите:&lt;br /&gt;
&lt;br /&gt;
bzr qlog&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_xbBcXgfHrHY/S0sjzSjYlgI/AAAAAAAAACs/jdBA7cb6LwM/s1600-h/qlog-pending-local-ci.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_xbBcXgfHrHY/S0sjzSjYlgI/AAAAAAAAACs/jdBA7cb6LwM/s640/qlog-pending-local-ci.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;и вы увидите, что все локальные фиксации ответвились от основной линии, как будто вы вели разработку в отдельной ветке и теперь хотите ее объединить с основным деревом, статус pending merge что нам и нужно.&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Тестируем наши объединенные изменения и если все нормально фиксируем в хранилище:&lt;br /&gt;
&lt;br /&gt;
bzr qcommit&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Причем теперь вместо списка измененных файлов вам покажут список ваших локальных фиксаций, что очень удобно для написания хорошего комментария.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Как отменить merge сделанное в результате bzr update&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Хочу предупредить, если после update у вас что-то пошло не так или вы просто передумали объединять ваши изменения, то не спешите использовать команду revert. Эта команда отменит неоконченное объединение и ваши изменения. Ваши локальные ревизии никуда не исчезнут, они останутся в хранилище истории локального дерева файлов. Но вы не вернетесь к своей локальной истории, а напротив останетесь с историей из основной ветки.&lt;br /&gt;
&lt;br /&gt;
Для возвращения к локальной истории вам необходимо узнать идентификатор последней ревизии в вашей локальной истории. Проще всего это сделать при помощи GUI команды qlog, но можно и воспользоваться командой heads из плагина bzrtools.&lt;br /&gt;
&lt;br /&gt;
В случае использования qlog выделите ревизию, помеченую ярлыком Pending Merge и затем в нижнем левом окне в первой строке с версией найдите подстроку вида revid:xxxx, в нашем примере это revid:_-20100111130959-gd9bfn7z2mxxixx3. Выделите ее мышкой и скопируйте в буфер обмена.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_xbBcXgfHrHY/S1CKb0ODP4I/AAAAAAAAAC0/z6OuHIMMOEo/s1600-h/qlog-pending-revid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_xbBcXgfHrHY/S1CKb0ODP4I/AAAAAAAAAC0/z6OuHIMMOEo/s640/qlog-pending-revid.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Затем закройте qlog и выполните следующие команды:&lt;br /&gt;
&lt;/div&gt;&lt;pre&gt;bzr revert
bzr unbind 
bzr pull . --overwrite -r revid:_-20100111130959-gd9bfn7z2mxxixx3
bzr bind 
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;Команде pull вы должны передать идентификатор ревизии локальной истории, тот самый, который мы скопировали из окна qlog.&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Идентификатор ревизии локальной истории можно также получить при помощи команды heads из плагина bzrtools. Для этого запустите следующую команду:&lt;br /&gt;
&lt;/div&gt;&lt;pre&gt;bzr heads --dead-only
&lt;/pre&gt;В ответ она выведет информацию следующего вида:&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\Centralised\trunk&amp;gt;bzr heads --dead
HEAD: revision-id: _-20100111130959-gd9bfn7z2mxxixx3 (dead)
&amp;nbsp; committer: Базарный день
&amp;nbsp; branch nick: trunk
&amp;nbsp; timestamp: Mon 2010-01-11 15:09:59 +0200
&amp;nbsp; message:
&amp;nbsp;&amp;nbsp;&amp;nbsp; локальная фиксация №2
&lt;/pre&gt;&lt;div style="text-align: justify;"&gt;В строке "HEAD: revision-id:" показан нужный нам идентификатор. Опять же копируем его и запускаем те же действия:&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;pre&gt;bzr revert
bzr unbind 
bzr pull . --overwrite -r revid:_-20100111130959-gd9bfn7z2mxxixx3
bzr bind 
&lt;/pre&gt;&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Даже если вы сделали revert до того, как посмотрели идентификатор локальной ревизии через qlog — не паникуйте, а используйте второй способ с командой heads.&lt;br /&gt;
&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;Замечание редакции:&lt;/i&gt; если вы используете локальные фиксации, то перед выполнением команды bzr update убедитесь, что все ваши изменения зафиксированы командой commit, либо отложены "на полочку" командой shelve. Иначе вы их легко потеряете при выполнении команды revert. Однако, вместо локальных фиксацией всё-таки более безопасно использовать либо отдельную ветку либо отдельную рабочую копию. &lt;br /&gt;
&lt;/blockquote&gt;&lt;h2&gt;Заключение&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Итак, если вы до этого пользовались Subversion и хотите получить небольшой fun от использования системы контроля версий, то смело переходите на Bazaar. Если при этом вам захочется большего, я имею ввиду полный контроль над ветками, то Bazaar умеет и так работать, при этом не придется ломать уже налаженный стиль работы остальных. В общем Bazaar это настоящий швейцарский нож для разработчика с весьма дружественным интерфейсом.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-2771139047305419480?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/2771139047305419480/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2010/01/blog-post.html#comment-form' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2771139047305419480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2771139047305419480'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2010/01/blog-post.html' title='Работа с bzr в централизованном стиле'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_xbBcXgfHrHY/S0sgNqfejFI/AAAAAAAAACc/9iyRUnXKF2g/s72-c/qgetnew.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-9071616211762611795</id><published>2009-12-13T15:01:00.005Z</published><updated>2009-12-14T04:53:20.406Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='концепции'/><category scheme='http://www.blogger.com/atom/ns#' term='особенности'/><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Модель "одна ветка = один каталог" в bzr</title><content type='html'>&lt;h2&gt;Немного истории&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Современная система контроля версий Bazaar имеет свои корни в другой распределенной системе: &lt;a href="http://www.gnu.org/software/gnu-arch/"&gt;GNU Arch&lt;/a&gt;. У системы Arch было несколько форков (разновидностей), одни из которых также назывался Bazaar (&lt;a href="http://en.wikipedia.org/wiki/Bazaar_%28software%29#Baz:_an_earlier_Canonical_Ltd_version_control_system"&gt;baz&lt;/a&gt;). Arch критиковали за излишнюю сложность интерфейса и трудность в освоении. Собственно современный Bazaar (bzr) появился как замена старому baz, и главной целью разработки нового bzr было именно упростить интерфейс пользователя системы, сделать систему удобной и лёгкой в использовании.&lt;br /&gt;
&lt;br /&gt;
По большей части новый bzr добился своей цели (удобства использования). Однако при этом некоторые особенности модели системы Arch перекочевали в том или ином виде в новый Bazaar (bzr). И это накладывает свой отпечаток на работу самой системы и на работу пользователей с системой.&lt;br /&gt;
&lt;br /&gt;
Следует заметить, что старый baz и новый bzr — обе эти системы разрабатывались и разрабатываются в основном за счет финансовой помощи компании &lt;a href="http://www.canonical.com/"&gt;Canonical Ltd&lt;/a&gt;, широко известной благодаря своему дистрибутиву Linux: &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Также следует отметить, что разработка нового bzr была задумана в ноябре 2004 года и официально началась в февраля 2005 года, на несколько месяцев ранее начала работ над git и hg. До первой половины 2006 года bzr развивался совершенно самостоятельно, как продолжатель baz. После стали очевидны успехи новых систем git и hg, особенно в плане показателей скорости, в результате чего внутренние алгоритмы bzr и форматы хранения данных в репозитории стали постепенно оптимизировать и улучшать в плане скорости работы. Однако несколько фундаментальных особенностей, унаследованных из baz/Arch, остались и до сегодняшнего дня. Понимание этих особенностей поможет вам более эффективно использовать bzr.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Унаследованные особенности&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Основные особенности, унаследованные из Arch:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;модель "каждая ветка живет в отдельном каталоге",&lt;/li&gt;
&lt;li&gt;доступ к веткам возможен без специального сервера,&lt;/li&gt;
&lt;li&gt;использование уникальных идентификаторов для файлов внутри системы.&lt;/li&gt;
&lt;/ul&gt;Об уникальных идентификаторах файлов мы поговорим в другой статье, сейчас же рассказ пойдёт о модели "ветка=каталог", о её достоинствах и недостатках.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Каждая ветка живет в отдельном каталоге&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Основная модель работы с ветками в bzr — это размещение каждой ветки в отдельном каталоге. У такого метода есть ряд плюсов и ряд минусов.&lt;br /&gt;
&lt;br /&gt;
К плюсам можно отнести следующее. Каждая ветка однозначно присутствует как объект файловой системы, поэтому с ней можно оперировать средствами самой файловой системы, т.е. переименовывать, перемещать или удалять. Каждая ветка однозначно идентифицируется своим расположением, поэтому для доступа к ней достаточно использовать простой путь (для локального доступа) либо URL (для удаленного доступа), т.е. нет необходимости указывать URL + собственно имя ветки. Присутствие одной ветки в одном месте позволяет эффективно реализовать идею &lt;a href="http://bzr-day.blogspot.com/2009/11/mainline-3.html"&gt;mainline&lt;/a&gt;. Каждая ветка хранит полную копию истории и полный набор рабочих файлов, что позволяет легко сравнивать и одновременно работать с несколькими ветками, которые содержат незафиксированные изменения.&lt;br /&gt;
&lt;br /&gt;
К минусам относится то, что каждая ветка хранит полную копию истории и полный набор рабочих файлов. Как следствие для каждой ветки требуется больше места на диске и операция создания новой ветки требует много времени, что существенно для веток с огромной историей. Также разные рабочие копии требуют полной перекомпиляции кода проекта для каждой ветки, в случае же совместного использования одной рабочей копии многими ветками эта проблема не стоит.&lt;br /&gt;
&lt;br /&gt;
Как вы могли заметить, я отнес один и тот же факт (каждая ветка хранит полную копию истории и полный набор рабочих файлов) и к плюсам и к минусам. На самом деле является ли это плюсом или минусом будет зависеть от конкретного проекта и того, как удобнее работать разработчикам.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим внимательно минусы. Они известны давно и для их нивелирования существует ряд методик эффективного использования bzr. Все указанные проблемы (каждая ветка занимает много места, долгое создание новой ветки, разделение одной рабочей копии) эффективно решаются при использовании разделяемого (или общего) репозитория (shared repository). Таким образом указанные минусы нивелируются использованием shared repository и остается лишь маленький недостаток: по умолчанию разделяемый репозиторий не создается сам по себе, его нужно создавать явно, командой &lt;tt&gt;init-repository&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
Будем предельно честными: bzr &lt;i&gt;позволяет эффективно работать&lt;/i&gt; с ветками, но &lt;i&gt;по умолчани&lt;/i&gt;ю создает обычные ветки. Это недостаток, который особенно сильно влияет на &lt;i&gt;восприятие&lt;/i&gt; системы новичками, пришедших в bzr из других систем (git/hg), в которых всегда ветки живут в едином каталоге и представляют собой лишь &lt;i&gt;виртуальные&lt;/i&gt; имена для разных линий истории проекта.&lt;br /&gt;
&lt;br /&gt;
Из-за непонимания этого факта bzr много и не всегда оправданно критикуют.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Эффективное использование bzr: разделяемые репозитории&lt;/h2&gt;&lt;h3&gt;Что такое разделяемый репозиторий (shared repository)?&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Для того, чтобы понять, что такое &lt;i&gt;shared repository&lt;/i&gt; (разделяемый или общий репозиторий), сначала рассмотрим внутреннее устройство bzr-ветки. Каждая ветка содержит указатель на последнюю зафиксированную ревизию, что однозначно определяет всю историю ветки, поскольку история имеет вид направленного графа. Каждая ветка должна иметь репозиторий, в котором хранятся зафиксированные ревизии и состояние всех файлов ветки для каждой ревизии. Также ветка может иметь рабочую копию (а может и не иметь).&lt;br /&gt;
&lt;br /&gt;
Для обычных веток репозиторий находится в том же каталоге, что и сама ветка. Однако это не обязательно. Репозиторий может находиться и за пределами каталога с веткой, в одном из родительских каталогов. Такой отдельный репозиторий может хранить зафиксированные ревизии и состояния файлов для нескольких веток, находящихся внутри репозитория. А поскольку история веток по большей части совпадает, то в результате место расходуется гораздо более экономно, чем в случае когда каждая ветка хранит полную копию всего репозитория. Каждая ветка, создаваемая внутри разделяемого репозитория, автоматически находит и начинает использовать этот репозиторий.&lt;br /&gt;
&lt;br /&gt;
Поэтому такой репозиторий (shared repository) является общим для нескольких веток, либо можно сказать, что несколько веток разделяют (совместно используют) один и тот же репозиторий.&lt;br /&gt;
&lt;br /&gt;
Следует запомнить фундаментальную разницу между ветками и репозиториями в bzr и репозиториями в git/hg. В bzr под репозиторием в большинстве случае понимают именно разделяемый репозиторий, каждая ветка внутри него — это отдельный каталог. В git/hg в одном каталоге живет и репозиторий, и ветки, и присутствует рабочая копия.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Локальная работа с ветками в репозитории&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Для локальной работы рекомендуется создавать разделяемый репозиторий командой:&lt;br /&gt;
&lt;pre&gt;bzr init-repo PATH
&lt;/pre&gt;После чего создавать копию главной ветки с сервера внутри репозитория:&lt;br /&gt;
&lt;pre&gt;cd PATH
bzr branch bzr://server/project/trunk
&lt;/pre&gt;А уже для конкретной работы над новыми функциями создавать новую ветку на основе локальной копии trunk:&lt;br /&gt;
&lt;pre&gt;bzr branch trunk new-feature
cd new-feature
&lt;/pre&gt;При такой работе каждая ветка будет иметь собственную рабочую копию, что позволит легко переходить между разными ветками и объединять изменения между ними. Такая методика работы подробно описывалась в наших предыдущих статьях (базовый набор команд и работа с ветками, см. &lt;a href="http://bzr-day.blogspot.com/2009/11/blog-post_26.html"&gt;оглавление&lt;/a&gt;).&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Использование репозитория на сервере&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Для хранения веток на сервере также полезно использовать разделяемые репозитории. Но зачастую сервер выступает просто хранилищем ревизий, поэтому рабочие копии для веток создавать не требуется. Это достигается командой:&lt;br /&gt;
&lt;pre&gt;bzr init-repo --no-trees URL
&lt;/pre&gt;Опция командой строки &lt;tt&gt;--no-trees&lt;/tt&gt; указывает, что по умолчанию рабочая копия для веток создаваться не будет.&lt;br /&gt;
&lt;br /&gt;
Остальные операции с ветками можно производить как обычно.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Разделение одной рабочей копии между несколькими ветками&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Как уже упоминалось выше в git/hg по умолчанию несколько веток живут в одном каталоге, который называют репозиторий, и в этом же каталоге присутствует рабочая копия, которую совместно используют все ветки. В каждый конкретный момент рабочая копия отражает состояние &lt;i&gt;только&lt;/i&gt; текущей активной ветки. Будем называть такую модель работы "git-стиль".&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что по умолчанию bzr использует другой стиль, однако мы может использовать и git-стиль, если так удобнее.&lt;br /&gt;
&lt;br /&gt;
Для этого нужно создать отдельный репозиторий с указанием флага --no-trees, чтобы локальные ветки в этом репозитории не создавали ненужные рабочие копии. А затем нужно создать отдельную легковесную рабочую копию (lightweight checkout), не содержащую истории. Такая легковесная рабочая копия может быть создана даже за пределами репозитория.&lt;br /&gt;
&lt;pre&gt;bzr init-repo --no-trees PROJECT
bzr init PROJECT/trunk
bzr checkout --lightweight PROJECT/trunk work
&lt;/pre&gt;В результате выполнения этой последовательности команд bzr создаст репозиторий в каталоге PROJECT, внутри репозитория создаст ветку trunk, и затем создаст рабочую копию в каталоге work.&lt;br /&gt;
&lt;br /&gt;
Для создания новой ветки и одновременного переключения рабочей копии на нее можно использовать команду:&lt;br /&gt;
&lt;pre&gt;bzr branch --switch trunk new-feature
&lt;/pre&gt;Переключение рабочей копии между ветками осуществляется командой &lt;tt&gt;switch&lt;/tt&gt;:&lt;br /&gt;
&lt;pre&gt;bzr switch trunk
&lt;/pre&gt;При переключении можно указать опцию &lt;tt&gt;--create-branch&lt;/tt&gt; (&lt;tt&gt;-b&lt;/tt&gt;), чтобы автоматически создать новую ветку:&lt;br /&gt;
&lt;pre&gt;bzr switch -b bugfix-123
&lt;/pre&gt;Для получения списка веток в репозитории используйте команду:&lt;br /&gt;
&lt;pre&gt;bzr branches PROJECT
&lt;/pre&gt;из плагина bzrtools.&lt;br /&gt;
&lt;br /&gt;
Более подробный рассказ о нюансах работы с bzr в git-стиле будет дан в виде отдельной статьи.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Заключение&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;В этой статье я попытался описать как и почему в bzr используется модель "одна ветка в одном каталоге", привести доводы за и против такого подхода, а также показать пути эффективного использования bzr.  &lt;br /&gt;
&lt;br /&gt;
Как вы могли убедиться, bzr — это очень гибкая система, и она позволяет достичь намного большего при умелом использовании. Однако требует несколько большего времени на освоение.  &lt;br /&gt;
&lt;br /&gt;
Недостатком можно назвать лишь то, что по умолчанию bzr работает в не самом оптимальном режиме, поэтому для достижения эффективности требуется сделать несколько больше телодвижений. Следует ли это считать смертельным недостатком? Уверен, что нет. &lt;br /&gt;
&lt;br /&gt;
Впрочем, каждому решать самому.  Помните лишь, что каждая из современных распределенных систем (git/hg/bzr) имеет как достоинства, так и недостатки. Однако очень часто значимость как плюсов, так и минусов, не абсолютна, а относительна, и зависит от конкретного проекта и предпочитаемого стиля работы. И часто одни недостатки компенсируются другими достоинствами.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-9071616211762611795?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/9071616211762611795/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr_13.html#comment-form' title='Комментарии: 7'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/9071616211762611795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/9071616211762611795'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr_13.html' title='Модель &quot;одна ветка = один каталог&quot; в bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-1102626717602580623</id><published>2009-12-11T12:22:00.004Z</published><updated>2010-03-23T17:12:03.316Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><title type='text'>Уборка мусора: команда bzr clean-tree</title><content type='html'>&lt;div style="text-align: justify;"&gt;Часто во время работы над некоторыми функциями в рабочем каталоге оседают какие-то дополнительные материалы, тестовые данные или скрипты. Всё, что относится к текущей работе и может быть безболезненно выброшено потом. Такие данные могут быть добавлены в список игнорируемых файлов, а могут и не быть, поскольку носят временный характер.&lt;br /&gt;
&lt;br /&gt;
И вот когда приходит время удалять это барахло, что вы делаете? Удаляете вручную?&lt;br /&gt;
&lt;br /&gt;
Есть более удобный способ: использовать команду &lt;b&gt;clean-tree&lt;/b&gt; (начиная с версии bzr 1.13 эта команда доступна в самом bzr, ранее эта команда жила в плагине &lt;a href="https://launchpad.net/bzrtools"&gt;bzrtools&lt;/a&gt;). Эта команда показывает вам список неизвестных (неверсионированных) файлов и предлагает их удалить. Просто и без затей.&lt;br /&gt;
&lt;br /&gt;
Также эта команда имеет удобный ключ командной строки: &lt;tt&gt;--ignored&lt;/tt&gt;. С этим ключом &lt;tt&gt;clean-tree&lt;/tt&gt; будет удалять только игнорируемые файлы. Такая функция тоже бывает полезной, особенно если у вас нет &lt;tt&gt;make clean&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
Приятной уборки!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-1102626717602580623?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/1102626717602580623/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr-clean-tree-bzrtools.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1102626717602580623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1102626717602580623'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr-clean-tree-bzrtools.html' title='Уборка мусора: команда bzr clean-tree'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5391584862501748441</id><published>2009-12-08T07:36:00.001Z</published><updated>2009-12-08T07:38:30.021Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><category scheme='http://www.blogger.com/atom/ns#' term='qbzr'/><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><title type='text'>Управление кодировкой файла при работе с QBzr (GUI для bzr)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="https://launchpad.net/qbzr"&gt;QBzr&lt;/a&gt; — это кросс-платформенный GUI плагин для bzr, использующий библиотеку Qt4/PyQt4. Мы рассмотрим вопрос управления кодировкой файлов для их корректного отображения в окнах QBzr.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;QBzr и кодировки&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Поскольку [Py]Qt4 ориентирована на использование unicode для отображения текстовых данных, то возникает небольшая проблема с файлами, содержащими неанглийские тексты (например, русский или японский). Для корректного отображения таких текстов QBzr необходимо знать кодировку, в которой был сохранен текст.&lt;br /&gt;
&lt;br /&gt;
По умолчанию, QBzr предполагает, что текст имеет кодировку UTF-8 (с автоматическим переключением на Latin-1, если текст невозможно отобразить как UTF-8). Кодировка UTF-8 довольно популярна и используется на многих современных дистрибутивах Linux и Mac. Однако на Windows часто используется кодировка ANSI (например, cp1251 для русского текста), а на старых платформах — исторически сложившиеся кодировки (например, koi8-r для русского текста). Поэтому некоторым пользователям приходится указывать кодировку вручную одним из 3х способов:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;указать кодировку в командной строке&lt;/li&gt;
&lt;li&gt;указать кодировку в конфигурационном файле&lt;/li&gt;
&lt;li&gt;указать кодировку непосредственно в диалоговом окне с отображаемым текстом&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;Рассмотрим эти методы подробнее.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Опция командной строки&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Большинство команд, непосредственно отображающих содержимое файлов, таких как qdiff, qannotate, qcat и qviewer, имеют опцию командной строки &lt;tt&gt;--encoding&lt;/tt&gt;. Эта опция позволяет напрямую задать кодировку файла из набора поддерживаемых библиотеками Python (&lt;a href="http://docs.python.org/library/codecs.html#standard-encodings"&gt;полный список&lt;/a&gt;). Часто используемые кодировки для русского языка:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;cp1251 (Windows ANSI)&lt;/li&gt;
&lt;li&gt;cp866 (DOS/OEM)&lt;/li&gt;
&lt;li&gt;koi8-r (Unix)&lt;/li&gt;
&lt;/ul&gt;Для украинского языка аналогично: cp1251, cp866, koi8-u.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Настройки в конфигурационном файле&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Кодировка, указанная опцией &lt;tt&gt;--encoding&lt;/tt&gt;, либо выбранная непосредственно (см. ниже), сохраняется в конфигурационном файле текущей ветки (файл .bzr/branch/branch.conf) как опция:&lt;br /&gt;
&lt;pre&gt;encodng = xxx
&lt;/pre&gt;Сохраненная кодировка будет использоваться по умолчанию при следующем запуске соответствующей команды QBzr.&lt;br /&gt;
&lt;br /&gt;
Если вы постоянно работаете с одной и той же кодировкой (например, cp1251), то ее можно указать как кодировку по умолчанию для всех веток, прописав в &lt;a href="http://doc.bazaar-vcs.org/latest/en/user-reference/index.html#the-main-configuration-file-bazaar-conf"&gt;главном конфигурационном файле bazaar.conf&lt;/a&gt;:&lt;br /&gt;
&lt;pre&gt;[DEFAULT]
email = Vasya Pupkin &amp;lt;vasya@pupkin.ru&amp;gt;
encoding = cp1251
&lt;/vasya@pupkin.ru&gt;&lt;/pre&gt;Более тонкой настройки можно добиться при использовании &lt;a href="http://doc.bazaar-vcs.org/latest/en/user-reference/index.html#the-branch-location-configuration-file-locations-conf"&gt;конфигурационного файла locations.conf&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Эти настройки будут использоваться для отображения всех файлов. К сожалению, по состоянию на декабрь 2009, bzr и qbzr не имеют возможности сохранять выборочные настройки для отдельных файлов. Однако, такая функциональность может появиться в будущем.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Непосредственное управление&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Благодаря Наоки Инада (&lt;a href="https://launchpad.net/%7Esongofacandy"&gt;Naoki INADA&lt;/a&gt;) в QBzr 0.17 появилась возможность управлять кодировкой файла прямо из соответствующих диалоговых окон. В окнах для отображения diff, annotate, cat появился элемент (выпадающий список), позволяющий выбрать нужную кодировку. Это очень полезное улучшение, особенно для пользователей TortoiseBzr и Bazaar Explorer, поскольку эти программы никак не передают данные о кодировках в диалоговые окна QBzr.&lt;br /&gt;
&lt;br /&gt;
Diff:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_xbBcXgfHrHY/Sx3__p5DcmI/AAAAAAAAAB4/khIy0RKi-6c/s1600-h/qdiff.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_xbBcXgfHrHY/Sx3__p5DcmI/AAAAAAAAAB4/khIy0RKi-6c/s320/qdiff.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xbBcXgfHrHY/Sx4AK8XyxBI/AAAAAAAAACA/1UIRMnPP79E/s1600-h/qdiff-encoding-selector1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_xbBcXgfHrHY/Sx4AK8XyxBI/AAAAAAAAACA/1UIRMnPP79E/s640/qdiff-encoding-selector1.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Annotate:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_xbBcXgfHrHY/Sx4AjaB95NI/AAAAAAAAACI/8dalz956fdw/s1600-h/qannotate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_xbBcXgfHrHY/Sx4AjaB95NI/AAAAAAAAACI/8dalz956fdw/s320/qannotate.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_xbBcXgfHrHY/Sx4AnxwmlTI/AAAAAAAAACQ/zmA2LQZ2Iwk/s1600-h/qannotate-encoding-selector.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_xbBcXgfHrHY/Sx4AnxwmlTI/AAAAAAAAACQ/zmA2LQZ2Iwk/s320/qannotate-encoding-selector.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Выбранная вами кодировка также сохраняется в конфигурационном файле branch.conf для вашей ветки, и будет использована при последующих запусках QBzr в этой ветке.&lt;br /&gt;
&lt;br /&gt;
Новая версия QBzr 0.17 с показанным элементом выбора кодировок будет выпущена в середине декабря 2009. Однако уже сейчас эти улучшения доступны в ветке &lt;a href="https://code.launchpad.net/%7Eqbzr-dev/qbzr/trunk2a"&gt;trunk2a&lt;/a&gt;.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5391584862501748441?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5391584862501748441/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/12/qbzr-gui-bzr.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5391584862501748441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5391584862501748441'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/12/qbzr-gui-bzr.html' title='Управление кодировкой файла при работе с QBzr (GUI для bzr)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_xbBcXgfHrHY/Sx3__p5DcmI/AAAAAAAAAB4/khIy0RKi-6c/s72-c/qdiff.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-3904218033588778959</id><published>2009-12-04T00:00:00.008Z</published><updated>2009-12-04T00:00:00.639Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><title type='text'>Строгий контроль со стороны bzr</title><content type='html'>&lt;div style="text-align: justify;"&gt;Хороший инструмент не только помогает нам выполнить работу качественно, но и помогает предотвратить ошибки, обусловленные человеческим фактором. Рассмотрим пару примеров, когда bzr &lt;i&gt;может&lt;/i&gt; помочь вам избежать таких ошибок.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Ситуация&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;&lt;blockquote&gt;Итак, за окном поздний вечер, завтра надо отдавать проект заказчику, а буквально полчаса назад был обнаружен непонятный дефект, который обязательно нужно победить сегодня.&amp;nbsp; Очень хочется домой, кушать и спать. Но вы знаете, что надо.&lt;br /&gt;
&lt;br /&gt;
Собрав всю волю в кулак, вы находите подозрительные места, дорабатываете код, добавляете новый модуль, фиксируете изменения, запускаете, проверяете и ура? Нет, снова что-то не так... ах вот же она опечатка. Последние изменения, всё работает. И вы запускаете команду &lt;tt&gt;bzr push&lt;/tt&gt; и передаете свою работу на сервер.&lt;br /&gt;
&lt;br /&gt;
Со спокойной душой уходите с работы, а рано утром вам уже звонят коллеги/начальство и очень обеспокоенно спрашивают зачем и что вы там сломали вчера и почему в главном репозитории неработоспособная версия. Как же так, ведь все же работало?&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Описанная ситуация псевдоправдоподобная, наверняка что-то из подобного когда-то случалось со многими. Попробуем разобраться с ситуацией, типичными ошибками, которые обусловлены человеческим фактором, и чем может помочь bzr для предотвращения таких инцидентов.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Ошибка №1: забыли добавить новые модули под контроль версий&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Достаточно частая ситуация, когда фиксируются изменения в коде старых файлов и при этом забывают добавить новые файлы под контроль версий командой &lt;tt&gt;bzr add&lt;/tt&gt;. В результате зафиксированное состояние дерева файлов и реальный набор файлов в рабочем каталоге будут отличаться. Что приведет к частичной или полной неработоспособности вашего кода.&lt;br /&gt;
&lt;br /&gt;
В большинстве случаев подобного рода ошибки можно поймать внимательным просмотром вывода команд &lt;tt&gt;bzr status&lt;/tt&gt; (до и/или после фиксации) и &lt;tt&gt;bzr diff&lt;/tt&gt;. Но в пылу сражения может случиться всякое, особенно если вы фиксируете только часть изменений.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;commit --strict&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;В таких ситуациях bzr может помочь если вы будете использовать опцию &lt;tt&gt;--strict&lt;/tt&gt; для команды &lt;tt&gt;commit&lt;/tt&gt;. Данная опция делает невозможным успешную фиксацию, если в рабочем каталоге присутствуют неизвестные файлы, которые не помещены под контроль версий командой add, и не соответствуют маскам игнорируемых файлов.&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\strict&gt;bzr ci --strict -m foo
Committing to: C:/work/bzr-day/strict/
aborting commit write group: StrictCommitFailed()
bzr: ERROR: Commit refused because there are unknown files in the working tree.
&lt;/pre&gt;При использовании &lt;a href="http://bzr-day.blogspot.com/2009/11/bzr-aliases.html"&gt;пользовательских псевдонимов&lt;/a&gt; вы можете включить эту опцию по умолчанию:&lt;br /&gt;
&lt;pre&gt;bzr alias commit="commit --strict"
bzr alias ci="commit --strict"
&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;Ошибка №2: последние изменения не зафиксированы, push передает на сервер неокончательный код&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;С этой ситуацией более-менее понятно. Push работает на уровне зафиксированной истории ветки, поэтому состояние рабочих файлов для него проверять не обязательно.&lt;br /&gt;
&lt;br /&gt;
Опять же внимательный просмотр вывода команды &lt;tt&gt;bzr status&lt;/tt&gt; поможет поймать такого рода ошибки.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;push --strict&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;К счастью, начиная с версии bzr 1.17 команда &lt;tt&gt;push&lt;/tt&gt; автоматически проверяет рабочее дерево файлов на наличие незафиксированных изменений, включая неоконченное объединение. И отказывается работать, если таковые обнаружатся:&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\strict&gt;bzr push ../foo
bzr: ERROR: Working tree "C:/work/bzr-day/strict/" has uncommitted changes (See bzr status). Use --no-strict to force the push.
&lt;/pre&gt;Как видно, эту проверку можно отключать, указывая опцию &lt;tt&gt;--no-strict&lt;/tt&gt;.&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;push --no-strict&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Если подобная проверка вам почему-то не по душе, то не спешите заводить новый пользовательский псевдоним для команды push, а используйте опцию &lt;tt&gt;push_strict&lt;/tt&gt; в файле конфигурации bazaar.conf или branch.conf. Например:&lt;br /&gt;
&lt;pre&gt;push_strict = False
&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;Заключение&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Мы рассмотрели две встроенные функции bzr для контроля и предотвращения некоторых распространенных ошибок при выполнении операций commit и push. Как указывалось, такие ошибки можно отловить при внимательном анализе вывода команды status. Но в том-то и дело, что подобные ошибки случаются когда смотрят не внимательно или не смотрят вообще.&lt;br /&gt;
&lt;br /&gt;
Дополнительные проверки, специфичные для конкретного проекта, можно осуществлять через функции-хуки, например хуки для событий pre_commit или pre_change_branch_tip. В качестве примера pre_commt хука см. плагин &lt;a href="https://code.launchpad.net/~bialix/+junk/checkeol"&gt;checkeol&lt;/a&gt;, который может осуществлять проверку концовок строк в фиксируемых файлах.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-3904218033588778959?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/3904218033588778959/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3904218033588778959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3904218033588778959'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr.html' title='Строгий контроль со стороны bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-498700053058093890</id><published>2009-12-02T22:20:00.000Z</published><updated>2009-12-02T22:20:58.292Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='блоги'/><title type='text'>Статьи про bzr  в блоге Kash Farooq</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://kashfarooq.wordpress.com/"&gt;Kash Farooq&lt;/a&gt; (Каш Фарук), .NET разработчик из Великобритании, опубликовал в своем блоге &lt;a href="http://kashfarooq.wordpress.com/category/bazaar-source-control"&gt;ряд статей про bzr&lt;/a&gt;.&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Затрагиваемые темы: работа с Subversion при помощи плагина bzr-svn, описания настроек внешних GUI утилит для объединения изменений и решения конфликтов, операции объединения и переименования в bzr.&lt;br /&gt;
&lt;/div&gt;__________________&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;Я считаю, что будет полезным делать обзоры и маленькую рекламу блогам, которые более-менее регулярно пишут про работу с bzr (чуть по более, чем заметка в стиле "я вчера поставил bzr и мне понравилось").&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Если вы знаете такие блоги или сами регулярно публикуете материалы на эту тему, то оставляйте ссылки в комментариях либо присылайте электропочтой.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-498700053058093890?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/498700053058093890/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr-kash-farooq.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/498700053058093890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/498700053058093890'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/12/bzr-kash-farooq.html' title='Статьи про bzr  в блоге Kash Farooq'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-6395274663792294718</id><published>2009-11-30T00:00:00.007Z</published><updated>2009-12-22T13:05:28.252Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='настройки'/><title type='text'>Пользовательские псевдонимы команд bzr (aliases)</title><content type='html'>&lt;div style="text-align: justify;"&gt;Bazaar имеет весьма интересную и полезную функцию тонкого тюнинга: поддержку для определяемых пользователем псевдонимов для команд (&lt;i&gt;aliases&lt;/i&gt;). Псевдонимы позволяют&amp;nbsp; определять команды с нужными опциями и параметрами по умолчанию, и даже переопределять встроенные команды. При умелом использовании псевдонимы могут значительно упростить повседневное использование bzr из командной строки.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Отличие пользовательских псевдонимов от встроенных псевдонимов команд&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Большинство стандартных команд bzr и даже команд, добавляемых плагинами, имеют заранее предопределенный набор альтернативных имен (псевдонимов) для вызова этих команд. Так, команда &lt;tt&gt;commit&lt;/tt&gt; имеет псевдонимы &lt;tt&gt;ci&lt;/tt&gt; и &lt;tt&gt;checkin&lt;/tt&gt;, а &lt;tt&gt;status&lt;/tt&gt; — &lt;tt&gt;st&lt;/tt&gt; и &lt;tt&gt;stat&lt;/tt&gt;, и т.п. Эти псевдонимы выводятся при запросе справки на конкретную команду (&lt;tt&gt;bzr xxx --help&lt;/tt&gt; или &lt;tt&gt;bzr xxx --usage&lt;/tt&gt;).&lt;br /&gt;
&lt;br /&gt;
В отличие от таких альтернативных имен пользовательские псевдонимы позволяют определить не просто еще одно имя для вызова команды, а дополнительно указать какие-нибудь опции и аргументы. Таким образом при вызове команды через псевдоним, указанные опции и параметры будут подставляться по умолчанию. При этом у пользователя остается возможность переопределить такие дефолтные опции в командной строке.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Как работают пользовательские псевдонимы&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Пользователь может определить псевдоним, как некоторое имя, и связать с этим именем существующую команду bzr и дополнительно какие-то опции и параметры. Тогда при вызове команды как:&lt;br /&gt;
&lt;pre&gt;bzr имя_псевдонима [опции аргументы]
&lt;/pre&gt;вместо имени псевдонима будет подставляться значение псевдонима: определенная ранее реальная команда bzr + дополнительные параметры.&lt;br /&gt;
&lt;br /&gt;
При этом опции псевдонима могут переопределяться в конкретной командной строке: просто укажите новое значение и bzr будет использовать последнее определенное значение опции при запуске команды. Для отмены действия булевой опции используйте префикс &lt;tt&gt;no&lt;/tt&gt;, например: &lt;tt&gt;--short =&amp;gt; --no-short&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
У псевдонимов есть еще одно интересное свойство: вы можете в качестве имени псевдонима использовать имя существующей команды bzr. Это особенно полезно в тех случаях, когда вы хотите "навсегда" поменять поведение какой-то команды по умолчанию. Например, чтобы вывод команды &lt;tt&gt;status&lt;/tt&gt; имел компактный вид применяется опция &lt;tt&gt;--short&lt;/tt&gt; или &lt;tt&gt;-S&lt;/tt&gt;. Если вы предпочитаете всегда использовать такую форму вывода информации, то можете определить псевдоним&lt;br /&gt;
&lt;pre&gt;status = status --short
&lt;/pre&gt;Следует однако помнить, что все встроенные альтернативные имена команд (о которых упоминалось ранее) автоматически не переопределяются при переопределении команды. Поэтому если вы определили псевдоним для &lt;tt&gt;status&lt;/tt&gt; как описано выше, то запуск &lt;tt&gt;bzr st&lt;/tt&gt; будет производиться обычным (не переопределенным) способом.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Как определить свой псевдоним&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Определения пользовательских псевдонимов хранятся в файле bazaar.conf (&lt;tt&gt;~/.bazaar/bazaar.conf&lt;/tt&gt; на Linux и &lt;tt&gt;C:\Documents and Settings\USERNAME\Application Data\bazaar\2.0\bazaar.conf&lt;/tt&gt; на Windows) внутри секции &lt;tt&gt;[ALIASES]&lt;/tt&gt;. Определения псевдонимов имеют простую форму:&lt;br /&gt;
&lt;pre&gt;имя_псевдонима = имя_команды [опции]
&lt;/pre&gt;Для определения новых псевдонимов или редактирования старых вы можете как напрямую редактировать файл bazaar.conf, так и использовать встроенную команду &lt;tt&gt;alias&lt;/tt&gt;, либо воспользоваться GUI диалогами из плагинов QBzr (команда &lt;tt&gt;qconfig&lt;/tt&gt;) или bzr-gtk (команда &lt;tt&gt;gpreferences&lt;/tt&gt;).&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Использование команды bzr alias&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Запуск команды &lt;tt&gt;bzr alias&lt;/tt&gt; без параметров выведет список уже определенных вами псевдонимов.&lt;br /&gt;
&lt;br /&gt;
Для определения нового псевдонима используйте синтаксис:&lt;br /&gt;
&lt;pre&gt;bzr alias имя_псевдонима="значение"
&lt;/pre&gt;(Не забывайте использовать кавычки если значение псевдонима состоит из имени команды bzr и набора опций по умолчанию).&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;pre&gt;bzr alias st="status --short"
&lt;/pre&gt;&lt;br /&gt;
Для удаления ранее определенного псевдонима используйте опцию &lt;tt&gt;--remove&lt;/tt&gt;:&lt;br /&gt;
&lt;pre&gt;bzr alias st --remove
&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;Примеры псевдонимов&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;Кроме уже упомянутого ранее псевдонима для &lt;tt&gt;status --short&lt;/tt&gt; рассмотрим еще несколько примеров полезных псевдонимов.&lt;br /&gt;
&lt;br /&gt;
Получать вывод команды missing в формате в максимально сжатом виде (1 ревизия на строку):&lt;br /&gt;
&lt;pre&gt;miss = missing --line
&lt;/pre&gt;Получить список десяти последних ревизий в компактном виде:&lt;br /&gt;
&lt;pre&gt;last = log -l10 --short
&lt;/pre&gt;Вывод максимальной информации в аннотации файла:&lt;br /&gt;
&lt;pre&gt;ann = annotate --long
&lt;/pre&gt;Всегда удалять файлы из-под контроля bzr без удаления их с диска:&lt;br /&gt;
&lt;pre&gt;forget = remove --keep
&lt;/pre&gt;Матерые пользователи darcs могут захотеть определить псевдоним:&lt;br /&gt;
&lt;pre&gt;whatsnew = diff
&lt;/pre&gt;&lt;blockquote&gt;&lt;i&gt;Примечание:&lt;/i&gt; примеры выше даны в нотации, подходящей для помещения в конфигурационный файл &lt;tt&gt;bazaar.conf&lt;/tt&gt;. Для установки их в командной строке через команду &lt;tt&gt;bzr alias&lt;/tt&gt; используйте форму &lt;tt&gt;имя="команда опции"&lt;/tt&gt;.&lt;br /&gt;
&lt;/blockquote&gt;&lt;/div&gt;&lt;h3&gt;Вредные советы&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;bzr никак не проверяет смысл и содержание псевдонимов, поэтому вполне реально определить что-нибудь неожиданно деструктивное, например:&lt;br /&gt;
&lt;pre&gt;ci = revert --no-backup
&lt;/pre&gt;Я, впрочем, надеюсь наши читатели такими диверсиями заниматься не будут.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Временное отключение пользовательских псевдонимов&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Иногда может оказаться полезным отключить псевдонимы. Например, когда возникают непонятные ошибки.&lt;br /&gt;
&lt;br /&gt;
Глобальная опция &lt;tt&gt;--no-aliases&lt;/tt&gt;, заданная до имени команды, поможет вам в этом:&lt;br /&gt;
&lt;pre&gt;bzr --no-aliases xxx
&lt;/pre&gt;Совет: опции &lt;tt&gt;--no-plugins&lt;/tt&gt; и &lt;tt&gt;--no-aliases&lt;/tt&gt; целесообразно использовать при замерах скорости работы bzr.&lt;br /&gt;
&lt;/div&gt;&lt;h2&gt;Заключение&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Если у вас тоже есть парочка любимых псевдонимов, которые могут быть полезны другим, поделитесь ими в комментариях.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-6395274663792294718?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/6395274663792294718/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/11/bzr-aliases.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6395274663792294718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6395274663792294718'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/11/bzr-aliases.html' title='Пользовательские псевдонимы команд bzr (aliases)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4184462303245316290</id><published>2009-11-27T00:00:00.000Z</published><updated>2009-11-27T00:00:00.869Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='справка'/><title type='text'>Встроенная справочная служба bzr: получение списка аргументов и опций для команды</title><content type='html'>&lt;div style="text-align: justify;"&gt;У встроенной справки bzr на команды есть один маленький недостаток: при попытке получить справку для нетривиальной команды как правило на терминал выводится огромное описание возможностей команды и вариантов ее использования. При этом собственно информация о списке аргументов и опций команды выводится в самом начале текста справки, и чтобы увидеть этот список приходится пользоваться программами-пейджерами типа &lt;tt&gt;more&lt;/tt&gt; или &lt;tt&gt;less&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
К счастью в bzr версии 1.14 появилось очень удобное дополнение: при запуске команды с опцией &lt;tt&gt;--usage&lt;/tt&gt; на экран выводится краткая справка по команде, которая содержит только назначение команды (1 строка) и список аргументов и опций командной строки. Очень удобно, когда запамятовал как называется (правильно пишется) нужная опция.&lt;br /&gt;
&lt;br /&gt;
Сравните вывод &lt;tt&gt;bzr add --help&lt;/tt&gt; и &lt;tt&gt;bzr add --usage&lt;/tt&gt;:&lt;br /&gt;
&lt;pre&gt;C:\&gt;bzr add --usage
Purpose: Add specified files or directories.
Usage:   bzr add [FILE...]

Options:
  --dry-run            Show what would be done, but don't actually do
                       anything.
  -v, --verbose        Display more information.
  --file-ids-from=ARG  Lookup file ids from this tree.
  --no-recurse         Don't recursively add the contents of directories.
  -q, --quiet          Only display errors and warnings.
  --usage              Show usage message and options.
  -h, --help           Show help message.

See bzr help add for more details and examples.

See also: ignore, remove
&lt;/pre&gt;&lt;br /&gt;
Подробнее о встроенной справочной службе можно прочитать в статье "bzr help: встроенная справочная служба класса "люкс" (&lt;a href="http://bzr-day.blogspot.com/2009/02/bzr-help-1.html"&gt;Часть 1&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/03/bzr-help-2.html"&gt;Часть 2&lt;/a&gt;)"&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4184462303245316290?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4184462303245316290/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/11/bzr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4184462303245316290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4184462303245316290'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/11/bzr.html' title='Встроенная справочная служба bzr: получение списка аргументов и опций для команды'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-6430292026582218292</id><published>2009-11-26T21:38:00.009Z</published><updated>2010-02-07T13:56:35.714Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='оглавление'/><title type='text'>Список статей блога bzr-day</title><content type='html'>Список статей теперь находится на странице &lt;a href="http://bzr-day.blogspot.com/p/bzr-day.html"&gt;http://bzr-day.blogspot.com/p/bzr-day.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Общие сведения&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/02/bazaar.html"&gt;Bazaar: зачем и почему&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/02/bzr.html"&gt;Установка bzr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/09/bazaar-20.html"&gt;Bazaar 2.0 и новый формат репозитория по умолчанию&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/12/bzr_13.html"&gt;Модель "одна ветка = один каталог" в bzr&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;h3&gt;Концепции&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Mainline: главная линия разработки и номера ревизий (&lt;a href="http://bzr-day.blogspot.com/2009/09/mainline-1_08.html"&gt;Часть 1&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/09/mainline-2.html"&gt;Часть 2&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/11/mainline-3.html"&gt;Часть 3&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Настройки&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/02/bzr-whoami.html"&gt;Настройки bzr: whoami или как меня зовут&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/04/whoami-ssh.html"&gt;Автоматический whoami при работе через SSH&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/11/bzr-aliases.html"&gt;Пользовательские псевдонимы команд bzr (aliases)&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Справка по bzr&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;bzr help: встроенная справочная служба класса "люкс" (&lt;a href="http://bzr-day.blogspot.com/2009/02/bzr-help-1.html"&gt;Часть 1&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/03/bzr-help-2.html"&gt;Часть 2&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/11/bzr.html"&gt;Встроенная справочная служба bzr: получение списка аргументов и опций для команды&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Работа с bzr&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/03/bazaar.html"&gt;Исправление ошибок при работе с Bazaar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Начинаем работу с bzr: базовый набор команд (&lt;a href="http://bzr-day.blogspot.com/2009/03/bzr-1.html"&gt;Часть 1&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/03/bzr-2.html"&gt;Часть 2&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Работа с ветками: push, pull, merge (&lt;a href="http://bzr-day.blogspot.com/2009/03/push-pull-merge-1.html"&gt;Часть 1&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/03/push-pull-merge-2.html"&gt;Часть 2&lt;/a&gt;, &lt;a href="http://bzr-day.blogspot.com/2009/04/push-pull-merge-3.html"&gt;Часть 3&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2010/01/blog-post.html"&gt;Работа в централизованном стиле&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Рецепты&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/11/blog-post_25.html"&gt;Как добавить каталог без содержащихся в нём файлов?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/12/bzr.html"&gt;Строгий контроль со стороны bzr&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/12/bzr-clean-tree-bzrtools.html"&gt;Уборка мусора: команда bzr clean-tree (плагин bzrtools)&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Дополнительно&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/03/webdav-bazaar.html"&gt;Использование WebDAV для доступа к Bazaar-серверу&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Плагины&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/04/bzr.html"&gt;Плагины bzr: основые сведения&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/05/bzr.html"&gt;Разработка плагинов для bzr&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;bzr-svn&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/10/svn-bzr.html"&gt;Работа с svn из bzr&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/10/bazaar-subversion.html"&gt;Использование Bazaar для работы с Subversion-репозиториями&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;QBzr&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/12/qbzr-gui-bzr.html"&gt;Управление кодировкой файла при работе с QBzr (GUI для bzr)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Блоги&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://bzr-day.blogspot.com/2009/12/bzr-kash-farooq.html"&gt;Статьи про bzr  в блоге Kash Farooq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;hr /&gt;Список обновлен: 2010/01/15&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-6430292026582218292?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6430292026582218292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6430292026582218292'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/11/blog-post_26.html' title='Список статей блога bzr-day'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5821393343646012851</id><published>2009-11-25T00:00:00.000Z</published><updated>2009-11-25T00:00:01.873Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='рецепты'/><title type='text'>Как добавить каталог без содержащихся в нём файлов?</title><content type='html'>&lt;div style="text-align: justify;"&gt;Для добавления файлов под контроль версий bzr используется команда &lt;tt&gt;add&lt;/tt&gt;. Эта команда по умолчанию добавляет все файлы и каталоги рекурсивно, что очень удобно когда вам нужно добавить много файлов и каталогов.&lt;br /&gt;
&lt;br /&gt;
Как же быть, когда нужно добавить каталог, не добавляя все файлы (или подкаталоги) содержащиеся в нём?&lt;br /&gt;
&lt;br /&gt;
Используйте опцию &lt;tt&gt;--no-recurse&lt;/tt&gt;. Эта опция отключает обычное рекурсивное поведение и при её использовании будут добавлены только те каталоги (или файлы), которые явно указаны в командной строке.&lt;br /&gt;
&lt;br /&gt;
Сравните обычное рекурсивное поведение:&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\add&gt;bzr st
unknown:
  foo/

C:\work\bzr-day\add&gt;dir /b foo
eggs
spam

C:\work\bzr-day\add&gt;bzr add foo
adding foo
adding foo/eggs
adding foo/spam
&lt;/pre&gt;И поведение при использовании опции &lt;tt&gt;--no-recurse&lt;/tt&gt;&lt;br /&gt;
&lt;pre&gt;C:\work\bzr-day\add&gt;bzr st
unknown:
  foo/

C:\work\bzr-day\add&gt;bzr add foo --no-recurse
adding foo

C:\work\bzr-day\add&gt;bzr st
added:
  foo/
unknown:
  foo/eggs
  foo/spam
&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5821393343646012851?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5821393343646012851/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/11/blog-post_25.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5821393343646012851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5821393343646012851'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/11/blog-post_25.html' title='Как добавить каталог без содержащихся в нём файлов?'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5263438418702823675</id><published>2009-11-22T18:07:00.002Z</published><updated>2009-11-26T22:13:21.053Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='концепции'/><category scheme='http://www.blogger.com/atom/ns#' term='особенности'/><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Mainline: главная линия разработки и номера ревизий (Часть 3)</title><content type='html'>&lt;div style="text-align: justify;"&gt;
Это заключительная статья с рассказом о концепции &lt;i&gt;mainline&lt;/i&gt; в Bazaar (предыдущие части &lt;a href="http://bzr-day.blogspot.com/2009/09/mainline-1_08.html"&gt;первая&lt;/a&gt; и &lt;a href="http://bzr-day.blogspot.com/2009/09/mainline-2.html"&gt;вторая&lt;/a&gt;). Я должен признать, что несмотря на то, что сама концепция mainline достаточно проста, но рассказать про нее просто и понятно у меня получается не так хорошо, как хотелось бы. Поэтому в начале этой части я снова повторю некоторые ключевые особенности концепции mainline и затем расскажу как она влияет на работу с Bazaar.&lt;br /&gt;
&lt;/div&gt;
&lt;h2&gt;
Концепция mainline&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
Концепция &lt;i&gt;mainline&lt;/i&gt; разделяет ревизии на те, которые были зафиксированы непосредственно в конкретной ветке, и на все остальные, которые были присоединены из других веток (при помощи команды &lt;tt&gt;merge&lt;/tt&gt;).&lt;br /&gt;
&lt;br /&gt;
Благодаря тому, что в Bazaar используется модель "одна ветка в одном каталоге", то концепция mainline становится возможной и в некотором смысле логичной.&lt;br /&gt;
&lt;br /&gt;
Наибольшее значение концепция mainline приобретает для главной ветки проекта (trunk), в которой должен находится только проверенный и рабочий код. При максимальном использовании mainline ни одна новая функция или багфикс не фиксируются напрямую в trunk, а всегда присоединяются (командой &lt;tt&gt;merge&lt;/tt&gt;). При этом история в trunk представляет собой четкий список новых функций и улучшений.&lt;br /&gt;
&lt;br /&gt;
Наиболее полно этот принцип используется самими разработчиками Bazaar. Если посмотреть на журнал ревизий ветки с кодом bzr, то мы увидим историю в виде списка улучшений и добавлений:&lt;br /&gt;
&lt;pre&gt;C:\work\Bazaar\bzr-2a\bzr.dev&amp;gt;bzr log -l10 --short
 4819 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Fix bug #485771,
        only change slashes on arguments that are being globbed.

 4818 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Add a developer doc describing dependencies for win32 builds

 4817 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (igc) Trivial formatting fix to merge help

 4816 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (igc) Explain that .bzrignore is implicitly added (Patrick Regan,
        #59608)

 4815 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Fix CommitBuilder.inv_sha1 when using record_iter_changes.

 4814 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Release the gil during some of the core groupcompress code
        paths.

 4813 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (jam) Remove a @needs_read_lock decorator from something that doesn't
        really need it.

 4812 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (Alexander Sack) Add --commit-time option to 'bzr commit'. (#459276)

 4811 Canonical.com Patch Queue Manager 2009-11-19 [merge]
      (Andrew Bennetts) Add 'Bazaar Contribution in Five Minutes'
        introduction to developer docs.

 4810 Canonical.com Patch Queue Manager 2009-11-18 [merge]
      (jam) Last few tweaks to get the win32 test suite to pass.

Use --include-merges or -n0 to see merged revisions.
&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;
Разделение ревизий на 2 группы&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
Как отмечено выше концепция mainline делит все ревизии в ветке на две неравные группы: &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;ревизии, непосредственно зафиксированные в конкретной ветке&lt;/li&gt;
&lt;li&gt;ревизии, присоединенные из других веток командой merge&lt;/li&gt;
&lt;/ul&gt;
Последовательность ревизий из 1й группы образует "основную" историю ветки, или mainline. Иногда еще эту последовательность называют "left-hand history", поскольку при выводе журнала ревизий основная группа отображается начиная с крайней левой колонки, в то время как присоединенные ревизии выводятся в журнале с отступом.&lt;br /&gt;
&lt;br /&gt;
Второе неравенство между группами ревизий заключается в том, что для "основной" истории ревизии нумеруются целыми числами, начиная с 1 для первой ревизии. Присоединенные ревизии нумеруются по сложной "точечной" схеме &lt;tt&gt;M.B.N&lt;/tt&gt;, где &lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;M — это основная ревизия, от которой отпочковалась ветка,&lt;/li&gt;
&lt;li&gt;B — это условный порядковый номер ветки (чтобы различать несколько веток отпочковавшихся из одной и той же основной ревизии)&lt;/li&gt;
&lt;li&gt;N — это номер ревизии в ветке, после отпочкования&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Собственно номера ревизий — это одно из наиболее заметных проявлений концепции mainline. Рассмотрим теперь как mainline влияет на различные команды bzr.&lt;br /&gt;
&lt;/div&gt;
&lt;h2&gt;
Журнал ревизий&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
Как уже отмечалось, журнал ревизий выводит основные и присоединенные ревизии немного по-разному. Прежде всего присоединенные ревизии выводятся с отступом. А в последних версиях bzr присоединенные ревизии по умолчанию не отображаются (это сделано из соображений производительности). Для того, чтобы увидеть присоединенные ревизии необходимо использовать опцию командной строки &lt;tt&gt;--include-merges&lt;/tt&gt; или &lt;tt&gt;-n0&lt;/tt&gt;:&lt;br /&gt;
&lt;pre&gt;C:\work\Bazaar\bzr-2a\bzr.dev&amp;gt;bzr log -r-1 --short -n0
 4819 Canonical.com Patch Queue Manager 2009-11-20 [merge]
      (jam) Fix bug #485771,
        only change slashes on arguments that are being globbed.

       4818.1.1 John Arbash Meinel      2009-11-20
                Fix bug #485771. Only change '/' to '/' when expanding globs.

                The code we had would replace '/' even if it was in a quoted section,
                or if it was part of a simple argument that didn't have a glob.
&lt;/pre&gt;
&lt;br /&gt;
При просмотре ревизий в GUI окне команды qlog присоединенные ревизии скрыты и помечены значком +:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/33668680@N07/3920175869/" title="qlog-test-collapsed by bialix, on Flickr"&gt;&lt;img alt="qlog-test-collapsed" height="314" src="http://farm4.static.flickr.com/3528/3920175869_5a74b35b5e_o.png" width="647" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Щелчком мышки по значку + (либо нажатие стрелки вправо при использовании клавиатуры) раскрывает присоединенные ревизии:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/33668680@N07/3920176099/" title="qlog-test-expanded by bialix, on Flickr"&gt;&lt;img alt="qlog-test-expanded" height="361" src="http://farm3.static.flickr.com/2628/3920176099_bb6472fa64_o.png" width="649" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;h2&gt;
Объединение двух веток&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
Как уже отмечалось ранее, ревизии разделены на две неравные группы. Поэтому история при объединении двух веток будет визуально различаться в зависимости от того как вы делаете merge, т.е. какая ветка будет основной, а какая присоединенной.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим несколько типовых случаев. Приведенные ниже примеры и рекомендации имеют смысл только если ваша команда разработчиков договорилась использовать парадигму mainline.&lt;br /&gt;
&lt;br /&gt;
В следующих примерах подразумевается, что пользователь работает со своей локальной рабочей (функциональной) веткой, главная ветка (trunk) располагается на центральном сервере, и локально пользователь имеет копию главной ветки. &lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
Неоконченная работа в функциональной ветке, присоединение изменений из другой ветки&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
При длительной работе над новой функцией в отдельной (функциональной) ветке зачастую приходится делать merge новых изменений из других веток (либо из главной ветки). Это может требоваться для того, чтобы задействовать новую функциональность, необходимую для вашей работы. Либо для того, что решить возможные конфликты из-за радикальных изменений (например рефакторинга) в основной ветке.&lt;br /&gt;
&lt;br /&gt;
В этом случае нормальным и правильным решением будет присоединение изменений из других веток в вашу рабочую ветку. При этом ваша ветка остается основной.&lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
Объединение главной ветки и нового кода из функциональной ветки&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
Когда работа над новой функциональностью закончена и вы готовы объединить свой новый код с главной веткой, то необходимо помнить, что основная история в главной ветке должна оставаться неизменной. Поэтому вы должны присоединить свою ветку в главную ветку. Часто эту операцию называют land или landing (посадка, приземление).&lt;br /&gt;
&lt;br /&gt;
Для выполнения объединения-приземления удобно использовать локальную копию главной ветки. Перед объединением вы обновляете локальную копию главной ветки (командой pull). Затем из каталога с копией главной ветки запускаете команду merge:&lt;br /&gt;
&lt;pre&gt;bzr merge ../my-work
&lt;/pre&gt;
После объединения вы проверяете результат, решаете конфликты если таковые имеются и фиксируете результат в копии главной ветки. Затем делаете push в главную ветку (на сервере).&lt;br /&gt;
&lt;br /&gt;
Такой порядок действия хорошо работает в небольших командах, где каждый может делать push в главную ветку. В тех командах, где присоединением новых веток в главную занимается специальный человек (gatekeeper) или объединение производится специальной программой (так например в проекте Bazaar объединением с основной веткой занимается PQM — программа-работ, получающая инструкции через электронную почту), в этом случае целесообразно сделать merge из главной ветки в свою функциональную ветку перед подачей заявки на объединение с главной веткой. Это merge позволит вам исправить все возможные конфликты и следовательно упростит процедуру включения ваших изменений.&lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
Когда объединение делать необязательно?&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
Продолжая тему объединения новой функциональности с главной веткой рассмотрим вопрос: всегда ли нужно использовать merge для этого?&lt;br /&gt;
&lt;br /&gt;
Если ваша функциональная ветка является прямым продолжением главной ветки, то может возникнуть искушение сделать push прямо в главную ветку. В общем случае так делать не следует. Особенно если принятая политика вашей команды требует, чтобы перед включением новых изменений обязательно были запущены все автоматические тесты.&lt;br /&gt;
&lt;br /&gt;
При отсутствии автоматических тестов у вас будет выбор. Но опять же — в общем случае делать прямой push не следует, особенно если в вашей ветке больше одной ревизии.&lt;br /&gt;
&lt;br /&gt;
Если все ваши изменения уместились в одну ревизию, то в этом случае выбор за вами: делать merge или push. Операция merge может оказаться полезной тем, что вы сможете написать другой комментарий к вашим изменениям, более уместный в контексте главной ветки.&lt;br /&gt;
&lt;/div&gt;
&lt;h2&gt;
Push/pull и основная история&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
Следует знать и всегда помнить о том, что операции push и pull могут поменять основную историю ветки. В некотором смысле даже без вашего желания. Это происходит в тех случаях, когда одна ветка была объединена с другой.&lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
Pull&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
Когда все ревизии из вашей рабочей (функциональной) ветки присоединены в основную ветку, то pull из основной ветки в вашу ветку приведет к тому, что ваша ветка станет полной копией другой ветки. Все ваши ревизии уже присоединены в основную ветку, так что вы ничего не теряете.&lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
Push&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
Наиболее частая ошибка при объединении функциональной ветки с главной веткой, это когда merge делается в функциональную ветку (вместо копии главной ветки). В этом случае push из функциональной ветки в главную ветку становится возможным. Но делать такой push — очень плохая идея, потому что при этом изменяется нумерация ревизий в главной ветке: push при этом меняет mainline главной ветки на mainline функциональной ветки. Так делать не следует. Как было описано выше правильно делать merge в локальную копию главной ветки и делать push оттуда.&lt;br /&gt;
&lt;br /&gt;
Хотя подобный push не является фатальным сам по себе, его следует избегать. Потому что если кто-то другой зафиксирует новую ревизию после того, как основная история была изменена, это превратится в проблему.&lt;br /&gt;
&lt;/div&gt;
&lt;h3&gt;
append_revisions_only&lt;/h3&gt;
&lt;div style="text-align: justify;"&gt;
В bzr существует способ запретить изменение основной истории ветки.&lt;br /&gt;
&lt;br /&gt;
Если при создании ветки указать опцию &lt;tt&gt;--append-revisions-only&lt;/tt&gt;, то для такой ветки устанавливается флаг, запрещающий изменение основной истории за исключением добавления новых ревизий. Т.е. запрещаются операции uncommit и pull/push, если в результате pull/push существующие mainline ревизии могут быть заменены другими с одинаковыми номерами.&lt;br /&gt;
&lt;br /&gt;
Флаг append_revisions_only можно установить и позднее, после того как ветка создана. Для этого необходимо добавить следующую строку в файл конфигурации branch.conf (он находится в .bzr/branch/branch.conf):&lt;br /&gt;
&lt;pre&gt;append_revisions_only = True
&lt;/pre&gt;
&lt;br /&gt;
Установка такого флага возможна и для веток на &lt;a href="https://code.launchpad.net/"&gt;Launchpad.net&lt;/a&gt;, хотя и не совсем тривиальным способом: вам понадобится использовать утилиту &lt;a href="https://launchpad.net/hitchhiker"&gt;hitchhicker&lt;/a&gt;.&lt;br /&gt;
&lt;/div&gt;
&lt;h2&gt;
Заключение&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
В этой статье я попытался описать ключевые моменты, о которых необходимо знать для эффективного использования парадигмы mainline.&lt;br /&gt;
&lt;br /&gt;
Еще раз хочу отметить, что идея mainline уникальна для bzr и отсутствует в других распределенных системах контроля версий (git, hg). У идеи mainline есть свои достоинства и недостатки, и правильное использование mainline требует определенной внимательности и соглашений в команде разработчиков.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5263438418702823675?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5263438418702823675/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/11/mainline-3.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5263438418702823675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5263438418702823675'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/11/mainline-3.html' title='Mainline: главная линия разработки и номера ревизий (Часть 3)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-3698684177019841614</id><published>2009-10-16T07:19:00.000+01:00</published><updated>2009-10-16T07:19:31.485+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr-svn'/><title type='text'>Использование Bazaar для работы с Subversion-репозиториями</title><content type='html'>Продолжаем тему работы с bzr-svn.&lt;br /&gt;
&lt;br /&gt;
John Szakmeister написал подробную статью &lt;a href="http://www.szakmeister.net/blog/2009/oct/12/bazaar-subversion-super-client/"&gt;Bazaar as Subversion "super client"&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Ian Clatworthy (Йен Клатворси), который занимается документацией в проекте Bazaar, создал (полу) оффициальный документ &lt;a href="http://doc.bazaar-vcs.org/migration/en/foreign/bzr-on-svn-projects.html"&gt;Using Bazaar on Subversion projects&lt;/a&gt;. Документ описывает детали работы с Subversion-репозиторием при помощи Bazaar и bzr-svn.&lt;br /&gt;
&lt;br /&gt;
В документе подробно описываются проблемы объединения svn-trunk с вашими bzr-ветками, применение rebase.&lt;br /&gt;
&lt;br /&gt;
Читать: &lt;a href="http://doc.bazaar-vcs.org/migration/en/foreign/bzr-on-svn-projects.html"&gt;http://doc.bazaar-vcs.org/migration/en/foreign/bzr-on-svn-projects.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-3698684177019841614?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://doc.bazaar-vcs.org/migration/en/foreign/bzr-on-svn-projects.html' title='Использование Bazaar для работы с Subversion-репозиториями'/><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/3698684177019841614/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/10/bazaar-subversion.html#comment-form' title='Комментарии: 7'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3698684177019841614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3698684177019841614'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/10/bazaar-subversion.html' title='Использование Bazaar для работы с Subversion-репозиториями'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-6845158817469425541</id><published>2009-10-11T20:22:00.001+01:00</published><updated>2009-10-11T20:23:13.286+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr-svn'/><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><title type='text'>Работа с svn из bzr</title><content type='html'>&lt;a href="http://softwaremaniacs.org/blog"&gt;Иван Сагалаев&lt;/a&gt; &lt;a href="http://softwaremaniacs.org/blog/2009/10/11/svn-from-bzr/"&gt;делится опытом&lt;/a&gt; использования Bazaar и плагина bzr-svn для работы с SVN репозиторием:&lt;br /&gt;
&lt;blockquote&gt;Юра Юревич подбил меня недавно на пост про то, как я пользуюсь Subversion из Bazaar. Недавно Bazaar поменял мажорную версию на 2.0, и я решил, что пора.&lt;br /&gt;
&lt;br /&gt;
Предыстория такова. В Яндексе много кода (бо́льшая часть наверное) хранится под управлением svn. Подозреваю, что мы не одни такие :-). Какое-то время назад меня стало точить настойчивое желание попользоваться или даже совсем переехать на какую-нибудь распределённую VCS. Волею случая выбор пал на bzr, я его попробовал, и вроде понравилось. Но на работе большую часть времени сидел всё равно под svn, чтобы работать с существующим кодом. Однако совсем недавно я вдруг сложил в голове несколько очевидных вещей, и теперь -- тадам! -- общаюсь со всем svn-кодом из bzr, используя все прелести последнего.&lt;br /&gt;
&lt;br /&gt;
Теперь делюсь опытом.&lt;/blockquote&gt;&lt;br /&gt;
Читать полностью: &lt;a href="http://softwaremaniacs.org/blog/2009/10/11/svn-from-bzr/"&gt;http://softwaremaniacs.org/blog/2009/10/11/svn-from-bzr/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-6845158817469425541?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://softwaremaniacs.org/blog/2009/10/11/svn-from-bzr/' title='Работа с svn из bzr'/><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/6845158817469425541/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/10/svn-bzr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6845158817469425541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6845158817469425541'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/10/svn-bzr.html' title='Работа с svn из bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4034246856592426847</id><published>2009-09-25T11:53:00.003+01:00</published><updated>2009-09-28T08:21:28.307+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Bazaar 2.0 и новый формат репозитория по умолчанию</title><content type='html'>&lt;div align="justify"&gt;Сегодня 25 сентября и со дня на день всё прогрессивное человечество ожидает выхода новой версии bzr 2.0. Как видно из названия, эта версия не просто очередная версия bzr, одна из тех, что выходят почти каждый  месяц. Это версия 2.0 (три восклицательных знака).&lt;br&gt; &lt;br&gt; Одно из ключевых изменений в версии 2.0 — это новый формат репозитория, используемый по умолчанию, который называется &lt;b&gt;2a&lt;/b&gt;. Именно это изменение может стать серьезным камнем преткновения для некоторых пользователей, как оно &lt;i&gt;почти&lt;/i&gt; стало для меня.&lt;/div&gt; &lt;h2&gt;Проблема&lt;/h2&gt; &lt;div align="justify"&gt;Bazaar имеет заслуженную репутацию системы, в которой существует зоопарк форматов репозиториев. В настоящий момент число форматов превышает 10. История появления каждого формата отмечает этапы развития системы и путь, который bzr прошел ради достижения скорости работы, сравнимой с такими лидерами как Mercurial и Git.&lt;br&gt; &lt;br&gt; Само по себе такое число форматов ни о чем плохом не говорит: все форматы поддерживаются по сей день, новые версии bzr без проблем умеют работать с репозиториями в старых форматах, хотя в ряде случаев рекомендуют обновить формат на более новый по причине морального старения. Да и новые форматы обычно более компактны и занимают меньше места на диске, плюс bzr работает с ними заметно быстрее. Проблема не в их числе, проблема в том, что существуют две группы форматов, взаимно не заменяемые.&lt;br&gt; &lt;br&gt; Речь идет о различии между обычными форматами и так называемыми rich-root форматами. По историческим причинам rich-root формат появился для поддержки одной долгожданной функции bzr, которая впрочем до сих пор не реализована. Отличие между простыми форматами и rich-root заключается в наличии дополнительных метаданных о ветках. Форматы rich-root никогда не были рекомендуемыми, и не являлись форматом по умолчанию. Более того, поскольку дополнительная информация rich-root формата не может быть сохранена в простом формате, то вы не можете перейти от rich-root к простому формату. Вообще. Переход от простых форматов к rich-root возможен всегда. Причем, вы не сможете даже сделать &lt;tt&gt;pull&lt;/tt&gt; или &lt;tt&gt;merge&lt;/tt&gt; из rich-root в обычную ветку. Собственно это и составляет проблему: односторонний переход из одной группы форматов в другую.&lt;br&gt; &lt;br&gt; Ящик пандоры открыл популярный плагин &lt;i&gt;bzr-svn&lt;/i&gt;, который первым стал активно использовать формат rich-root при конверсии svn репозитория в bzr. Причины такого решения целиком логичные, однако имели далеко идущие последствия. Каждый новый формат в серии bzr 1.x всегда имел пару реализаций: простую и rich-root. Много раз подымался вопрос об их объединении в единый формат, однако по ряду причин это сделано только в новом формате 2a.&lt;br&gt; &lt;br&gt; Новый формат bzr 2a поддерживает &lt;i&gt;только rich-root&lt;/i&gt;, поэтому новые пользователи будут избавлены от имеющейся дихотомии.&lt;br&gt; &lt;br&gt; Однако, все существующие репозитории и ветки должны быть либо обновлены до 2a или хотя бы до rich-root, чтобы избежать проблемы несовместимости форматов.&lt;br&gt; &lt;/div&gt; &lt;h3&gt;Пример несовместимости&lt;/h3&gt; Создадим ветку в формате pack-0.92 (основной формате в серии bzr 1.x, обычный не rich-root). &lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats&amp;gt;bzr init 0.92 --format=pack-0.92&lt;br&gt; Created a standalone tree (format: pack-0.92)&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\0.92&amp;gt;bzr ci --unchanged -m 1&lt;br&gt; Committing to: C:/work/bzr-day/Formats/0.92/&lt;br&gt; Committed revision 1.&lt;/samp&gt;&lt;br&gt; &lt;br&gt; Сделаем копию этой ветки и сконвертируем ее в формат 2a.&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats&amp;gt;bzr branch 0.92 2a&lt;br&gt; Branched 1 revision(s).&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\2a&amp;gt;bzr upgrade --format=2a&lt;br&gt; starting upgrade of &lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/2a/"&gt;file:///C:/work/bzr-day/Formats/2a/&lt;/a&gt;&lt;br&gt; making backup of &lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/2a/.bzr"&gt;file:///C:/work/bzr-day/Formats/2a/.bzr&lt;/a&gt;&lt;br&gt;   to &lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/2a/backup.bzr"&gt;file:///C:/work/bzr-day/Formats/2a/backup.bzr&lt;/a&gt;&lt;br&gt; starting repository conversion&lt;br&gt; repository converted&lt;br&gt; finished&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\2a&amp;gt;bzr info&lt;br&gt; Standalone tree (format: 2a)&lt;br&gt; Location:&lt;br&gt;   branch root: .&lt;br&gt; &lt;br&gt; Related branches:&lt;br&gt;   parent branch: C:/work/bzr-day/Formats/0.92&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\2a&amp;gt;bzr ci --unchanged -m 2a&lt;br&gt; Committing to: C:/work/bzr-day/Formats/2a/&lt;br&gt; Committed revision 2.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Зафиксируем еще одну ревизию в первой ветке:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats\0.92&amp;gt;bzr commit --unchanged -m 2-0.92&lt;br&gt; Committing to: C:/work/bzr-day/Formats/0.92/&lt;br&gt; Committed revision 2.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; И попробуем сделать объединение. Объединение из обычного формата в 2a работает без проблем:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats\2a&amp;gt;bzr merge ../0.92&lt;br&gt; All changes applied successfully.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; А вот в обратную сторону не работает вовсе:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats\0.92&amp;gt;bzr merge ../2a&lt;br&gt; bzr: ERROR: KnitPackRepository('&lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/"&gt;file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/&lt;/a&gt;')&lt;br&gt; is not compatible with&lt;br&gt; CHKInventoryRepository('&lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/2a/.bzr/repository/"&gt;file:///C:/work/bzr-day/Formats/2a/.bzr/repository/&lt;/a&gt;')&lt;br&gt; different rich-root support&lt;/samp&gt;&lt;br&gt; &lt;br&gt; В последней строке явно виден корень проблемы: &lt;b&gt;different rich-root support.&lt;/b&gt;&lt;br&gt; &lt;br&gt; Проблема усугубляется тем, что конвертация из простого формата в rich-root может произойти неявно и без вашего ведома. Например, когда вы делаете копию не-rich-root ветки в разделяемый репозиторий (shared repository) в rich-root формате:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats&amp;gt;bzr init-repo --2a shared-repo&lt;br&gt; Shared repository with trees (format: 2a)&lt;br&gt; Location:&lt;br&gt;   shared repository: shared-repo&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\shared-repo&amp;gt;bzr branch ../0.92 trunk&lt;br&gt; Branched 2 revision(s).&lt;br&gt; &lt;br&gt; C:\work\bzr-day\Formats\0.92&amp;gt;bzr merge ../shared-repo/trunk&lt;br&gt; bzr: ERROR: KnitPackRepository('&lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/"&gt;file:///C:/work/bzr-day/Formats/0.92/.bzr/repository/&lt;/a&gt;')&lt;br&gt; is not compatible with&lt;br&gt; CHKInventoryRepository('&lt;a class="moz-txt-link-freetext" href="file:///C:/work/bzr-day/Formats/shared-repo/.bzr/repository/"&gt;file:///C:/work/bzr-day/Formats/shared-repo/.bzr/repository/&lt;/a&gt;')&lt;br&gt; different rich-root support&lt;/samp&gt;&lt;br&gt; &lt;h2&gt;Как узнать текущий формат ветки/репозитория&lt;/h2&gt; Команда &lt;tt&gt;bzr info -v&lt;/tt&gt; отображает различную информацию о ветке/репозитории и в том числе формат репозитория.&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats\0.92&amp;gt;bzr info -v&lt;br&gt; Standalone tree (format: pack-0.92)&lt;br&gt; Location:&lt;br&gt;   branch root: .&lt;br&gt; &lt;br&gt; Related branches:&lt;br&gt;   submit branch: C:/work/bzr-day/Formats/2a&lt;br&gt; &lt;br&gt; Format:&lt;br&gt;        control: Meta directory format 1&lt;br&gt;   working tree: Working tree format 4&lt;br&gt;         branch: Branch format 6&lt;br&gt;     repository: Packs containing knits without subtree support&lt;br&gt; ...&lt;br&gt; &lt;/samp&gt;&lt;br&gt; В строке repository описан детальный формат. Если там написано &lt;b&gt;without subtree support&lt;/b&gt; — это обычный не-rich-root формат.&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Formats\2a&amp;gt;bzr info -v&lt;br&gt; Standalone tree (format: 2a)&lt;br&gt; Location:&lt;br&gt;   branch root: .&lt;br&gt; &lt;br&gt; Related branches:&lt;br&gt;   parent branch: C:/work/bzr-day/Formats/0.92&lt;br&gt;   submit branch: C:/work/bzr-day/Formats/0.92&lt;br&gt; &lt;br&gt; Format:&lt;br&gt;        control: Meta directory format 1&lt;br&gt;   working tree: Working tree format 6&lt;br&gt;         branch: Branch format 7&lt;br&gt;     repository: Repository format 2a - rich roots, group compression and chk inventories&lt;br&gt; ...&lt;/samp&gt;&lt;br&gt; &lt;br&gt; Заметьте, что для 2a в описании формата присутствует упоминание rich roots.&lt;br&gt; &lt;h2&gt;Что делать&lt;/h2&gt; &lt;div align="justify"&gt;С первым вопросом русской интеллигенции мы разобрались выше, теперь перейдем ко второму вопросу. Ответ на него имеет несколько вариантов в зависимости от конкретной ситуации.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;1. Конвертировать все свои ветки и репозитории в формат 2a&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;В долгосрочной перспективе наиболее правильное решение — это конвертация всех ваших репозиториев в формат, поддерживающий rich-root. В первую очередь в формат 2a. &lt;br&gt; Формат 2a поддерживается в bzr, начиная с версии 1.16. Поэтому если на всех компьютерах в вашей организации установлена достаточная свежая версия bzr вы можете пойти этим путём. &lt;br&gt; &lt;br&gt; Рекомендуется сделать тестовое обновление на локальной машине. Перед обновлением целесообразно запустить команду bzr reconcile для исправления возможных нестыковок внутри репозитория. Затем кто-то один из вашей команды должен сделать обновление веток на центральном сервере, а затем остальные сделают новую копию главной ветки на свои компьютеры, или обновят все свои ветки в формат 2a.&lt;/div&gt;
&lt;a href="http://doc.bazaar-vcs.org/latest/en/upgrade-guide/index.html"&gt;Подробная инструкция по обновлению.&lt;/a&gt;&lt;br&gt;
&lt;b&gt;2. Конвертировать свои ветки в формат rich-root&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Если по ряду причин в вашем ведении находятся компьютеры со старой версией bzr, либо вы используете сторонние продукты, которые зависят от старых версий bzr, то вы можете рассмотреть вариант обновления до формата rich-root-pack, который совместим с 2a. Рекомендации по последовательности обновления те же самые.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;3. Не использовать bzr 2.0 и выше&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Если по ряду причин вы не можете обновить часть компьютеров и не считаете целесообразным обновлять все ветки и репозитории в rich-root формат, то, возможно, вам стоит принять волевое решение не обновлять ни на одном подведомственном вам компьютере bzr до версии 2.0. Последняя стабильная версия из серии bzr 1.x — это bzr 1.18.&lt;br&gt; &lt;br&gt; Однако рано или поздно перейти придётся. Хотя бы потому, что в новых версиях чинят старые баги.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;4. Использовать специальный плагин для установки старого формата по умолчанию&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Я написал маленький плагин format1, который устанавливает старый не-rich-root формат &lt;tt&gt;pack-0.92&lt;/tt&gt; в качестве формата по умолчанию для bzr. После установки этого плагина при каждом запуске bzr форматом по умолчанию будет устанавливаться pack-0.92. Поэтому все создаваемые с нуля новые ветки и разделяемые репозитории (что самое важное!) будут иметь формат pack-0.92. При этом пользователь может принудительно выбрать другой формат через опции командной строки.&lt;br&gt; &lt;br&gt; Ветка плагина располагается на Launchpad: &lt;a class="moz-txt-link-freetext" href="https://code.launchpad.net/~bialix/+junk/format1"&gt;https://code.launchpad.net/~bialix/+junk/format1&lt;/a&gt;&lt;br&gt; &lt;br&gt; Установка плагина: как обычно, поместите копию ветки в ваш каталог plugins.&lt;br&gt; &lt;br&gt; ПРЕДУПРЕЖДЕНИЕ ОБ ОТКАЗЕ ОТ ОТВЕТСТВЕННОСТИ: написанный мною плагин должен работать корректно, однако 100% гарантию я давать не буду. Поэтому используйте его на свой страх и риск, либо не используйте вовсе, а рассмотрите предыдущие озвученные варианты решения проблемы.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Выводы&lt;/h2&gt; &lt;div align="justify"&gt;Переход на использование нового bzr 2.0 влечёт за собой и переход на новый формат 2a. Будьте внимательны и донесите до сведения каждого участника вашей команды все последствия такого перехода и скоординируйте обновление &lt;i&gt;всех&lt;/i&gt; ваших веток.&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4034246856592426847?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4034246856592426847/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/09/bazaar-20.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4034246856592426847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4034246856592426847'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/09/bazaar-20.html' title='Bazaar 2.0 и новый формат репозитория по умолчанию'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4666140242818062080</id><published>2009-09-14T21:54:00.004+01:00</published><updated>2009-09-15T00:15:53.632+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='концепции'/><category scheme='http://www.blogger.com/atom/ns#' term='особенности'/><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Mainline: главная линия разработки и номера ревизий (Часть 2)</title><content type='html'>&lt;div align="justify"&gt;Продолжаем &lt;a  href="http://bzr-day.blogspot.com/2009/09/mainline-1_08.html"&gt;разговор&lt;/a&gt; об одной специфичной особенности bzr, которую вы не найдете ни в одной другой распределенной системе контроля версий. Мы рассматриваем понятие &lt;b&gt;mainline&lt;/b&gt; (главная линия разработки), его связь с номерами ревизий, и каким образом mainline влияет на работу с несколькими ветками.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Откуда есмь пошло понятие mainline&lt;/h2&gt; &lt;blockquote&gt;В английском языке &lt;i&gt;mainline&lt;/i&gt; означает основную дорогу, магистраль, основную колею участка железной дороги.&lt;br&gt; &lt;/blockquote&gt; &lt;div align="justify"&gt;Понятие mainline пришло в Bazaar из его предшественника Arch. В Arch это понятие использовалось, чтобы разделить ревизии, зафиксированные в этой конкретной ветке, от ревизий, присоединенных (merged) из других веток. В таком же контексте mainline используется и в Bazaar.&lt;br&gt; &lt;br&gt; Синонимом понятия mainline (главная линия или главная ветка) в распределенных системах можно считать ствол (trunk) в централизованных системах (svn). Однако при этом промежуточные стадии разработки производятся в отдельных ветках, а в главную ветку (trunk) попадает уже готовый отлаженный результат работы. В этом случае trunk теоретически всегда находится в работоспособном состоянии: программа заведомо компилируется и работает. Подробное изложение такого метода разработки можно найти в документе &lt;a  href="http://www.divmod.org/trac/wiki/UltimateQualityDevelopmentSystem"&gt;Ultimate Quality Development System (UQDS)&lt;/a&gt;.&lt;br&gt; &lt;br&gt; Реально, mainline в Bazaar — это фактически закрепленная на уровне системы контроля версий модель разработки с основной (центральной) веткой, в которая содержит законченные результаты работы, и множества  рабочих веток (features branches — ветки для разработки новых функций), которые собственно используются разработчиками.&lt;br&gt; &lt;br&gt; Достоинством встроенной поддержки парадигмы mainline является то, что при правильном использовании вы получаете красивую историю вашего проекта, в которой каждая ревизия в главной ветке представляет собой мини-аннотацию для одной или несколько новых функций, присоединенных из соответствующей ветки разработки. &lt;br&gt; &lt;br&gt; Недостатком встроенной поддержки парадигмы mainline является то, что отключить эту поддержку в Bazaar нет возможности, поэтому для нормальной работы с системой пользователь должен так или иначе следовать этой парадигме. В противном случае журнал ревизий будет не так легко анализировать.&lt;br&gt; &lt;h2&gt;Как mainline влияет на вывод журнала ревизий&lt;/h2&gt; Дополнительное (негативное) влияние парадигма mainline косвенно оказывает на быстродействие некоторых операций, в которых участвуют составные "точечные" номера ревизий (dotted revno), например, ревизия 2.1.1. Для однозначного вычисления "точечного" номера ревизии Bazaar должен проанализировать полный граф ревизий на достаточную глубину, чтобы найти ревизию, после которой ветки разошлись.&lt;br&gt; &lt;br&gt; В связи с этим разработчики Bazaar, начиная с версии bzr 1.14, пошли на небольшую хитрость: по умолчанию "точечные" ревизии в журнале не отображаются, что позволяет избежать затрат на вычисление их номеров. При этом у пользователя остается возможность принудительно включить их вывод при помощи соответствующей опции командной строки.&lt;br&gt; &lt;br&gt; Чтобы было понятнее, рассмотрим основные форматы вывода журнала ревизий, которые нам предлагает Bazaar.&lt;br&gt; &lt;ul&gt;   &lt;li&gt;&lt;tt&gt;bzr log --long&lt;/tt&gt; — формат вывода журнала по умолчанию; отображается детальная информация о ревизии в несколько строк: условный номер ревизии, теги, автор(ы), короткое имя ветки (branch nick), дата, полный текст комментария к ревизии. Пример (из знакомой нам &lt;a  href="https://code.launchpad.net/%7Ebzr-day/bzr-day-examples/basic-test"&gt;ветки Test&lt;/a&gt;):&lt;/li&gt; &lt;/ul&gt; &lt;blockquote&gt;&lt;samp&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log -r-1&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 4 [merge]&lt;br&gt; committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;&lt;br&gt; branch nick: Test&lt;br&gt; timestamp: Tue 2009-09-08 23:50:01 +0300&lt;br&gt; message:&lt;br&gt;   Объединение с веткой Experimental&lt;br&gt; ------------------------------------------------------------&lt;br&gt; Use --include-merges or -n0 to see merged revisions.&lt;/samp&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;ul&gt;   &lt;li&gt;&lt;tt&gt;bzr log --short&lt;/tt&gt; — "краткий" формат вывода: в одну строку выводится условный номер ревизии, автор, дата; ниже выводится полный комментарий к ревизии. Пример:&lt;/li&gt; &lt;/ul&gt; &lt;blockquote&gt;&lt;samp&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log -r-1 --short&lt;br&gt;     4 Базарный день     2009-09-08 [merge]&lt;br&gt;       Объединение с веткой Experimental&lt;br&gt;   &lt;br&gt; Use --include-merges or -n0 to see merged revisions.&lt;br&gt;   &lt;/samp&gt;&lt;/blockquote&gt; &lt;ul&gt;   &lt;li&gt;bzr log --line — наиболее компактный формат вывода: в одну строку выводится условный номер ревизии, автор, дата и начало комментария к ревизии. Пример:&lt;/li&gt; &lt;/ul&gt; &lt;blockquote&gt;&lt;samp&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log -r-1 --line&lt;br&gt; 4: Базарный день 2009-09-08 [merge] Объединение с веткой Experimental&lt;/samp&gt;&lt;br&gt; &lt;/blockquote&gt; До версии bzr 1.14 log --long всегда отображал присоединенные ревизии, а log --short и log --line не умели этого. Теперь все форматы умеют отображать присоединенные ревизии при запуске команды log с опцией -n0 или --include-merges. Например:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log --line -n0&lt;br&gt; 4: Базарный день 2009-09-08 [merge] Объединение с веткой Experimental&lt;br&gt;   2.1.1: Базарный день 2009-09-08 Скорректирован файл goodbye.txt в ветке Experimental&lt;br&gt; 3: Базарный день 2009-09-08 Скорректирован файл foo.txt в ветке Test&lt;br&gt; 2: Базарный день 2009-09-08 Внесены изменения для иллюстрации команд status и diff&lt;br&gt; 1: Базарный день 2009-09-08 Начальное состояние файлов&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Итак, мы можем видеть, что сегодня журнал по умолчанию отображает только ревизии, соответствующие mainline. Поэтому, если ваш проект не следует этой парадигме, вы всегда должны запускать команду log с включенной опцией отображения присоединенных ревизий. (Этого можно достичь при помощи &lt;a href="http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#using-aliases"&gt;aliases&lt;/a&gt;).

Аналогичная картина и с GUI командой qlog (из плагина &lt;a href="https://launchpad.net/qbzr"&gt;QBzr&lt;/a&gt;): после запуска этой команды пользователь видит только mainline-ревизии, а присоединенные ревизии свернуты. Для разворачивания/отображения этих ревизий пользователь должен щелкнуть мышкой по значку + в круглом узле на графе ревизий (либо использовать стрелки влево-вправо на клавиатуре), см. снимок с экрана ниже.&lt;br&gt; &lt;br&gt; &lt;a href="http://www.flickr.com/photos/33668680@N07/3920175869/" title="qlog-test-collapsed by bialix, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3528/3920175869_5a74b35b5e_o.png" width="647" height="314" alt="qlog-test-collapsed" /&gt;&lt;/a&gt;&lt;br&gt; &lt;br&gt; &lt;i&gt;Рисунок 1. Отображение графа ревизий после запуска: только mainline ревизии&lt;/i&gt;&lt;br&gt; &lt;br&gt; &lt;a href="http://www.flickr.com/photos/33668680@N07/3920176099/" title="qlog-test-expanded by bialix, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2628/3920176099_bb6472fa64_o.png" width="649" height="361" alt="qlog-test-expanded" /&gt;&lt;/a&gt;&lt;br&gt; &lt;br&gt; &lt;i&gt;Рисунок 2. Развернутый узел с присоединенными ревизиями&lt;/i&gt;&lt;br&gt; &lt;br&gt; В следующей части этой статьи мы рассмотрим как mainline влияет на команды &lt;tt&gt;merge&lt;/tt&gt;, &lt;tt&gt;commit&lt;/tt&gt; и &lt;tt&gt;push&lt;/tt&gt;. Также мы попытаемся сформулировать ряд советов по правильному использованию парадигмы главной линии разработки (mainline).&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4666140242818062080?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4666140242818062080/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/09/mainline-2.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4666140242818062080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4666140242818062080'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/09/mainline-2.html' title='Mainline: главная линия разработки и номера ревизий (Часть 2)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-3414539992284175331</id><published>2009-09-08T22:37:00.004+01:00</published><updated>2009-09-12T12:09:36.968+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='концепции'/><category scheme='http://www.blogger.com/atom/ns#' term='особенности'/><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Mainline: главная линия разработки и номера ревизий (Часть 1)</title><content type='html'>&lt;div align="justify"&gt;Сегодня речь пойдет об одной специфичной особенности bzr, которую вы не найдете ни в одной другой распределенной системе контроля версий. Мы рассмотрим понятие &lt;b&gt;mainline&lt;/b&gt; (главная линия разработки), его связь с номерами ревизий, и каким образом mainline влияет на работу с несколькими ветками.&lt;br&gt; &lt;h2&gt;Номера ревизий в распределенной системе&lt;/h2&gt; Прежде всего необходимо четко понимать и помнить, что в распределенных системах контроля версий для однозначной идентификации любой ревизии необходимо применять некие &lt;i&gt;уникальные идентификаторы&lt;/i&gt;. Простая нумерация ревизий 1,2,3,… для этого не подходит, поскольку идентификаторы должны быть уникальны в глобальном смысле, а простые номера уникальны только в пределах одной физической копии репозитория (что вполне подходит для централизованных систем типа svn). &lt;br&gt; &lt;br&gt; Поэтому все современные распределенные системы применяют уникальные идентификаторы. Так Monotone, Git и Mercurial используют в качестве уникального идентификатора ревизии &lt;code&gt;SHA-1&lt;/code&gt; хэш от данных самой ревизии. Bazaar тоже использует уникальные идентификаторы для ревизий, однако эти идентификаторы представляют произвольную строку и нет требования, чтобы идентификатор был основан на данных самой ревизии.&lt;br&gt; &lt;br&gt; Использование длинных и/или абстрактных идентификаторов в большинстве случаев не является оптимальным способом адресации ревизии для простых смертных. Поэтому разработчики Bazaar решили, что внутри системы будут использоваться уникальные идентификаторы, а пользователи системы будут большую часть времени оперировать с &lt;i&gt;условными&lt;/i&gt; номерами ревизий. При этом в Bazaar остается возможность использовать собственно уникальные идентификаторы.&lt;br&gt; &lt;br&gt; Номера ревизий в Bazaar имеют условный характер и имеют смысл только в контексте конкретной ветки, с которой производятся какие-то действия и в большинстве случаев эти номера стабильны и не меняются.&lt;br&gt; &lt;h2&gt;Принципы формирования номеров ревизий в Bazaar&lt;/h2&gt; Каждой ревизии, которую вы фиксируете в своей ветке присваивается свой порядковый номер (revno), начиная с 1. Эти номера &lt;i&gt;неизменны&lt;/i&gt; для конкретной ветки.&lt;br&gt; &lt;br&gt; Когда вы объединяете свою ветку с другой, то должны зафиксировать результат объединения в виде новой ревизии. Эта ревизия получит свой порядковый номер как и раньше. А вот ревизии, которые были добавлены в вашу ветку в результате объединения, получат специальные новые "номера", состоящие из 3х чисел, разделенных точками (так называемые dotted revno).&lt;br&gt; &lt;br&gt; В качестве примера вернемся к нашей прошлой статье &lt;a  href="http://bzr-day.blogspot.com/2009/03/bzr-2.html"&gt;Начинаем работу с bzr: базовый набор команд (Часть 2).&lt;/a&gt; Я приведу кусочек вывода команды bzr log для ветки после объединения:&lt;br&gt; 
&lt;pre&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log -n0 
------------------------------------------------------------ 
revno: 4 [merge] 
committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
branch nick: Test 
timestamp: Tue 2009-09-08 23:50:01 +0300 
message: 
  Объединение с веткой Experimental     
------------------------------------------------------------ 
    revno: 2.1.1
    committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
    branch nick: Experimental 
    timestamp: Tue 2009-09-08 23:48:42 +0300 
    message: 
      Скорректирован файл goodbye.txt в ветке Experimental 
------------------------------------------------------------ 
revno: 3 
committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
branch nick: Test 
timestamp: Tue 2009-09-08 23:49:13 +0300 
message: 
  Скорректирован файл foo.txt в ветке Test 
------------------------------------------------------------&lt;/pre&gt; 
Обратите внимание на строки, начинающиеся с "&lt;tt&gt;revno:&lt;/tt&gt;" — они показывают номер ревизии.&lt;br&gt; &lt;br&gt; Можно видеть, что после ревизии номер 3 было произведено объединение, результат объединения зафиксирован в ревизии под номером 4. В результате объединения появилась ревизия из другой ветки, ей был присвоен номер 2.1.1.&lt;br&gt; &lt;br&gt; Ревизии с целыми номерами (без точек) образуют &lt;i&gt;главную линию разработки&lt;/i&gt; вашей ветки (&lt;i&gt;mainline&lt;/i&gt;). Ревизии, присоединенные из других веток (&lt;i&gt;merged revisions&lt;/i&gt;) являются частью полной истории ветки, но не входят в главную линию и имеют составной номер ревизии, разделенный точками (X.Y.Z).&lt;br&gt; &lt;h3&gt;Как узнать уникальные идентификаторы ревизий&lt;/h3&gt; Команда &lt;tt&gt;bzr log&lt;/tt&gt; способна отображать настоящие глобально-уникальные идентификаторы ревизий при запуске с дополнительной опцией &lt;tt&gt;--show-ids&lt;/tt&gt;:&lt;br&gt; 
&lt;pre&gt;C:\work\bzr-day\Basic-commands\Test&amp;gt;bzr log -n0 --show-ids -l3 
------------------------------------------------------------ 
revno: 4 [merge] 
revision-id: ru_bzr@googlegroups.com-20090908205001-h9q4wxqx76bi0j6u
parent: ru_bzr@googlegroups.com-20090908204913-43cyv2j60fva7w8g
parent: ru_bzr@googlegroups.com-20090908204842-5c0hseh1g4zyrzwx
committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
branch nick: Test 
timestamp: Tue 2009-09-08 23:50:01 +0300 
message: 
  Объединение с веткой Experimental     
------------------------------------------------------------ 
    revno: 2.1.1 
    revision-id: ru_bzr@googlegroups.com-20090908204842-5c0hseh1g4zyrzwx
    parent: ru_bzr@googlegroups.com-20090908204210-qegq6pfotpffqda6
    committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
    branch nick: Experimental 
    timestamp: Tue 2009-09-08 23:48:42 +0300 
    message: 
      Скорректирован файл goodbye.txt в ветке Experimental 
------------------------------------------------------------ 
revno: 3 
revision-id: ru_bzr@googlegroups.com-20090908204913-43cyv2j60fva7w8g
parent: ru_bzr@googlegroups.com-20090908204210-qegq6pfotpffqda6
committer: Базарный день &amp;lt;ru_bzr@googlegroups.com&amp;gt;
branch nick: Test 
timestamp: Tue 2009-09-08 23:49:13 +0300 
message: 
  Скорректирован файл foo.txt в ветке Test 
------------------------------------------------------------&lt;/pre&gt; 
Строки, начинающиеся на "&lt;tt&gt;revision-id:&lt;/tt&gt;" собственно отображают идентификаторы ревизий. Так, ревизии номер 4 в этой ветке соответствует уникальный идентификатор "&lt;tt&gt;ru_bzr@googlegroups.com-20090908205001-h9q4wxqx76bi0j6u&lt;/tt&gt;".&lt;br&gt; &lt;br&gt; Можно заметить, что Bazaar использует данные об авторе ревизии и дате фиксации плюс некоторые случайные данные для формирования уникального идентификатора. Однако, как я упоминал ранее, формат и содержание идентификатора — произвольные.&lt;br&gt; &lt;h3&gt;Что означают цифры в номере присоединенной ревизии&lt;/h3&gt; Правило образования номеров для присоединенных ревизий следующее: &lt;br&gt; &lt;ul&gt;   &lt;li&gt;первая цифра означает номер ревизии в главной ветке, от которой отпочковалась побочная ветка&lt;/li&gt;   &lt;li&gt;вторая цифра означает порядковый номер побочной ветки (начиная с 1)&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;третья цифра означает порядковый номер ревизии в побочной ветке, после того, как история разошлась.&lt;br&gt;   &lt;/li&gt; &lt;/ul&gt; Взглянем на граф ревизий, визуализированный при помощи команды qlog из плагина QBzr:&lt;br&gt; &lt;br&gt; &lt;small&gt;&lt;small&gt;&lt;img alt="граф ревизий"  src="http://bialix.com/bzr-day/qlog-2.png" height="110" width="632"&gt;&lt;/small&gt;&lt;/small&gt;&lt;br&gt; Ревизия 2.1.1 отпочковалась от ревизии 2 в основной ветке, имеем всего одну побочную ветку (Experimental), и одну ревизию в побочной ветке. Если бы в побочной ветке Experimental были бы еще ревизии, то они были бы пронумерованы как 2.1.2, 2.1.3 и т.д. &lt;br&gt; &lt;br&gt; В следующей части статьи мы рассмотрим, каким образом концепция главной линии разработки (mainline) влияет на работу с Bazaar.&lt;br&gt; &lt;br&gt; Примеры к статье можно найти на Launchpad.net: &lt;a  href="https://code.launchpad.net/%7Ebzr-day/bzr-day-examples/basic-test"&gt;ветка Test&lt;/a&gt;, &lt;a  href="https://code.launchpad.net/%7Ebzr-day/bzr-day-examples/basic-experimental"&gt;ветка Experimental&lt;/a&gt;.&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-3414539992284175331?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/3414539992284175331/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/09/mainline-1_08.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3414539992284175331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3414539992284175331'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/09/mainline-1_08.html' title='Mainline: главная линия разработки и номера ревизий (Часть 1)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4963598548599786356</id><published>2009-05-10T19:33:00.001+01:00</published><updated>2009-05-10T19:34:14.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><title type='text'>Разработка плагинов для bzr</title><content type='html'>&lt;div align="justify"&gt;Если вы хотите написать плагин для bzr, но не знаете с чего начать, то эта статья для вас. В этой статье я кратко расскажу об основных моментах разработки плагинов, которые вам нужно/полезно знать.&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Для успешной разработки плагина нужно знать и понимать следующие вопросы: как плагины загружаются при запуске bzr, как плагины взаимодействуют с кодом bzr, как плагин может расширять существующую функциональность bzr, как организовать код плагина. Есть также ряд менее важных сопутствующих вопросов: как распространять/устанавливать плагины, как писать тесты для плагинов.&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;h2&gt;Язык программирования&lt;/h2&gt; Bazaar написан на языке программирования &lt;a  href="http://www.python.org"&gt;Python&lt;/a&gt;. Плагины очень тесно взаимодействуют с кодом самого bzr, поэтому они также должны быть написаны на Python.&lt;br&gt; &lt;h2&gt;Документация и примеры&lt;/h2&gt; &lt;div align="justify"&gt;При разработке плагинов вам поможет следующая документация:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;Прежде всего полезно ознакомиться с кратким учебником по разработке плагинов: &lt;a href="http://bazaar-vcs.org/WritingPlugins"&gt;http://bazaar-vcs.org/WritingPlugins&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;Чтобы узнать о методах использования библиотеки &lt;tt&gt;bzrlib&lt;/tt&gt; для выполнения типичных операций, используйте документ &lt;a  href="http://bazaar-vcs.org/Integrating_with_Bazaar"&gt;http://bazaar-vcs.org/Integrating_with_Bazaar&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;Подробнее узнать о поддерживаемом API плагинов можно из документа     &lt;a  href="http://doc.bazaar-vcs.org/bzr.dev/developers/plugin-api.html"&gt;http://doc.bazaar-vcs.org/bzr.dev/developers/plugin-api.html&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;Хуки и их сигнатуры приведены в документе &lt;a  href="http://doc.bazaar-vcs.org/bzr.dev/en/user-reference/bzr_man.html#hooks"&gt;http://doc.bazaar-vcs.org/bzr.dev/en/user-reference/bzr_man.html#hooks&lt;/a&gt;&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;В качестве справочника по &lt;tt&gt;bzrlib API&lt;/tt&gt; можно использовать автоматически сгенерированную API-документацию: &lt;a  href="http://starship.python.net/crew/mwh/bzrlibapi/"&gt;http://starship.python.net/crew/mwh/bzrlibapi/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; При создании любого нетривиального плагина вам понадобится плотно работать с &lt;tt&gt;bzrlib API&lt;/tt&gt;. Поэтому вам необходимо хоть немного ориентироваться в коде библиотеки &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/files/head%3A/bzrlib/"&gt;&lt;tt&gt;bzrlib&lt;/tt&gt;&lt;/a&gt;. Библиотека довольно хорошо документирована, так что не бойтесь читать код. Также не забывайте, что для bzr написаны &lt;a  href="http://bazaar-vcs.org/BzrPlugins"&gt;десятки плагинов&lt;/a&gt; под разные задачи. Исходный код всех плагинов свободно доступен. Не стесняйтесь изучать их код. При написании своего плагина за основу можно взять имеющийся плагин с похожей функциональностью. Так вы сэкономите время.&lt;br&gt; &lt;/div&gt; &lt;h2&gt; Как bzr загружает плагин&lt;/h2&gt; &lt;div align="justify"&gt;Код загрузки плагинов содержится в модуле &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/annotate/head%3A/bzrlib/plugin.py"&gt;&lt;tt&gt;bzrlib/plugin.py&lt;/tt&gt;&lt;/a&gt;&lt;br&gt; &lt;br&gt; При старте bzr производит поиск питон-модулей и питон-пакетов в предопределенных каталогах (&lt;tt&gt;~/.bazaar/plugin&lt;/tt&gt;, &lt;tt&gt;site-packages/bzrlib/plugin&lt;/tt&gt; и т.п., подробнее см. статью &lt;a  href="http://bzr-day.blogspot.com/2009/04/bzr.html"&gt;"Плагины bzr: основные сведения"&lt;/a&gt; раздел "Как подключить плагин").&lt;br&gt; &lt;br&gt; Для всех найденных модулей и пакетов делается попытка импорта (в терминах Python). При импорте Python исполняет импортируемый код, поэтому вся инициализация плагина  и регистрация новых команд/функций/форматов/хуков должна производиться в момент импорта. Сам &lt;tt&gt;bzr&lt;/tt&gt; в момент загрузки плагина не вызывает никаких функций из импортируемого модуля. &lt;br&gt; &lt;br&gt; В случае успешного импорта плагин регистрируется для последующего использования.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Взаимодействие плагина с bzrlib&lt;/h2&gt; &lt;div align="justify"&gt;Плагины должны регистрировать новые команды и функции императивным способом: путем вызова соответствующих функций из &lt;tt&gt;bzrlib&lt;/tt&gt;. Т.е. код плагина импортирует соответствующие модули/функции из &lt;tt&gt;bzrlib&lt;/tt&gt; и затем вызывает их с необходимыми аргументами.&lt;br&gt; &lt;br&gt; Практически для всех точек расширения в &lt;tt&gt;bzrlib&lt;/tt&gt; используются реестры объектов. API объектов-реестров находится в модуле &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/annotate/head%3A/bzrlib/registry.py"&gt;&lt;tt&gt;bzrlib/registry.py&lt;/tt&gt;&lt;/a&gt;. Однако, часто регистрация расширений производится и при помощи специальных функций.  Так, например, функция регистрации новых команд &lt;tt&gt;register_command&lt;/tt&gt; находится в модуле &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/annotate/head%3A/bzrlib/commands.py"&gt;bzrlib/commands.py&lt;/a&gt;. API для регистрации хуков определено в модуле &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/annotate/head%3A/bzrlib/hooks.py"&gt;&lt;tt&gt;bzrlib/hooks.py&lt;/tt&gt;&lt;/a&gt;, однако сами хуки регистрируются для классов &lt;tt&gt;Branch&lt;/tt&gt; (&lt;tt&gt;bzrlib/branch.py&lt;/tt&gt;), &lt;tt&gt;BzrDir&lt;/tt&gt; (&lt;tt&gt;bzrlib/bzrdir.py&lt;/tt&gt;) и проч.&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Данная статья не ставит перед собой целью дать исчерпывающее описание всех точек расширения в &lt;tt&gt;bzrlib&lt;/tt&gt;. Мы постараемся осветить эти вопросы в других статьях на живых примерах. Однако помните о том, что для bzr написано множество плагинов, которые можно использовать в качестве наглядного примера использования точек расширения.&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;h2&gt;Советы по организации кода плагина&lt;/h2&gt; &lt;div align="justify"&gt;Плагин может быть одиночным модулем или питон-пакетом. Удобнее оформлять плагин как питон-пакет. В этом случае каталог с кодом плагина можно легко превратить в &lt;tt&gt;bzr&lt;/tt&gt;-ветку и использовать эту ветку для ведения разработки. Также кроме собственно кода плагина в такой ветке можно спокойно разместить тесты, дополнительные документы (такие как &lt;tt&gt;README&lt;/tt&gt;), скрипт установки &lt;tt&gt;setup.py&lt;/tt&gt; и любые дополнительные ресурсы. Дополнительным удобством такой организации является то, что любой желающий может просто поместить локальную копию ветки с вашим плагином в каталог &lt;tt&gt;~/.bazaar/plugins&lt;/tt&gt; и тем самым не только подключить плагин, но и иметь возможность легко обновлять код плагина командой &lt;tt&gt;bzr pull&lt;/tt&gt;.&lt;br&gt; &lt;/div&gt; &lt;h3&gt;Совместимость с автономной версией bzr.exe для Windows&lt;/h3&gt; &lt;div align="justify"&gt;При использовании автономной версии &lt;tt&gt;bzr.exe&lt;/tt&gt;, которая создается при помощи утилиты &lt;tt&gt;py2exe,&lt;/tt&gt; следует помнить об одной важной детали. Автономная версия &lt;tt&gt;bzr.exe&lt;/tt&gt; содержит интерпретатор Python и большую часть (но не всю!) стандартной библиотеки Python внутри. В дополнение к стандартной библиотеке внутри &lt;tt&gt;bzr.exe&lt;/tt&gt; содержатся библиотеки, необходимые для полноценной работы &lt;tt&gt;bzr&lt;/tt&gt;, такие как &lt;tt&gt;paramiko&lt;/tt&gt;, &lt;tt&gt;pyCrypto&lt;/tt&gt; и т.п. Однако, если для работы вашего плагина потребуется какая-то экзотическая библиотека, то возможности "доустановить" ее у пользователя &lt;tt&gt;bzr.exe&lt;/tt&gt; не будет. В таком случае следует предусмотреть возможность импорта дополнительных библиотек из подкаталога внутри вашего плагина. В качестве примера см. &lt;a  href="http://bazaar.launchpad.net/%7Eqbzr-dev/qbzr/trunk/annotate/head%3A/lib/__init__.py"&gt;плагин QBzr&lt;/a&gt;.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Советы по отладке плагина&lt;/h2&gt; &lt;h3&gt;Проблемы с загрузкой плагина&lt;/h3&gt; &lt;div align="justify"&gt;В случае проблем с загрузкой кода плагина (ошибки при импорте плагина) вы увидите сообщение на экране:&lt;br&gt; &lt;blockquote&gt;&lt;samp&gt;Unable to load plugin 'foo' from '...'&lt;/samp&gt;&lt;br&gt; &lt;/blockquote&gt; Полный traceback для ошибки записывается в лог-файл &lt;tt&gt;.bzr.log&lt;/tt&gt;. Точное расположение лог-файла можно узнать из вывода команды &lt;tt&gt;bzr version&lt;/tt&gt; (см. строку &lt;tt&gt;Bazaar log file&lt;/tt&gt;). &lt;br&gt; &lt;/div&gt; &lt;h3&gt;Отладочная печать&lt;/h3&gt; &lt;div align="justify"&gt;При отладке нетривиальных алгоритмов вам поможет отладочная печать. Вы конечно можете воспользоваться оператором &lt;tt&gt;print&lt;/tt&gt;, но для конечных пользователей это будет создавать ненужный шум и мусор на экране. Поэтому целесообразнее производить отладочную печать в лог-файл &lt;tt&gt;.bzr.log&lt;/tt&gt;. Для этого используйте функцию &lt;tt&gt;mutter&lt;/tt&gt; из модуля &lt;a  href="http://bazaar.launchpad.net/%7Ebzr/bzr/trunk/annotate/head%3A/bzrlib/trace.py"&gt;&lt;tt&gt;bzrlib/trace.py&lt;/tt&gt;&lt;/a&gt;:&lt;br&gt; &lt;blockquote&gt;&lt;code&gt;import trace&lt;br&gt; trace.mutter('My debug print')&lt;br&gt;   &lt;/code&gt;&lt;/blockquote&gt; Для логирования bzr использует стандартную библиотеку &lt;a  href="http://docs.python.org/library/logging.html"&gt;&lt;tt&gt;logging&lt;/tt&gt;&lt;/a&gt;.&lt;br&gt; &lt;/div&gt; &lt;h3&gt;Пошаговая отладка&lt;/h3&gt; &lt;div align="justify"&gt;В особо трудных случаях вы можете захотеть использовать отладчик. Для этого можно использовать любой отладчик для Python, как с графическим, так и с консольным интерфейсом. Очень простым вариантом создания "точки останова" в нужном месте с последующим вызовом стандартного отладчика pdb является использование следующего кода:&lt;br&gt; &lt;blockquote&gt;&lt;code&gt;import pdb; pdb.set_trace()&lt;br&gt;   &lt;/code&gt;&lt;/blockquote&gt; &lt;/div&gt; &lt;h2&gt;Публикация плагинов&lt;/h2&gt; &lt;div align="justify"&gt;Чаще всего плагины разрабатывают в отдельных ветках и публикуют их как обычные &lt;tt&gt;bzr&lt;/tt&gt;-ветки. Для публикации &lt;tt&gt;bzr&lt;/tt&gt;-плагинов удобно использовать сайт &lt;a href="https://launchpad.net/"&gt;Launchpad.net&lt;/a&gt;. При регистрации нового проекта для &lt;tt&gt;bzr&lt;/tt&gt;-плагина рекомендуется использовать приставку &lt;tt&gt;"bzr-"&lt;/tt&gt;, например &lt;tt&gt;bzr-email, bzr-svn&lt;/tt&gt;. Краткое описание вашего плагина и ссылку на страницу с кодом плагина желательно добавить на соответствующую страничку wiki: &lt;a  href="http://bazaar-vcs.org/BzrPlugins"&gt;http://bazaar-vcs.org/BzrPlugins&lt;/a&gt;.&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4963598548599786356?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4963598548599786356/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/05/bzr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4963598548599786356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4963598548599786356'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/05/bzr.html' title='Разработка плагинов для bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-8091240983701607884</id><published>2009-04-21T10:19:00.002+01:00</published><updated>2009-04-21T10:26:09.841+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><category scheme='http://www.blogger.com/atom/ns#' term='плагины'/><title type='text'>Плагины bzr: основые сведения</title><content type='html'>&lt;div align="justify"&gt;Базар имеет множество команд для выполнения своих основых функций: для просмотра изменений, для фиксирования состояния файлов и каталогов в определенные моменты времени и для работы с историей изменений. И для большей части пользователей этого достаточно. Однако существуют ситуации, когда требуются дополнительные возможности от системы контроля версий, не предоставляемые стандартной поставкой. В этом случае на сцене появляются модули расширения или плагины (plugins) для bzr.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;div align="justify"&gt;Плагины позволяют расширить возможности bzr за счет новых команд, либо за счет модификации поведения старых. Плагины могут регистрировать специальные обработчики событий (хуки/hooks), которые будут вызываться перед или после некоторых операций, например, commit, pull/push и т.д. Плагины могут добавлять новые алгоритмы обработки данных либо позволять работать с другими форматами репозиториев, например, предоставлять доступ к репозиториям других систем контроля версий. Наиболее знаменитым плагином в этом отношении является &lt;a href="http://bazaar-vcs.org/BzrForeignBranches/Subversion"&gt;bzr-svn&lt;/a&gt;, который позволяет напрямую работать с &lt;a  href="http://subversion.tigris.org/"&gt;svn&lt;/a&gt;.&lt;br&gt; &lt;h2&gt;Список плагинов&lt;/h2&gt; Список имеющихся плагинов для bzr приведен на странице &lt;a  href="http://bazaar-vcs.org/BzrPlugins"&gt;BzrPlugins&lt;/a&gt;. &lt;br&gt; &lt;br&gt; Для каждого плагина указано его краткое описание, информация об авторе (авторах) плагина, информация о совместимости с основными операционными системами (Linux/Windows/Mac). Также указан URL на страничку плагина либо bzr-ветку с его кодом. &lt;br&gt; &lt;h2&gt;Что представляют собой плагины&lt;/h2&gt; Плагины представляют собой модули или пакеты, написанные на языке программирования &lt;a href="http://python.org/"&gt;Python&lt;/a&gt;. Плагины должны писаться на Python, поскольку сама система bzr написана на Python, а плагины взаимодействуют напрямую с внутренним &lt;a  href="http://starship.python.net/crew/mwh/bzrlibapi/bzrlib.html"&gt;API bzr&lt;/a&gt;.&lt;br&gt; &lt;h2&gt;Как подключить плагин&lt;/h2&gt; При каждом запуске bzr ищет установленные плагины в следующих каталогах:&lt;br&gt; &lt;ol&gt;   &lt;li&gt;Если установлена переменная окружения &lt;tt&gt;BZR_PLUGIN_PATH&lt;/tt&gt;, то проводится поиск в списке каталогов из этой переменной&lt;/li&gt;   &lt;li&gt;Иначе проводится поиск плагинов в каталоге настроек приложения для текущего пользователя (на Linux/Mac это &lt;tt&gt;~/.bazaar/plugins&lt;/tt&gt;; на Windows это &lt;tt&gt;C:\Documents and Settings\&lt;i&gt;USERNAME&lt;/i&gt;\Application Data\bazaar\2.0\plugins&lt;/tt&gt;).&lt;/li&gt;   &lt;li&gt;Дополнительно проводится поиск в подкаталоге, где установлен bzr:&lt;/li&gt; &lt;/ol&gt; &lt;blockquote&gt;   &lt;ul&gt;     &lt;li&gt;например на Linux это может быть &lt;tt&gt;/usr/lib/python2.5/site-packages/bzrlib/plugins&lt;/tt&gt;&lt;/li&gt;     &lt;li&gt;на Windows:&lt;/li&gt;     &lt;ul&gt;       &lt;li&gt;для случая установки standalone installer это будет &lt;tt&gt;C:\Program Files\Bazaar\plugins&lt;/tt&gt; (если сам bzr установлен в каталоге &lt;tt&gt;C:\Program Files\Bazaar&lt;/tt&gt;)&lt;/li&gt;       &lt;li&gt;для случая установки как python-программы — аналогично Linux в каталоге &lt;tt&gt;site-packages/bzrlib/plugins&lt;br&gt;         &lt;/tt&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/ul&gt; &lt;/blockquote&gt; Если плагин находится в указанных каталогах, то он будет загружен. Никаких специальных настроек для разрешения или запрещения плагина не требуется. Для того чтобы отключить плагин достаточно удалить плагин из соответствующего каталога.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Установка плагинов&lt;/h2&gt; &lt;div align="justify"&gt;Многие популярные плагины имеют специальные пакеты для установки на Linux. Они могут быть установлены/удалены обычным образом при помощи менеджера пакетов.&lt;br&gt; &lt;br&gt; Рассмотрим установку плагина из исходного кода. &lt;br&gt; &lt;br&gt; Большинство плагинов работают прямо из исходного кода и не требуют специальных действий для установки. Достаточно просто поместить каталог (или ветку) с кодом плагина в каталог &lt;tt&gt;plugins&lt;/tt&gt;. Однако все-таки стоит изучить имеющийся файл &lt;tt&gt;README&lt;/tt&gt; или &lt;tt&gt;INSTALL&lt;/tt&gt; на предмет дополнительных инструкций по установке. &lt;br&gt; &lt;br&gt; Следует также помнить о том, что часто код плагинов размещается на сайте &lt;a href="http://launchpad.net"&gt;Launchpad.net&lt;/a&gt;, который предоставляет бесплатный хостинг для проектов и/или bzr-веток. В этом случае страница bzr-плагина зачастую имеет приставку &lt;tt&gt;"bzr-"&lt;/tt&gt; в имени плагина (чтобы подчеркнуть свою принадлежность).  При установке плагина эту приставку нужно опустить, плюс все дефисы в названии поменять на знак подчеркивания. Так, например, плагин &lt;tt&gt;bzr-gtk&lt;/tt&gt; должен устанавливаться в каталог &lt;tt&gt;gtk&lt;/tt&gt;, а плагин &lt;tt&gt;bzr-x-bit&lt;/tt&gt; в каталог &lt;tt&gt;x_bit&lt;/tt&gt;. Каталог, в котором должен помещаться код плагина, часто жестко предопределен и при его изменении плагин в большинстве случаев оказывается неработоспособным.&lt;br&gt; &lt;br&gt; Рассмотрим установку на примере плагина &lt;a  href="https://launchpad.net/bzr-merge-into"&gt;&lt;tt&gt;merge-into&lt;/tt&gt;&lt;/a&gt;:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;перейти в каталог plugins: &lt;tt&gt;&lt;br&gt; cd ~/.bazaar/plugins&lt;/tt&gt;&lt;/li&gt;   &lt;li&gt;получить копию ветки с launchpad.net: &lt;br&gt;     &lt;tt&gt;bzr branch lp:bzr-merge-into merge_into&lt;/tt&gt;&lt;/li&gt; &lt;/ul&gt; В каталоге &lt;tt&gt;merge_into&lt;/tt&gt; будет создана копия ветки плагина. Таким образом вы сможете легко обновлять свою копию плагина, когда автор плагина опубликует новую функциональность или исправления найденных ошибок.&lt;br&gt; &lt;br&gt; Чтобы убедиться в том, что плагин установлен корректно, запустите команду &lt;tt&gt;bzr plugins&lt;/tt&gt;. Ваш плагин должен присутствовать в списке, который выдает эта команда:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\&amp;gt;bzr plugins&lt;br&gt; bzrtools 1.13&lt;br&gt;     Various useful commands for working with bzr.&lt;br&gt; &lt;br&gt; launchpad&lt;br&gt;     Launchpad.net integration plugin for Bazaar.&lt;br&gt; &lt;br&gt; merge_into&lt;br&gt;     Provide the 'merge-into' command.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Многие плагины содержат набор тестов, которые можно использовать для проверки работоспособности плагина на вашей платформе или для проверки совместимости с используемой версией bzr. Для запуска тестов конкретного плагина используйте команду &lt;tt&gt;selftest&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\&amp;gt;bzr selftest -s bp.merge_into&lt;br&gt; testing: C:/Program Files/Bazaar/bzr.EXE&lt;br&gt;    C:\Program Files\Bazaar\lib\library.zip\bzrlib (1.13.1 python2.5.4)&lt;br&gt; &lt;br&gt; [5/5 in 4s] bzrlib.plugins.merge_into.test_bb_merge_into.TestMergeInto.test_smoke&lt;br&gt; ----------------------------------------------------------------------&lt;br&gt; Ran 5 tests in 5.125s&lt;br&gt; &lt;br&gt; OK&lt;br&gt; tests passed&lt;br&gt; &lt;/samp&gt; &lt;h2&gt;Справочная информация о плагине&lt;/h2&gt; Для получения справки о плагине посмотрите файл &lt;tt&gt;README&lt;/tt&gt;, поставляемый с кодом плагина, либо используйте команду &lt;tt&gt;help&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\&amp;gt;bzr help merge_into&lt;br&gt; Provide the 'merge-into' command.&lt;br&gt; &lt;br&gt; This command allows you to merge other branches into subdirectories, rather&lt;br&gt; than always merging into root, and then needing to be moved around.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Некоторые плагины добавляют большое количество команд, не все из которых описаны в скудной справке к плагину. Отыскать все команды нам поможет команда &lt;tt&gt;bzr help commands&lt;/tt&gt; и утилита &lt;tt&gt;grep&lt;/tt&gt;. Например, найдем все команды, предоставляемые популярным плагином &lt;tt&gt;bzrtools&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\&amp;gt;bzr help commands | grep bzrtools&lt;br&gt; branch-history     Display the development history of a branch. [bzrtools]&lt;br&gt; branches           Scan a location for branches [bzrtools]&lt;br&gt; cbranch            Create a new checkout, associated with a new repository branch. [bzrtools]&lt;br&gt; cdiff              A color version of bzr's diff [bzrtools]&lt;br&gt; clean-tree         Remove unwanted files from working tree. [bzrtools]&lt;br&gt; fetch-ghosts       Attempt to retrieve ghosts from another branch. [bzrtools]&lt;br&gt; graph-ancestry     Produce ancestry graphs using dot. [bzrtools]&lt;br&gt; heads              Show all revisions in a repository not having descendants. [bzrtools]&lt;br&gt; import             Import sources from a directory, tarball or zip file [bzrtools]&lt;br&gt; link-tree          Hardlink matching files to another tree. [bzrtools]&lt;br&gt; multi-pull         Pull all the branches under a location, e.g. a repository. [bzrtools]&lt;br&gt; patch              Apply a named patch to the current tree. [bzrtools]&lt;br&gt; rspush             Upload this branch to another location using rsync. [bzrtools]&lt;br&gt; shelf1             Perform various operations on your shelved patches. See also shelve1. [bzrtools]&lt;br&gt; shell              Begin an interactive shell tailored for bzr. [bzrtools]&lt;br&gt; shelve1            Temporarily set aside some changes from the current tree. [bzrtools]&lt;br&gt; trees              Scan a location for trees [bzrtools]&lt;br&gt; unshelve1          Restore shelved changes. [bzrtools]&lt;br&gt; zap                Remove a lightweight checkout, if it can be done safely. [bzrtools]&lt;/samp&gt;&lt;br&gt; &lt;blockquote&gt;&lt;i&gt;Примечание:&lt;/i&gt; пользователям Windows необходимо установить утилиту &lt;tt&gt;&lt;a  href="http://gnuwin32.sourceforge.net/packages/grep.htm"&gt;grep&lt;/a&gt;&lt;/tt&gt; самостоятельно.&lt;br&gt; &lt;/blockquote&gt; &lt;h2&gt;Временное отключение плагинов&lt;/h2&gt; &lt;div align="justify"&gt;В некоторых (редких) случаях  может потребоваться запустить команду bzr без плагинов. В этом случае вы можете использовать &lt;a  href="http://doc.bazaar-vcs.org/latest/en/user-reference/bzr_man.html#global-options"&gt;глобальную опцию&lt;/a&gt; командной строки &lt;tt&gt;--no-plugins&lt;/tt&gt;. Глобальные опции должны указываться после имени программы (bzr) и перед собственно командой. Так, например, следующая команда выведет список только встроенных команд:&lt;br&gt; &lt;br&gt; &lt;tt&gt;bzr --no-plugins help commands&lt;/tt&gt;&lt;br&gt; &lt;br&gt; Имеется еще одна глобальная опция, воздействующая на плагины: &lt;tt&gt;--builtin&lt;/tt&gt;. При использовании этой опции плагины загружаются как обычно, но при этом плагинам запрещается декорирование команд. Т.е. плагины не смогут зарегистрировать новую команду с именем, которое совпадает с именем встроенной команды. Эта опция полезна прежде всего для целей отладки.&lt;br&gt; &lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-8091240983701607884?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/8091240983701607884/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/04/bzr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/8091240983701607884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/8091240983701607884'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/04/bzr.html' title='Плагины bzr: основые сведения'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5219632780936359999</id><published>2009-04-05T22:23:00.002+01:00</published><updated>2009-05-14T09:11:39.150+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='настройки'/><title type='text'>Автоматический whoami при работе через SSH</title><content type='html'>&lt;div align="justify"&gt;В статье рассматривается простой пример использования (документированных) возможностей как &lt;tt&gt;sshd&lt;/tt&gt;, так и &lt;tt&gt;bzr&lt;/tt&gt;, для автоматической установки идентификатора пользователя при работе на удаленной машине.&lt;br&gt; &lt;/div&gt; &lt;h2&gt;Сценарий&lt;/h2&gt; &lt;div align="justify"&gt;Имеется общий компьютер, на котором могут работать несколько человек под одной учетной записью. Этот компьютер может использоваться как тестовый полигон, либо как машина для компиляции окончательной версии программы, или для сборки инсталляционных пакетов. Либо же это тестовый/боевой сервер, на котором запущен веб-сайт или другое приложение. Разработчики используют &lt;tt&gt;SSH&lt;/tt&gt; для работы на этом общем компьютере.&lt;br&gt; &lt;br&gt; Для отслеживания изменений, производимых разработчиками на общем компьютере, используется одна или несколько bzr-веток. &lt;br&gt; &lt;h2&gt;Проблема&lt;/h2&gt; При такой совместной работе остро стоит вопрос адекватной идентификации разработчиков, которые фиксировали свои изменения. По умолчанию bzr использует автоматический идентификатор, состоящий из имени учетной записи и имени компьютера, например: &lt;tt&gt;root@server&lt;/tt&gt;. А поскольку под одной учетной записью могут работать несколько человек, то нельзя установить глобальный идентификатор через команду &lt;a  href="http://bzr-day.blogspot.com/2009/02/bzr-whoami.html"&gt;&lt;tt&gt;bzr whoami&lt;/tt&gt;&lt;/a&gt;.&lt;br&gt; &lt;h2&gt;Способы идентификации&lt;/h2&gt; Базар позволяет идентифицировать автора ревизии несколькими способами: глобальная идентификация, идентификация на уровне ветки, или через использование переменных окружения.&lt;br&gt; &lt;br&gt; &lt;/div&gt; &lt;div align="justify"&gt;При всем богатстве выбора, для рассматриваемого сценария работы подходят далеко не все варианты. Первый вариант (глобальная идентификация), как мы уже сказали ранее, здесь категорически не приемлем. Вариант с идентификацией на уровне отдельной ветки может подойти, если каждый разработчик имеет отдельную ветку и работает только в ней. Чаще всего это не так, да и легко забыть о необходимости настраивать идентификатор для каждой новой ветки. Так что этот вариант скорее всего тоже отпадает.&lt;br&gt; &lt;/div&gt; &lt;div align="justify"&gt;&lt;br&gt; Остается вариант с использованием переменных окружения. Базар использует значение переменной окружения &lt;tt&gt;BZR_EMAIL&lt;/tt&gt; или &lt;tt&gt;EMAIL&lt;/tt&gt; в качестве идентификатора пользователя. Если одна из этих переменных определена, то она имеет приоритет как над глобальным идентификатором, так и над идентификацией на уровне ветки.&lt;br&gt; &lt;div align="justify"&gt;&lt;/div&gt; &lt;br&gt; Вариант с использованием переменных окружения тоже имеет свой недостаток: в начале каждой новой &lt;tt&gt;SSH-&lt;/tt&gt;сессии разработчик должен установить переменную окружения &lt;tt&gt;BZR_EMAIL&lt;/tt&gt;. О необходимости установки этой переменной легко забыть. К счастью имеется возможность автоматизировать этот скучный процесс при использовании аутентификации пользователей при помощи SSH-ключей.&lt;br&gt; &lt;h2&gt;Использование файла authorized_keys&lt;/h2&gt; При аутентификации при помощи SSH-ключей используется файл &lt;tt&gt;~/.ssh/authorized_keys&lt;/tt&gt; (или &lt;tt&gt;~/.ssh/authorized_keys2&lt;/tt&gt;). В этом файле сохраняется список публичных SSH-ключей, которым &lt;a  href="http://www.opennet.ru/cgi-bin/opennet/man.cgi?topic=sshd#lbAL"&gt;разрешена аутентификация&lt;/a&gt;. Однако кроме самих ключей, дополнительно могут быть указаны различные параметры соединения, либо ограничения доступа, либо директивы запуска некоторой программы при аутентификации конкретным ключом. Либо директива установки переменной окружения при аутентификации конкретным ключем. Именно эта директива нам и нужна.&lt;br&gt; &lt;br&gt; Директива установки переменной окружения при логине указывается в виде:&lt;br&gt; &lt;blockquote&gt;&lt;tt&gt;environment="ИМЯ=значение"&lt;/tt&gt;&lt;br&gt; &lt;/blockquote&gt; Подробнее о формате и параметрах в файле &lt;tt&gt;authorized_keys&lt;/tt&gt; читайте в &lt;tt&gt;&lt;a  href="http://www.opennet.ru/cgi-bin/opennet/man.cgi?topic=sshd#lbAL"&gt;man sshd&lt;/a&gt;&lt;/tt&gt;. &lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Таким образом для настройки автоматической идентификации пользователей необходимо применить вход на общий компьютер через SSH-ключи, и для каждого пользователя (перед его публичным ключем) указать свою директиву &lt;tt&gt;environment&lt;/tt&gt;, например:&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;tt&gt;&lt;b&gt;--------------------Файл: authorized_keys-------------------------------------&lt;br&gt; &lt;/b&gt;environment=&lt;a class="moz-txt-link-rfc2396E"  href="mailto:BZR_EMAIL=bialix@ukr.net"&gt;"BZR_EMAIL=Vasya Pupkin &amp;lt;pupkin@mail.ru&amp;gt;"&lt;/a&gt; ssh-dss AAAAB3NzaC1kc3MAAACAcdSwa...&lt;br&gt; &lt;b&gt;------------------------------------------------------------------------------&lt;br&gt; &lt;/b&gt;&lt;/tt&gt;&lt;br&gt; &lt;div align="justify"&gt;Таким образом каждый из участников проекта может работать в любой ветке на общем компьютере, и все фиксируемые изменения будут сохраняться от имени конкретного человека.&lt;br&gt; &lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5219632780936359999?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5219632780936359999/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/04/whoami-ssh.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5219632780936359999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5219632780936359999'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/04/whoami-ssh.html' title='Автоматический whoami при работе через SSH'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-9220349017339909238</id><published>2009-04-03T03:16:00.001+01:00</published><updated>2009-04-03T19:24:25.699+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Работа с ветками: push, pull, merge (Часть 3)</title><content type='html'>&lt;div align="justify"&gt;Рассмотрим еще &lt;a  href="http://bzr-day.blogspot.com/2009/03/push-pull-merge-2.html"&gt;один пример&lt;/a&gt; &lt;a  href="http://bzr-day.blogspot.com/2009/03/push-pull-merge-1.html"&gt;работы с ветками&lt;/a&gt;: совместная работа над проектом в небольшом коллективе. Для определенности будем рассматривать коллектив из 2х человек, поскольку приводимый сценарий легко масштабируется и на большее количество участников.&lt;br&gt; &lt;h2&gt;Сценарий №2&lt;/h2&gt; Над созданием программы под кодовым названием MegaApp работают Иван и Сергей. У них есть общее хранилище для веток проекта на центральном сервере. Там находится главная ветка проекта под названием &lt;tt&gt;trunk&lt;/tt&gt;. Каждый из участников проекта, Иван и Сергей, имеет локальную копию главной ветки на своем компьютере и периодически синхронизирует ее с оригиналом на сервере.&lt;br&gt; &lt;br&gt; Для реализации новой функции Иван создает новую копию ветки &lt;tt&gt;trunk&lt;/tt&gt; для локальной работы. Иван пишет новую функциональность, фиксирует изменения, тестирует свой код в локальной рабочей ветке. Когда работа над новой функцией завершена Иван объединяет свои изменения с копией главной ветки, фиксирует результат объединения и отправляет новые ревизии в главную ветку на сервере.&lt;br&gt; &lt;br&gt; Для исправления найденного дефекта в программе Сергей создает новую копию ветки &lt;tt&gt;trunk&lt;/tt&gt; для локальной работы. Сергей находит причину дефекта и исправляет его, фиксирует изменения, тестирует свой код в локальной рабочей ветке. Когда работа над исправлением дефекта завершена Сергей объединяет свои изменения с копией главной ветки, фиксирует результат объединения и отправляет новые ревизии в главную ветку на сервере.&lt;br&gt; &lt;h2&gt;Главная ветка проекта&lt;/h2&gt; С технической точки зрения для Базара все ветки равны. Однако в любом проекте должна быть &lt;i&gt;главная ветка&lt;/i&gt;, которая используется всеми участниками проекта для синхронизации, в которую попадают новые изменения, багфиксы, из которой в конечном счете формируются окончательные версии (релизы) вашего продукта. Такая ветка является центральным связующим звеном для проекта.&lt;br&gt; &lt;br&gt; Поскольку в распределенных системах все ветки равноправны, то участники проекта должны договориться какую ветку использовать в качестве главной. Имя такой ветки может быть произвольным, но наиболее часто используются такие имена: &lt;b&gt;&lt;tt&gt;trunk&lt;/tt&gt;, &lt;tt&gt;main&lt;/tt&gt;, &lt;tt&gt;dev&lt;/tt&gt;&lt;/b&gt;.&lt;br&gt; &lt;blockquote&gt;Имя &lt;tt&gt;trunk&lt;/tt&gt; пришло из &lt;tt&gt;svn&lt;/tt&gt;. По английски "trunk" означает "ствол" (ствол дерева), как противоположность просто веткам (branch), которые ответвляются от ствола.&lt;br&gt; &lt;/blockquote&gt; &lt;div align="justify"&gt; &lt;h2&gt;Центральное хранилище&lt;/h2&gt; Для хранения эталонной главной ветки, с которой все участники проекта будут периодически синхронизироваться, нужно какое-либо центральное хранилище, или центральный сервер. Базар поддерживает различные типы серверов для хранения веток: SFTP, FTP, специализированный bzr-сервер, можно даже задействовать какой-то общий каталог на одной из машин (в сети Windows) или на SAMBA-сервере. Выбор того или иного варианта зависит от конкретной ситуации.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;div align="justify"&gt;Далее в примерах будет использоваться локальный bzr-сервер, запущенный командой:&lt;br&gt; &lt;blockquote&gt;&lt;tt&gt;bzr serve --allow-writes --directory C:/work/bzr-day/server&lt;/tt&gt;&lt;br&gt; &lt;/blockquote&gt; где опция &lt;tt&gt;--directory&lt;/tt&gt; указывает каталог, в котором располагаются ветки. Используйте любой другой удобный для вас каталог.&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;div align="justify"&gt; &lt;blockquote&gt;Будьте внимательны: &lt;tt&gt;bzr&lt;/tt&gt;-сервер не осуществляет никакую авторизацию пользователей, и с опцией &lt;tt&gt;--allow-writes&lt;/tt&gt; разрешает любому клиенту операции как чтения так и записи. &lt;tt&gt;bzr&lt;/tt&gt;-сервер использует порт 4155 для работы.&lt;br&gt; &lt;/blockquote&gt; &lt;h2&gt;Создание главной ветки на сервере&lt;/h2&gt; Иван использует команду &lt;tt&gt;init&lt;/tt&gt; (или &lt;tt&gt;push&lt;/tt&gt;), чтобы создать ветку &lt;tt&gt;trunk &lt;/tt&gt;на сервере:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan&amp;gt;bzr init bzr://localhost/trunk&lt;br&gt; Created a standalone branch (format: unnamed)&lt;/samp&gt;&lt;br&gt; &lt;h2&gt;Создание локальной копии главной ветки&lt;/h2&gt; Для работы над проектом Ивану необходима локальная копия главной ветки. Для получения главной ветки с сервера Иван использует команду &lt;tt&gt;branch&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan&amp;gt;bzr branch bzr://localhost/trunk&lt;br&gt; Branched 0 revision(s).&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;div align="justify"&gt;Ветка совсем пустая (0 revisions), поэтому Иван решает сделать первую фиксацию прямо в ней и обновить ветку на сервере:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan\trunk&amp;gt;bzr commit -m initial --unchanged&lt;br&gt; Committing to: C:/work/bzr-day/ivan/trunk/&lt;br&gt; Committed revision 1.&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;bzr push bzr://localhost/trunk&lt;br&gt; Pushed up to revision 1.&lt;/samp&gt;&lt;br&gt; &lt;h2&gt;Рекомендации по работе над проектом&lt;/h2&gt; Участники проекта могут изменять файлы и фиксировать новые ревизии прямо в своей копии ветки &lt;tt&gt;trunk&lt;/tt&gt;, однако целесообразнее использовать отдельные ветки (так называемые &lt;a  href="http://bzr-day.blogspot.com/2009/03/bzr-2.html"&gt;feature branches или функциональные ветки&lt;/a&gt;). Для чего это нужно?&lt;br&gt; &lt;br&gt; При работе над сложным проектом редко когда новую функцию удается реализовать быстро, гораздо чаще требуется длительный промежуток времени (больше чем 5-10 минут). Работа над сложными функциями может состоять из реализации нескольких последовательных этапов работы. Каждый такой логический этап можно (и нужно) фиксировать командой &lt;tt&gt;commit&lt;/tt&gt;. При этом что-то может быть недоделано или программа вообще откажется работать. Фиксировать неработоспособный код прямо в &lt;tt&gt;trunk&lt;/tt&gt; — это очень плохая идея. Ваш коллега по работе может взять новый неработоспособный код, не подозревая об этом, и получить в нагрузку кучу неприятной головной боли. Всегда старайтесь держать в &lt;tt&gt;trunk &lt;/tt&gt;&lt;i&gt;только&lt;/i&gt; работоспособный (комплирующийся, протестированный) код.&lt;br&gt; &lt;/div&gt; &lt;br&gt; Еще одним плюсом функциональных веток является логическая группировка ревизий. Гораздо удобнее анализировать историю проекта, когда ревизии, относящиеся к реализации конкретной функции, идут в журнале вместе. Если же каждый разработчик фиксирует свои изменения прямо в &lt;tt&gt;trunk &lt;/tt&gt;и часто делает &lt;tt&gt;push &lt;/tt&gt;в главную ветку, то в результате история изменений становится запутанной, как куча спагетти. Хотите ли вы этого?&lt;br&gt; &lt;br&gt; Это не все &lt;a  href="http://divmod.org/trac/wiki/UltimateQualityDevelopmentSystem#WhyBranches"&gt;причины в пользу использования функциональных веток&lt;/a&gt;, но две наиболее серьезные.&lt;br&gt; &lt;blockquote&gt;Правило использования функциональных веток — это не догма, но полезная рекомендация.&lt;br&gt; &lt;/blockquote&gt; &lt;h2&gt;Иван работает над новой функцией&lt;/h2&gt; Иван начинает работу над новой функцией с того, что обновляет свою локальную копию главной ветки, и затем создает отдельную ветку для работы:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan\trunk&amp;gt;bzr pull&lt;br&gt; Using saved parent location: bzr://localhost/trunk/&lt;br&gt; No revisions to pull.&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;cd ..&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan&amp;gt;bzr branch trunk feature&lt;br&gt; Branched 1 revision(s).&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan&amp;gt;cd feature&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Иван пишет новый код, фиксирует каждый логически законченный этап, тестирует его...&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan\feature&amp;gt;bzr st&lt;br&gt; ...&lt;br&gt; C:\work\bzr-day\ivan\feature&amp;gt;bzr diff&lt;br&gt; ...&lt;br&gt; C:\work\bzr-day\ivan\feature&amp;gt;bzr commit ...&lt;br&gt; ...&lt;br&gt; C:\work\bzr-day\ivan\feature&amp;gt;bzr log&lt;br&gt; ...&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Наконец, работа над новой функцией закончена и Иван объединяет главную ветку со своей работой:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan\feature&amp;gt;cd ../trunk&lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;bzr merge ../feature&lt;br&gt; +N  foo.c&lt;br&gt; All changes applied successfully.&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;bzr status&lt;br&gt; added:&lt;br&gt;   foo.c&lt;br&gt; pending merge tips: (use -v to see all merge revisions)&lt;br&gt;   Базарный день 2009-03-31 Реализована и протестирована новая функция foo&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;bzr status -v&lt;br&gt; added:&lt;br&gt;   foo.c&lt;br&gt; pending merges:&lt;br&gt;   Базарный день 2009-03-31 Реализована и протестирована новая функция foo&lt;br&gt;     Базарный день 2009-03-31 Исправлена ошибка в функции foo&lt;br&gt;     Базарный день 2009-03-31 Реализован базовый алгоритм функции foo&lt;br&gt; &lt;br&gt; C:\work\bzr-day\ivan\trunk&amp;gt;bzr commit -m "Реализована функция foo"&lt;br&gt; Committing to: C:/work/bzr-day/ivan/trunk/&lt;br&gt; added foo.c&lt;br&gt; Committed revision 2.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; После чего можно отправлять новые ревизии на сервер командой &lt;tt&gt;push&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\ivan\trunk&amp;gt;bzr push bzr://localhost/trunk&lt;br&gt; Pushed up to revision 2.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Подобным образом работают все участники проекта.&lt;br&gt; &lt;h2&gt;Сергей работает над исправлением найденного дефекта&lt;/h2&gt; Работа над исправлением дефекта для Сергея мало отличается от написания новой функции программы. Сергей точно также использует отдельную ветку для работы и в конце объединяет главную ветку со своими изменениями:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;обновить локальную копию главной ветки (&lt;tt&gt;bzr pull&lt;/tt&gt;)&lt;/li&gt;   &lt;li&gt;создать отдельную ветку для работы (&lt;tt&gt;bzr branch trunk bugfix&lt;/tt&gt;)&lt;/li&gt;   &lt;li&gt;проделать работу в отдельной ветке (&lt;tt&gt;status, diff, commit, log&lt;/tt&gt;)&lt;/li&gt;   &lt;li&gt;объединить локальную копию главной ветки со своими изменениями (&lt;tt&gt;bzr merge ../bugfix&lt;/tt&gt;)&lt;/li&gt;   &lt;li&gt;передать новые ревизии в главную ветку на центральном сервере (&lt;tt&gt;bzr push&lt;/tt&gt;)&lt;br&gt;   &lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;h2&gt;Регулярная синхронизация с главной веткой&lt;/h2&gt; &lt;div align="justify"&gt;При длительной уединенной работе в отдельной ветке следует помнить о том, что ваши коллеги по проекту не спят и тоже пишут новый код. Поэтому чем дольше вы работаете над новыми функциями или багфиксами, тем выше вероятность, что кто-то из коллег сделает изменения, которые будут влиять на вашу работу. Это может быть и простое исправление опечатки в коде или комментариях, массивный &lt;a  href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3"&gt;рефакторинг&lt;/a&gt;, либо просто частичное изменение API используемых вами модулей. В первых двух случаях у вас возникнут конфликты при объединении вашей законченной работы и &lt;tt&gt;trunk&lt;/tt&gt;. В случае изменения API вы получите неработоспособную программу. Поэтому необходима регулярно обновлять свою копию ветки trunk и синхронизировать свою работу с ней.&lt;br&gt;&lt;/div&gt; &lt;div align="justify"&gt;Рассмотрим следующий пример. Иван работает над новой сложной функцией программы не первый день. В это время Сергей исправляет найденный дефект в коде одного из модулей, и свои исправления публикует в ветке &lt;tt&gt;trunk&lt;/tt&gt;. Исправления Сергея затрагивают код, над которым работает Иван. Иван время от времени обновляет копию главной ветки и просматривает новые ревизии. Когда он замечает, что появились изменения, влияющие на его работу, то Иван объединяет новые ревизии из trunk со своей веткой, исправляет возможные несоответствия в своем коде и продолжает работу в своей ветке. &lt;br&gt; &lt;br&gt; Вот как этот пример выглядит в командах &lt;tt&gt;bzr&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; Иван работает в своей ветке bigfeature над новой сложной функцией:&lt;br&gt; &lt;br&gt; &lt;samp&gt;bzr branch trunk bigfeature&lt;br&gt; cd bigfeature&lt;br&gt; hack-hack-hack&lt;br&gt; bzr diff&lt;br&gt; bzr commit&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Иван периодически обновляет свою копию trunk, просматривает новые ревизии и обнаруживает появление багфикса от Сергея:&lt;br&gt; &lt;br&gt; &lt;samp&gt;cd ../trunk&lt;br&gt; bzr pull&lt;br&gt; bzr log&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Для того, чтобы увидеть только новые ревизии в главной ветке, которые отсутствуют в ветке bigfeature Иван может воспользоваться командой &lt;tt&gt;missing&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;cd ../bigfeature&lt;br&gt; bzr missing --theirs-only ../trunk&lt;br&gt; &lt;/samp&gt;&lt;/div&gt; &lt;br&gt; Флаг &lt;tt&gt;--theirs-only&lt;/tt&gt; указывает команде &lt;tt&gt;missing&lt;/tt&gt;, что пользователя интересует только информация о новых ревизиях в ветке &lt;tt&gt;trunk&lt;/tt&gt;.&lt;br&gt; &lt;br&gt; Иван решает, что ему нужно объединить новые правки из &lt;tt&gt;trunk&lt;/tt&gt; с его собственной работой и делает &lt;tt&gt;merge&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;cd ../bigfeature&lt;br&gt; bzr merge ../trunk&lt;br&gt; bzr diff&lt;br&gt; bzr commit -m "merge trunk"&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Теперь Иван может продолжать свою работу, имея в своей ветке все последние необходимые ему изменения и багфиксы.&lt;br&gt; &lt;h2&gt;Резюме&lt;/h2&gt; &lt;div align="justify"&gt;Итак, мы рассмотрели основные моменты совместной работы над проектом. Данный сценарий характерен для работы с распределенными системами контроля версий, но может и варьироваться в зависимости от нужд коллектива разработчиков. В больших командах может практиковаться ревью нового кода другими (опытными) разработчиками, в этом случае по окончании работы новая функциональная ветка публикуется на центральном сервере, чтобы те, кто будет делать ревью, имели к ней свободный доступ. После ревью объединение нового кода с главной веткой может делать или автоматическая система объединения, либо специально назначенный человек. Выбирайте необходимый вам вариант работы.&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-9220349017339909238?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/9220349017339909238/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/04/push-pull-merge-3.html#comment-form' title='Комментарии: 11'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/9220349017339909238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/9220349017339909238'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/04/push-pull-merge-3.html' title='Работа с ветками: push, pull, merge (Часть 3)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-6517953543307326380</id><published>2009-03-30T13:52:00.027+01:00</published><updated>2009-04-01T12:33:10.257+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='протоколы'/><category scheme='http://www.blogger.com/atom/ns#' term='настройки'/><title type='text'>Использование WebDAV для доступа к Bazaar-серверу</title><content type='html'>&lt;div align="justify"&gt;При совместной работе группы разработчиков над проектом с использованием Bazaar практически всегда необходимо организовывать некоторое центральное хранилище (центральный сервер) для рабочих веток. Имеется несколько вариантов организации такого сервера, поскольку сам Bazaar поддерживает несколько транспортных протоколов для удаленной работы. Кратко рассмотрим имеющиеся варианты.
&lt;h2&gt;Варианты доступа к удаленному серверу&lt;/h2&gt; &lt;/div&gt; &lt;div align="justify"&gt; &lt;ul&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;bzr://&lt;/span&gt; — "умный" (smart) протокол Bazaar. Это наиболее функциональный и производительный протокол удаленного доступа, использующий встроенный в Bazaar сервер. К сожалению, на данный момент, не имеет возможности аутентифицировать пользователей и управлять доступом. По этим причинам не рекомендуется использовать его самостоятельно, а только в связке с SSH или HTTP/HTTPS:&lt;/li&gt;   &lt;ul&gt;     &lt;li&gt;&lt;a href="http://doc.bazaar-vcs.org/latest/en/user-guide/index.html#running-a-smart-server"&gt;&lt;span style="font-style: italic;"&gt;bzr+ssh://&lt;/span&gt;&lt;/a&gt; — использует &lt;span style="font-style: italic;"&gt;bzr://&lt;/span&gt; протокол через SSH-туннель. Совмещает функциональность и производительность протокола &lt;span style="font-style: italic;"&gt;bzr://&lt;/span&gt; с безопасностью протокола SSH. Наиболее часто используемый в среде Unix/Linux и наиболее часто рекомендуемый протокол удаленного доступа.&lt;/li&gt;     &lt;li&gt;&lt;i&gt;&lt;a href="http://doc.bazaar-vcs.org/latest/en/user-guide/index.html#serving-bazaar-with-fastcgi"&gt;bzr+http://&lt;/a&gt;&lt;/i&gt; — использует &lt;i&gt;bzr://&lt;/i&gt; протокол совместно с web-сервером Apache и модулем FastCGI или mod_python. Для авторизации пользователей используются механизмы, встроенные в Apache.
 &lt;/li&gt;   &lt;/ul&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;sftp://&lt;/span&gt; — для доступа используется протокол SFTP, поддерживаемый большинством SSH серверов. Может быть хорошей альтернативой &lt;i&gt;bzr+ssh://&lt;/i&gt;, например, в случае отсутствия на сервере Bazaar.&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;ftp://&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;aftp://&lt;/span&gt; — доступ с использованием пассивного (и соотв. активного) режимов FTP. Позволяет давать доступ на запись, но &lt;a href="http://en.wikipedia.org/wiki/File_Transfer_Protocol#Security_problems"&gt;имеет проблемы с безопасностью&lt;/a&gt;.
&lt;/li&gt;   &lt;li&gt;&lt;span style="font-style: italic;"&gt;http://&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;https://&lt;/span&gt; — доступ только для чтения с использованием протоколов HTTP и HTTPS. Хороший вариант если нужен только доступ на чтение.
&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div align="justify"&gt;Из всех рассмотренных выше протоколов только bzr:// (bzr+ssh:// bzr+http://) поддерживают работу с подключаемыми модулями или плагинами (plugins) Bazaar на сервере, т.к. используют встроенный в Bazaar сервер. Остальные же протоколы только предоставляют доступ локальному клиенту Bazaar к данным на удаленном сервере.
&lt;h2&gt;Зачем нужен доступ по протоколу WebDAV?&lt;/h2&gt; Достаточно часто встречается ситуация, когда для обеспечения политики безопасности, или по другим причинам, нет возможности использовать ни один из перечисленных выше протоколов. Такая ситуация может возникать в случае если нужен удаленный доступ на запись, но нельзя использовать SSH/SFTP, потому что необходимо создавать системные учетные записи. При этом FTP тоже отпадает, поскольку он считается недостаточно безопасным.

&lt;div align="justify"&gt;Именно для таких случаев был создан плагин для bzr, который позволяет организовать удаленный доступ по протоколу WebDAV.
&lt;/div&gt; &lt;/div&gt;
&lt;div align="justify"&gt;&lt;a href="http://ru.wikipedia.org/wiki/WebDAV"&gt;WebDAV&lt;/a&gt; — это набор расширений для протокола HTTP, позволяющий пользователям совместное редактирование и управление файлами на удаленных WEB-серверах. Таким образом, он, как и HTTP/HTTPS, обеспечивает для Bazaar доступ к данным на удаленном сервере, но предоставляет при этом также и возможность их изменения. Одно из основных преимуществ использования WebDAV — это возможность использования стандартных средств HTTP-сервера для управления аутентификацией и доступом пользователей.
&lt;/div&gt;
Для работы через WebDAV нам понадобится установить плагин на стороне клиента (на локальной машине) и настроить HTTP сервер (в нашем примере Apache) для работы с WebDAV.
&lt;h2&gt;Установка плагина WebDAV&lt;/h2&gt; Плагин WebDAV для Bazaar можно найти на сайте Launchpad: &lt;a href="https://launchpad.net/bzr.webdav"&gt;https://launchpad.net/bzr.webdav&lt;/a&gt;.

Для получения плагина сделаем копию ветки с Launchpad и затем установим плагин.
&lt;h3&gt;Установка только для текущего пользователя&lt;/h3&gt; &lt;div align="justify"&gt;Наиболее просто установить плагин для текущего пользователя. На Unix/Linux системах плагины устанавливаются в каталог &lt;tt&gt;~/.bazaar/plugins/&lt;/tt&gt; (на Windows используется каталог &lt;tt&gt;C:\Documents and Settings\USERNAME\Application Data\2.0\bazaar\plugins&lt;/tt&gt;). Перейдите в каталог &lt;tt&gt;plugins&lt;/tt&gt; и выполните команду &lt;tt&gt;branch&lt;/tt&gt;:
&lt;/div&gt;
&lt;samp&gt;$ cd ~/.bazaar/plugins/
$ bzr branch lp:bzr.webdav webdav
&lt;/samp&gt;
Плагин будет установлен в подкаталог &lt;tt&gt;webdav&lt;/tt&gt;.
&lt;h3&gt;Установка для всех пользователей&lt;/h3&gt; &lt;div align="justify"&gt;В данном случае модуль устанавливается в системной директории для поиска модулей bzrlib/plugins (на Unix системах это может быть /usr/lib/python2.5/site-packages/bzrlib/plugins/).
&lt;/div&gt;
&lt;samp&gt;$ bzr branch lp:bzr.webdav
$ cd bzr.webdav/
$ sudo python setup.py install
&lt;/samp&gt; &lt;h3&gt;Проверка наличия плагина WebDAV&lt;/h3&gt; &lt;div align="justify"&gt;Для проверки наличия плагина необходимо использовать команду &lt;tt&gt;plugins&lt;/tt&gt;. Эта команда выведет список всех установленных плагинов, их версий, и краткое описание каждого плагина. В этом списке должен присутствовать плагин &lt;tt&gt;webdav&lt;/tt&gt;:&lt;/div&gt;
&lt;pre&gt;$ bzr plugins
...
webdav 1.12
  An http transport, using webdav to allow pushing.
...
&lt;/pre&gt; 
&lt;h2&gt;Настройка сервера Apache&lt;/h2&gt; 
&lt;div align="justify"&gt;Теперь рассмотрим настройки HTTP сервера Apache.

Прежде всего для Apache должен быть установлен модуль &lt;tt&gt;mod_dav&lt;/tt&gt;. Конфигурация для этого модуля будет выглядеть приблизительно следующим образом:&lt;/div&gt;
&lt;pre&gt;&amp;lt;IfModule mod_dav.c&amp;gt;

  Alias /bzr /var/www/bzr

  &amp;lt;Directory /var/www/bzr&amp;gt;
    Dav On
    DirectorySlash Off
    DavDepthInfinity On

    AuthType Basic
    AuthName "Bazaar server"
    AuthUserFile /etc/apache2/dav.users
    Require valid-user
  &amp;lt;/Directory&amp;gt;
&amp;lt;/IfModule&amp;gt;
&lt;/pre&gt;
Рассмотрим настройки подробнее:
&lt;div align="justify"&gt; &lt;ul&gt;   &lt;li&gt;директива &lt;tt&gt;Alias &lt;/tt&gt;устанавливает связь между путем в URL (&lt;tt&gt;/bzr&lt;/tt&gt;) и каталогом &lt;tt&gt;/var/www/bzr&lt;/tt&gt;, где будут хранится ветки;&lt;/li&gt;   &lt;li&gt;опция &lt;tt&gt;Dav On&lt;/tt&gt; включает &lt;tt&gt;WebDAV&lt;/tt&gt; для &lt;tt&gt;/var/www/bzr&lt;/tt&gt;;&lt;/li&gt;   &lt;li&gt;опция     &lt;tt&gt;DirectorySlash Off&lt;/tt&gt; выключает перенаправление в случае если в конце URL для каталогов не указан &lt;tt&gt;'/'&lt;/tt&gt;. (Такие перенаправления не очень хорошо работают с Bazaar);&lt;/li&gt;   &lt;li&gt;опция &lt;tt&gt;DavDepthInfinity On&lt;/tt&gt; включает обработку &lt;tt&gt;PROPFIND&lt;/tt&gt; запросов с заголовком &lt;tt&gt;Depth: Infinity&lt;/tt&gt;;&lt;/li&gt;   &lt;li&gt;оставшиеся опции настраивают простую HTTP авторизацию;&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;h2&gt;Работа с сервером&lt;/h2&gt; После перезагрузки Apache вы сможете работать с удаленными ветками с помощью протокола &lt;span style="font-style: italic;"&gt;http+webdav://&lt;/span&gt; следующим образом:

&lt;samp&gt; $ bzr branch http+webdav://user@a.site/bzr/branch
&lt;/samp&gt;
Кроме использования HTTP можно настроить работу WebDAV и по протоколу HTTPS.
&lt;h2&gt;Сохранение пароля&lt;/h2&gt; &lt;div align="justify"&gt;Если вы используете на сервере авторизацию и не хотите каждый раз набирать пароль, то можно воспользоваться клиентским файлом конфигурации &lt;span style="font-style: italic;"&gt;authentication.conf&lt;/span&gt;. Этот файл должен находится в каталоге с файлами конфигурации Bazaar (по умолчанию на Unix - ~/.bazaar). В файле для WebDAV должна быть следующая информация:
&lt;/div&gt;
&lt;code&gt; [myprojects]
scheme = http
host = host.com
user = ivan
password = secret
&lt;/code&gt;
Обратите внимание, что значение параметра &lt;tt&gt;scheme&lt;/tt&gt; должно быть &lt;tt&gt;http&lt;/tt&gt; для &lt;span style="font-style: italic;"&gt;http+webdav://&lt;/span&gt; и &lt;tt&gt;https&lt;/tt&gt; для &lt;span style="font-style: italic;"&gt;https+webdav://&lt;/span&gt;.
&lt;blockquote&gt;Один из минусов использования файла &lt;span style="font-style: italic;"&gt;authentication.conf&lt;/span&gt;  в том, что (на данный момент) пароли хранятся в виде простого текста.
&lt;/blockquote&gt; &lt;h2&gt;Резюме&lt;/h2&gt; &lt;div align="justify"&gt;Подытоживая, можно сказать, что WebDAV может быть хорошей альтернативой для &lt;span style="font-style: italic;"&gt;bzr+ssh://&lt;/span&gt;, в случае если вы не хотите создавать системные учетные записи для каждого пользователя и в то же время предоставлять более безопасный доступ (при использовании HTTPS) чем &lt;span style="font-style: italic;"&gt;ftp://&lt;/span&gt;.
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-6517953543307326380?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/6517953543307326380/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/webdav-bazaar.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6517953543307326380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/6517953543307326380'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/webdav-bazaar.html' title='Использование WebDAV для доступа к Bazaar-серверу'/><author><name>Dmitry Vasiliev</name><uri>http://www.blogger.com/profile/00061696491069141929</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://2.bp.blogspot.com/_IMMKOFdsrBs/SaVM6sgwSlI/AAAAAAAAAAM/w5eRtt_fGyo/s1600-R/dmitry_vasiliev.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4479188094331081356</id><published>2009-03-26T11:07:00.002Z</published><updated>2009-03-26T11:18:49.821Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Работа с ветками: push, pull, merge (Часть 2)</title><content type='html'>&lt;div align="justify"&gt;Продолжаем &lt;a  href="http://bzr-day.blogspot.com/2009/03/push-pull-merge-1.html"&gt;начатую тему&lt;/a&gt; работы с ветками. Рассмотрим практическое применение команд push, pull, merge на двух примерах: синхронизация веток между несколькими компьютерами (одиночная работа), совместная работа над одним проектом в небольшом коллективе.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Сценарий №1&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Петр работает над своим проектом &lt;tt&gt;FuzzyCoding&lt;/tt&gt; на нескольких компьютерах (например, на домашнем и на рабочем). Перед тем как уйти с одного рабочего места на другое Петр фиксирует сделанные изменения, чтобы можно было продолжить работу на другом компьютере. Петр использует синхронизацию своих веток на разных компьютерах при помощи USB-flash диска. Когда он заканчивает работу, то  копирует новые ревизии из локальной ветки на флеш-диск командой &lt;tt&gt;bzr push&lt;/tt&gt;. Придя на другое рабочее место синхронизирует локальную ветку, копируя новые ревизии с флеш-диска командой &lt;tt&gt;bzr pull&lt;/tt&gt;.&lt;br&gt; &lt;br&gt; Рассмотрим этот сценарий более детально.&lt;br&gt; &lt;br&gt; &lt;b&gt;Подготовка USB-flash диска&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Петр уже создал новую ветку на своем компьютере и &lt;a  href="http://bzr-day.blogspot.com/2009/03/bzr-1.html"&gt;работает в ней&lt;/a&gt; некоторое время. Для переноса своей ветки на другой компьютер он решил использовать USB-диск. Петр может просто использовать команду &lt;tt&gt;bzr push&lt;/tt&gt; в своей рабочей ветке, чтобы передать ревизии и рабочие файлы на USB-диск. Базар полностью поддерживает такую работу.&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Однако, имеет смысл сделать некоторые подготовительные действия на USB-диске. Дело в том, что команда &lt;tt&gt;push&lt;/tt&gt; не только копирует новые ревизии в другую ветку, но еще и обновляет рабочие файлы в другой ветке в том случае, если ветка локальная. Поскольку подключенный USB-диск практически всегда является локальным диском, то &lt;tt&gt;bzr&lt;/tt&gt; будет стараться создать и обновить ваши рабочие файлы. В то же время для синхронизации веток вам совсем не требуется переносить и рабочие файлы (поскольку они присутствуют в истории и могут быть легко восстановлены). Поэтому с практической точки зрения необходимо исключить рабочие файлы с USB-диска и синхронизировать только историю.&lt;br&gt; &lt;br&gt; Для одной ветки это можно сделать так: создать новую ветку и удалить дерево рабочих файлов.&lt;br&gt; &lt;br&gt; &lt;samp&gt;E:\USB_sync&amp;gt;bzr init&lt;br&gt; Created a standalone tree (format: pack-0.92)&lt;br&gt; &lt;br&gt; E:\USB_sync&amp;gt;bzr remove-tree&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;div align="justify"&gt;Здесь мы создали новую ветку командой &lt;tt&gt;init&lt;/tt&gt; в каталоге &lt;tt&gt;E:\USB_sync&lt;/tt&gt; (&lt;tt&gt;E:&lt;/tt&gt; это наш USB-диск при использовании Windows, на Linux флеш-диски монтируются в &lt;tt&gt;/mnt/flash&lt;/tt&gt; или другое место). А затем удалили рабочее дерево командой &lt;tt&gt;remove-tree&lt;/tt&gt;.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;div align="justify"&gt;Другим вариантом является создание общего репозитория для веток на USB-диске, новые ветки в котором автоматически будут создаваться без рабочих файлов:&lt;br&gt; &lt;br&gt; &lt;tt&gt;E:\&amp;gt;bzr init-repo --no-trees USB_repo&lt;br&gt; Shared repository (format: pack-0.92)&lt;br&gt; Location:&lt;br&gt;   shared repository: USB_repo&lt;br&gt; &lt;/tt&gt;&lt;br&gt; &lt;div align="justify"&gt;Опция командной строки &lt;tt&gt;--no-trees&lt;/tt&gt; указывает, что по умолчанию для всех веток в этом репозитории рабочие файлы создаваться &lt;i&gt;не будут&lt;/i&gt;.&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div align="justify"&gt;&lt;br&gt; &lt;b&gt;Копирование новых ревизий на USB-диск&lt;/b&gt;&lt;br&gt; &lt;br&gt; Для отправки новых ревизий на USB-диск Петр использует команду &lt;tt&gt;push&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\FuzzyCode&amp;gt;bzr push E:\USB_sync&lt;br&gt; Pushed up to revision 3.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;b&gt;Создание копии ветки на другом компьютере&lt;/b&gt;&lt;br&gt; &lt;br&gt; Придя на другое рабочее место со своим USB-диском Петр создает копию ветки для работы:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day&amp;gt;bzr branch E:\USB_sync FuzzyCode&lt;br&gt; Branched 3 revision(s).&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Теперь он может продолжать работу со своей веткой &lt;tt&gt;FuzzyCode&lt;/tt&gt;. По окончании работы Петр снова отправляет новые ревизии на USB-диск командой &lt;tt&gt;push&lt;/tt&gt;.&lt;br&gt; &lt;br&gt; &lt;b&gt;Синхронизация рабочей ветки с USB-диском&lt;/b&gt;&lt;br&gt; &lt;br&gt; Для получения новых ревизий с USB-диска в свою рабочую ветку Петр использует команду &lt;tt&gt;pull&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\FuzzyCode&amp;gt;bzr pull E:\USB_sync&lt;br&gt; All changes applied successfully.&lt;br&gt; Now on revision 4.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Рабочая ветка успешно обновлена, можно продолжать работу.&lt;br&gt; &lt;br&gt; &lt;b&gt;Иногда ветки могут разойтись&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Если же Петр забыл синхронизировать рабочую ветку с USB-диском и зафиксировал новые изменения, то при попытке сделать &lt;tt&gt;push&lt;/tt&gt; или &lt;tt&gt;pull&lt;/tt&gt; он получит сообщение, что ветки "разошлись". В этом случае Петр должен объединить ветки командой &lt;tt&gt;merge&lt;/tt&gt;:&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\FuzzyCode&amp;gt;bzr merge E:\USB_sync&lt;br&gt; +N  dir/&lt;br&gt; +N  foo.txt&lt;br&gt; All changes applied successfully.&lt;br&gt; &lt;br&gt; C:\work\bzr-day\FuzzyCode&amp;gt;bzr commit -m "Объединение рабочей ветки с копией ветки на USB-диске"&lt;br&gt; Committing to: C:/work/bzr-day/FuzzyCode/&lt;br&gt; added dir&lt;br&gt; added foo.txt&lt;br&gt; Committed revision 5.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; После этого команда &lt;tt&gt;push&lt;/tt&gt; позволит синхронизировать копию на USB-диске с рабочей веткой.&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Мы рассмотрели простой пример синхронизации веток между несколькими компьютерами. В качестве промежуточной ветки также можно использовать и некоторый общедоступный сервер, например &lt;tt&gt;SFTP/FTP&lt;/tt&gt;. &lt;br&gt; &lt;br&gt; В следующей части мы рассмотрим сценарий совместной работы над проектом в небольшом коллективе.&lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4479188094331081356?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4479188094331081356/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/push-pull-merge-2.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4479188094331081356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4479188094331081356'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/push-pull-merge-2.html' title='Работа с ветками: push, pull, merge (Часть 2)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-2442920819915168413</id><published>2009-03-23T07:14:00.002Z</published><updated>2009-03-23T07:17:43.360Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Работа с ветками: push, pull, merge (Часть 1)</title><content type='html'>&lt;div align="justify"&gt;Ранее &lt;a  href="http://bzr-day.blogspot.com/2009/03/bzr-2.html"&gt;мы рассмотрели&lt;/a&gt; базовую работу с ветками. В дополнение к &lt;tt&gt;branch&lt;/tt&gt; и &lt;tt&gt;merge&lt;/tt&gt;, сегодня мы рассмотрим еще несколько дополнительных команд. В первой части рассмотрим как они работают. Во второй части рассмотрим пример их использования.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Команды&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;table border="1" cellpadding="5" cellspacing="0"&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;branch&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Ветка&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Создать новую ветку&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;merge&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Объединить&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Объединить изменения из разных веток&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;pull&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Тянуть, втягивать (направление движения: на себя)&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Получить (загрузить) изменения из другой ветки в рабочую ветку&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;push&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Толкать, выталкивать (направление движения: от себя)&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Передать (отправить) изменения из рабочей ветки в другую ветку&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;missing&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Недостающий, отсутствующий&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Просмотр набора ревизий, различающихся между двумя ветками&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;br&gt; &lt;div align="justify"&gt;&lt;b&gt;Графы ревизий&lt;/b&gt;&lt;br&gt; &lt;br&gt; Рассматриваемые команды в первую очередь работают с историей изменений. История хранится в bzr в виде DAG, поэтому в описании работы будем использовать соответствующие графы, помечая знаком &lt;tt&gt;"O"&lt;/tt&gt; отдельные (ключевые) ревизии. Считаем что ревизии растут снизу вверх, т.е. вверху более новые. Рассматривая две родственные ветки, мы можем иметь 4 возможных типа графов:&lt;br&gt; &lt;br&gt; &lt;table border="1" cellpadding="10" cellspacing="0"&gt;   &lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;O &lt;/tt&gt;Рабочая ветка, другая ветка&lt;tt&gt; &lt;br&gt; |&lt;br&gt; O&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;       &lt;td valign="top"&gt;Ветки содержат одинаковый набор ревизий&lt;tt&gt;&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;O &lt;/tt&gt;Рабочая ветка&lt;br&gt;       &lt;tt&gt;|  O &lt;/tt&gt;Другая ветка&lt;br&gt;       &lt;tt&gt;| /&lt;br&gt; O&lt;br&gt; |&lt;br&gt; O&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;       &lt;td valign="top"&gt;Ветки содержат различный набор ревизий, история "разошлась"&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;O &lt;/tt&gt;Рабочая ветка&lt;br&gt;       &lt;tt&gt;|&lt;br&gt; O &lt;/tt&gt;Другая ветка&lt;br&gt;       &lt;tt&gt;|&lt;br&gt; O&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;       &lt;td valign="top"&gt;Рабочая ветка является продолжением другой ветки; рабочая ветка имеет новые ревизии (относительно истории другой ветки)&lt;tt&gt;&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;O &lt;/tt&gt;Другая ветка&lt;tt&gt;&lt;br&gt; |&lt;br&gt; O &lt;/tt&gt;Рабочая ветка&lt;tt&gt;&lt;br&gt; |&lt;br&gt; O&lt;br&gt;       &lt;/tt&gt;&lt;/td&gt;       &lt;td valign="top"&gt;Другая ветка является продолжением рабочей ветки; в рабочей ветке отсутствуют новые ревизии (относительно истории другой ветки)&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;br&gt;     &lt;br&gt; &lt;/div&gt; &lt;b&gt;Команда &lt;tt&gt;branch&lt;/tt&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Команда &lt;tt&gt;branch&lt;/tt&gt; создает копию существующей ветки. После выполнения этой команды обе ветки содержат одинаковый набор ревизий, что соответствует графу 1.&lt;br&gt; &lt;br&gt; &lt;b&gt;Команда &lt;tt&gt;merge&lt;/tt&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt; &lt;div align="justify"&gt;Команда &lt;tt&gt;merge&lt;/tt&gt; используется в случаях, когда две ветки "разошлись", т.е. имеют различный набор ревизий, что соответствует графу 2. Эта команда объединяет ревизии рабочей ветки с другой веткой. После фиксации объединения граф ревизий будет содержать все ревизии из другой ветки. Другая ветка при этом не изменяется. &lt;br&gt; &lt;br&gt; &lt;/div&gt; Граф ревизий после объединения:&lt;br&gt; &lt;br&gt; &lt;tt&gt;O &lt;/tt&gt;Рабочая ветка&lt;br&gt; &lt;tt&gt;|\&lt;/tt&gt;&lt;br&gt; &lt;tt&gt;O \&lt;br&gt; |  O &lt;/tt&gt;Другая ветка&lt;br&gt; &lt;tt&gt;| /&lt;br&gt; O&lt;br&gt; |&lt;br&gt; O&lt;br&gt; &lt;/tt&gt;&lt;br&gt; &lt;div align="justify"&gt;Такой граф уже ближе к графу номер 3, когда рабочая ветка является продолжением другой ветки.&lt;br&gt; &lt;br&gt; В случаях, когда история еще не разошлась, имеется возможность использовать команды &lt;tt&gt;push&lt;/tt&gt; и &lt;tt&gt;pull&lt;/tt&gt; для синхронизации веток.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Команда &lt;tt&gt;push&lt;/tt&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Команда &lt;tt&gt;push&lt;/tt&gt; используется для синхронизации другой ветки с рабочей веткой. В случае, когда рабочая ветка содержит новые ревизии, которые отсутствуют в другой ветке (как показано на графе 3), пользователь может отправить новые ревизии в другую ветку командой &lt;tt&gt;push&lt;/tt&gt;. После выполнения команды &lt;tt&gt;push&lt;/tt&gt; обе ветки будут синхронизированы (см. граф 1).&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\a&amp;gt;bzr push ../other&lt;br&gt; All changes applied successfully.&lt;br&gt; Pushed up to revision 3.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Если обе ветки уже синхронизированы, то команда &lt;tt&gt;push&lt;/tt&gt; сообщит об этом::&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\a&amp;gt;bzr push ../other&lt;br&gt; No new revisions to push.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; В случае, когда история двух веток разошлась, команда выдаст ошибку и предложит сделать &lt;tt&gt;merge&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\b&amp;gt;bzr push ../a&lt;br&gt; bzr: ERROR: These branches have diverged.  Try using "merge" and then "push".&lt;/samp&gt;&lt;br&gt; &lt;blockquote&gt;Команда &lt;tt&gt;push&lt;/tt&gt; чаще всего используется для публикации рабочих веток на общем сервере, чтобы другие участники проекта могли получить к ней доступ. Если ветка еще не существует, то она будет автоматически создана.&lt;br&gt; &lt;/blockquote&gt; &lt;b&gt;Команда &lt;tt&gt;pull&lt;/tt&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Команда &lt;tt&gt;pull&lt;/tt&gt; является полной противоположностью команде &lt;tt&gt;push&lt;/tt&gt;: она предназначена для синхронизации рабочей ветки с другой веткой. В случае, когда другая ветка содержит новые ревизии, которые отсутствуют в рабочей ветке (как показано на графе 4), пользователь может загрузить новые ревизии из другой ветки командой &lt;tt&gt;pull&lt;/tt&gt;. После выполнения команды &lt;tt&gt;pull&lt;/tt&gt; обе ветки будут синхронизированы (см. граф 1).&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\other&amp;gt;bzr pull ../a&lt;br&gt; All changes applied successfully.&lt;br&gt; Now on revision 3.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Если обе ветки уже синхронизированы, то команда &lt;tt&gt;pull&lt;/tt&gt; сообщит об этом::&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\other&amp;gt;bzr pull ../a&lt;br&gt; No revisions to pull.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; В случае, когда история двух веток разошлась, команда выдаст ошибку и предложит сделать &lt;tt&gt;merge&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\b&amp;gt;bzr pull ../a&lt;br&gt; bzr: ERROR: These branches have diverged. Use the merge command to reconcile them.&lt;/samp&gt;&lt;br&gt; &lt;blockquote&gt;Команда &lt;tt&gt;pull&lt;/tt&gt; часто используется для обновления локальной копии ветки, которая находится на общем сервере.&lt;br&gt; &lt;/blockquote&gt; &lt;b&gt;Команда &lt;tt&gt;missing&lt;/tt&gt;&lt;/b&gt;&lt;br&gt; &lt;br&gt; Команда &lt;tt&gt;missing&lt;/tt&gt; — это информационная команда. Она позволяет сравнить наборы ревизий в двух ветках и увидеть какие ревизии содержатся в одной ветке и отсутствуют в другой. Команду &lt;tt&gt;missing&lt;/tt&gt; удобно использовать перед запуском команд &lt;tt&gt;push, pull&lt;/tt&gt; или &lt;tt&gt;merge&lt;/tt&gt;, чтобы яснее представлять себе общий граф ревизий двух веток.&lt;br&gt; &lt;br&gt; Вывод команды &lt;tt&gt;missing&lt;/tt&gt; разделен на 2 части: сначала выводится список ревизий в рабочей ветке, которые отсутствуют в другой ветке; затем список ревизий из другой ветки, которые отсутствуют в рабочей ветке. Вывод списка ревизий аналогичен выводу команды &lt;tt&gt;log&lt;/tt&gt;.&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\b&amp;gt;bzr missing ../a&lt;br&gt; You have 1 extra revision(s):&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 3&lt;br&gt; committer: Базарный день &lt;a class="moz-txt-link-rfc2396E" href="mailto:ru_bzr@googlegroups.com"&gt;&amp;lt;ru_bzr@googlegroups.com&amp;gt;&lt;/a&gt;&lt;br&gt; branch nick: b&lt;br&gt; timestamp: Mon 2009-03-23 08:47:47 +0200&lt;br&gt; message:&lt;br&gt;   Новая ревизия в ветке b&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; You are missing 1 revision(s):&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 3&lt;br&gt; committer: Базарный день &lt;a class="moz-txt-link-rfc2396E" href="mailto:ru_bzr@googlegroups.com"&gt;&amp;lt;ru_bzr@googlegroups.com&amp;gt;&lt;/a&gt;&lt;br&gt; branch nick: a&lt;br&gt; timestamp: Mon 2009-03-23 08:47:39 +0200&lt;br&gt; message:&lt;br&gt;   Новая ревизия в ветке a&lt;br&gt; &lt;br&gt; &lt;/samp&gt; &lt;div align="justify"&gt;Здесь мы видим, что история двух веток разошлась после ревизии 2, поскольку обе ветки содержат новую ревизию 3, но в каждой ветке это своя ревизия (см. граф 2).&lt;br&gt; &lt;br&gt; Если история веток еще не разошлась (см. графы 3 и 4), то команда &lt;tt&gt;missing&lt;/tt&gt; покажет только новые/недостающие ревизии:&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\a&amp;gt;bzr missing ../other&lt;br&gt; You have 1 extra revision(s):&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 3&lt;br&gt; committer: Базарный день &lt;a class="moz-txt-link-rfc2396E" href="mailto:ru_bzr@googlegroups.com"&gt;&amp;lt;ru_bzr@googlegroups.com&amp;gt;&lt;/a&gt;&lt;br&gt; branch nick: a&lt;br&gt; timestamp: Mon 2009-03-23 08:47:39 +0200&lt;br&gt; message:&lt;br&gt;   Новая ревизия в ветке a&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\other&amp;gt;bzr missing ../a&lt;br&gt; You are missing 1 revision(s):&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 3&lt;br&gt; committer: Базарный день &lt;a class="moz-txt-link-rfc2396E" href="mailto:ru_bzr@googlegroups.com"&gt;&amp;lt;ru_bzr@googlegroups.com&amp;gt;&lt;/a&gt;&lt;br&gt; branch nick: a&lt;br&gt; timestamp: Mon 2009-03-23 08:47:39 +0200&lt;br&gt; message:&lt;br&gt;   Новая ревизия в ветке a&lt;br&gt; &lt;br&gt; &lt;/samp&gt;Обе ветки синхронизированы:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\work\bzr-day\a&amp;gt;bzr missing ../a&lt;br&gt; Branches are up to date.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;div align="justify"&gt;Итак, в первой части статьи было показано как работают команды push, pull, missing. В второй части этой статьи рассмотрим сценарий работы с использованием этих команд.&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-2442920819915168413?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/2442920819915168413/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/push-pull-merge-1.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2442920819915168413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/2442920819915168413'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/push-pull-merge-1.html' title='Работа с ветками: push, pull, merge (Часть 1)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-1574724515906031450</id><published>2009-03-15T08:33:00.008Z</published><updated>2011-11-30T11:47:18.831Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Начинаем работу с bzr: базовый набор команд (Часть 2)</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div align="justify"&gt;
В &lt;a href="http://bzr-day.blogspot.com/2009/03/bzr-1.html"&gt;первой части&lt;/a&gt; мы рассмотрели работу с одной веткой. Рассмотрим теперь работу с несколькими ветками.&lt;br /&gt;
&lt;/div&gt;
&lt;b&gt;Сценарий работы&lt;/b&gt;

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
&lt;i&gt;Создадим копию ветки&lt;/i&gt; для параллельной работы. Изменим некоторые файлы в старой и новой ветках и &lt;i&gt;зафиксируем&lt;/i&gt; новое состояние. &lt;i&gt;Объединим&lt;/i&gt; изменения в двух ветках.
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Для чего нужны дополнительные ветки?&lt;/b&gt;

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Использование веток — это неотъемлемая часть при распределенной работе. Фактически каждый участник проекта работает в своей ветке на своем компьютере, периодически рабочие ветки объединяются в главную или интеграционную ветку, которая считается основной веткой проекта.

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Часто ветки используются, чтобы разделить разработку нового функционала программного продукта и поддержку выпущенных версий. В этом случае выпущенные версии (release — релизы) живут в своих собственных ветках. Как правило в &lt;i&gt;релизных ветках&lt;/i&gt; только исправляются найденные ошибки, например, исправления ошибок из основной ветки переносятся (портируются) в релизную ветку.

Другой тип веток — &lt;i&gt;функциональные ветки&lt;/i&gt; (feature branches). Функциональные ветки используются для работы над одной конкретной задачей: реализации одной новой функции,  исправления одного найденного дефекта и т.п.. Функциональные ветки удобно использовать для работы над экспериментальными вещами, про которые заранее неизвестно: выйдет что-либо полезное или нет.  Независимо от стиля работы (централизованный или распределенный) или от того, работаете вы в одиночку или группой, использование функциональных веток позволяет более эффективно работать над проектами. Функциональные ветки помогают сфокусировать усилия при работе над конкретными задачами. Когда работа над конкретной задачей закончена, функциональная ветка объединяется с основной веткой проекта. (О пользе функциональных веток подробно излагается в статье &lt;a href="http://divmod.org/trac/wiki/UltimateQualityDevelopmentSystem"&gt;Ultimate Quality Development System&lt;/a&gt;).
&lt;br /&gt;
&lt;blockquote&gt;
Чаще всего в централизованных системах контроля версий (например таких популярных как CVS или SVN) реализация веток подразумевает именно только работу с релизными ветками, а поддержка работы с функциональными ветками (точнее с многократным объединением изменений между основной и функциональной веткой) реализована хуже. Поэтому их часто критикуют за слабую поддержку веток, имея ввиду именно слабую поддержку объединений в модели работы с функциональными ветками.
&lt;/blockquote&gt;
Далее в статье мы рассмотрим работу с ветками именно с позиции функциональных веток.

&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Создать копию ветки&lt;/b&gt;

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Поскольку &lt;tt&gt;bzr&lt;/tt&gt; хранит всю служебную информацию локально в рабочем каталоге, то мы можем просто скопировать рабочий каталог со всеми файлами. Это вполне корректный вариант, однако рекомендуется все же использовать специальную команду &lt;tt&gt;branch&lt;/tt&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;C:\Temp&amp;gt; bzr branch Test Experimental&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;
Branched 2 revision(s).&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;&lt;/samp&gt;Мы создали копию ветки &lt;tt&gt;Test&lt;/tt&gt; в каталоге &lt;tt&gt;Experimental&lt;/tt&gt;. Сразу после выполнения команды &lt;tt&gt;branch&lt;/tt&gt; обе ветки содержат одинаковый набор ревизий и их история идентична. По мере того, как пользователь будет фиксировать новые изменения в той или иной ветке, история веток начнет различаться.
&lt;br /&gt;
&lt;blockquote&gt;
Будем считать &lt;tt&gt;Test&lt;/tt&gt; — основной веткой, а &lt;tt&gt;Experimental&lt;/tt&gt; — функциональной (или экспериментальной) веткой.
&lt;/blockquote&gt;
&lt;b&gt;Работа в другой ветке&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Работа со второй веткой ничем не отличается от сценария работы рассмотренного в первой части статьи. Новая ветка полностью автономна и независима от своего родителя. Пользователь может просматривать историю, фиксировать изменения в файлах и т.д.

Изменим один из файлов и зафиксируем его:

&lt;b&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;code&gt;------Файл goodbye.txt--------&amp;nbsp;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;code&gt;&lt;/code&gt;&lt;/b&gt;&lt;code&gt;До свидания&lt;/code&gt;&lt;b&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;code&gt;------------------------------
&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;C:\Temp\Experimental&amp;gt;bzr commit -m "Скорректирован файл goodbye.txt в ветке Experimental"&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Committing to: C:/Temp/Experimental/&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;modified goodbye.txt&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Committed revision 3.
&lt;/samp&gt;&lt;br /&gt;
&lt;br /&gt;
Вернемся в первую ветку Test и изменим там другой файл:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;code&gt;--------Файл foo.txt----------&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;code&gt;
&lt;/code&gt;&lt;/b&gt;&lt;code&gt;bar&lt;/code&gt;&lt;b&gt;&lt;code&gt;&amp;nbsp;&lt;/code&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;code&gt;------------------------------
&lt;/code&gt;&lt;/b&gt;
&lt;samp&gt;&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;C:\Temp\Test&amp;gt;bzr commit -m "Скорректирован файл foo.txt в ветке Test"&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Committing to: C:/Temp/Test/&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;
modified foo.txt&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;
Committed revision 3.
&lt;/samp&gt;&lt;br /&gt;
&lt;br /&gt;
Обе ветки теперь содержат по 3 ревизии, но с различными изменениями. История "разошлась".

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
История веток в &lt;tt&gt;bzr&lt;/tt&gt; представляется в виде &lt;a href="http://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B0%D1%86%D0%B8%D0%BA%D0%BB%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B3%D1%80%D0%B0%D1%84"&gt;ориентированного ациклического графа&lt;/a&gt; (&lt;a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph"&gt;DAG&lt;/a&gt;), совместный граф для этих двух веток будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;

&lt;img align="middle" alt="" height="91" src="http://bialix.com/bzr-day/qlog-1.png" title="Граф ревизий в двух ветках" width="621" /&gt;

&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Работа в обеих ветках может продолжаться независимо. Как только пользователь посчитает, что работа над функциональной веткой &lt;tt&gt;Experimental&lt;/tt&gt; закончена, можно объединить основную и функциональные ветки.
&lt;/div&gt;
&lt;/div&gt;
&lt;div align="justify"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
&lt;b&gt;Объединение веток&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Операция объединения веток выполняется командой &lt;tt&gt;merge&lt;/tt&gt;. При этом &lt;tt&gt;bzr&lt;/tt&gt; будет объединять историю и изменения из другой ветки с текущей веткой.
&lt;/div&gt;
&lt;br /&gt;
&lt;samp&gt;C:\Temp\Test&amp;gt;bzr merge ../Experimental&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;M  goodbye.txt&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;All changes applied successfully.
&lt;/samp&gt;
&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Как мы видим, объединение изменений прошло успешно. В случаях, когда в обеих ветках были произведены несовместимые изменения, в результате объединения мы получим один или несколько конфликтов в рабочих файлах. (Подробнее о типах конфликтов и методах их разрешения мы поговорим в отдельной статье.)
&lt;/div&gt;
&lt;br /&gt;
После объединения команда &lt;tt&gt;status&lt;/tt&gt; будет отображать ревизии, которые мы объединили, но еще не зафиксировали:&lt;br /&gt;


&lt;samp&gt;&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;C:\Temp\Test&amp;gt;bzr status -v&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;modified:&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;&amp;nbsp; goodbye.txt&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;pending merges:&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;&amp;nbsp; Alexander Belchenko 2009-03-13 Скорректирован файл goodbye.txt в ветке Experimental
&lt;/samp&gt;
&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Как видно ревизии из ветки &lt;tt&gt;Experimental&lt;/tt&gt; помечены как &lt;tt&gt;pending merges&lt;/tt&gt; (незаконченное объединение). Чтобы закончить процесс объединения мы должны зафиксировать изменения командой &lt;tt&gt;commit&lt;/tt&gt;.

&lt;/div&gt;
&lt;div align="justify"&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Результаты объединения желательно просмотреть визуально, проанализировав содержимое изменившихся файлов либо просмотреть различия командой &lt;tt&gt;diff&lt;/tt&gt;:
&lt;/div&gt;
&lt;br /&gt;
&lt;tt&gt;C:\Temp\Test&amp;gt;bzr diff&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;=== modified file 'goodbye.txt'&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;--- goodbye.txt 2009-03-10 09:06:24 +0000&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;+++ goodbye.txt 2009-03-15 07:59:47 +0000&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;@@ -1,1 +1,1 @@&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;
-Пока&amp;nbsp;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;+До свидания
&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
Если пользователь согласен с внесенными изменениями, то их нужно зафиксировать как обычно:&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;C:\Temp\Test&amp;gt;bzr commit -m "Объединение с веткой Experimental"&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Committing to: C:/Temp/Test/&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;modified goodbye.txt&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Committed revision 4.&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;samp&gt;&lt;/samp&gt;Если мы просмотрим журнал изменений для ветки Test, то мы увидим объединенные ревизии в истории основной ветки:

&lt;br /&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;C:\Temp\Test&amp;gt;bzr log
------------------------------------------------------------
revno: 4
committer: Alexander Belchenko &amp;lt;alexander.belchenko @ gmail.com&amp;gt;
branch nick: Test
timestamp: Sun 2009-03-15 10:11:30 +0200
message:
  Объединение с веткой Experimental
    ------------------------------------------------------------
    revno: 2.1.1
    committer: Alexander Belchenko &amp;lt;alexander.belchenko @ gmail.com&amp;gt;
    branch nick: Experimental
    timestamp: Fri 2009-03-13 20:04:12 +0200
    message:
      Скорректирован файл goodbye.txt в ветке Experimental
------------------------------------------------------------
revno: 3
committer: Alexander Belchenko &amp;lt;alexander.belchenko @ gmail.com&amp;gt;
branch nick: Test
timestamp: Fri 2009-03-13 20:07:10 +0200
message:
  Скорректирован файл foo.txt в ветке Test
------------------------------------------------------------
revno: 2
committer: Alexander Belchenko &amp;lt;alexander.belchenko @ gmail.com&amp;gt;
branch nick: Test
timestamp: Tue 2009-03-10 15:38:19 +0200
message:
  Внесены изменения для иллюстрации команд status и diff
------------------------------------------------------------
revno: 1
committer: Alexander Belchenko &amp;lt;alexander.belchenko @ gmail.com&amp;gt;
branch nick: Test
timestamp: Tue 2009-03-10 11:06:24 +0200
message:
  Начальное состояние файлов
&lt;/pre&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Объединенные ревизии отображаются под ревизией, в которой объединение было зафиксировано, с небольшим отступом. Соответствующий граф ревизий теперь выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;

&lt;/div&gt;
&lt;img alt="" height="110" src="http://bialix.com/bzr-day/qlog-2.png" title="Граф ревизий после объединения" width="632" /&gt;
После объединения вся история ветки &lt;tt&gt;Experimental&lt;/tt&gt; содержится в ветке &lt;tt&gt;Test&lt;/tt&gt;. Мы видим ревизию из этой ветки под номером &lt;tt&gt;2.1.1&lt;/tt&gt; в ветке &lt;tt&gt;Test&lt;/tt&gt;.  Если работа с веткой &lt;tt&gt;Experimental&lt;/tt&gt; закончена, то ее можно смело удалить.

Если ветка &lt;tt&gt;Experimental&lt;/tt&gt; понадобится вновь, ее можно восстановить командой &lt;tt&gt;branch&lt;/tt&gt;, указав номер ревизии при помощи опции &lt;tt&gt;--revision (-r)&lt;/tt&gt;:&lt;br /&gt;

&lt;samp&gt;&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;C:\Temp&amp;gt;bzr branch Test Experimental -r 2.1.1&amp;nbsp;&lt;/samp&gt;&lt;br /&gt;
&lt;samp&gt;Branched 3 revision(s).
&lt;/samp&gt;
&lt;br /&gt;
&lt;div align="justify"&gt;
&lt;br /&gt;
Итак, мы рассмотрели работу с несколькими ветками и научились объединять ветки. В следующих статьях мы рассмотрим другие команды для работы с ветками, а также научимся справляться с конфликтами объединения.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-1574724515906031450?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/1574724515906031450/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-2.html#comment-form' title='Комментарии: 14'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1574724515906031450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/1574724515906031450'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-2.html' title='Начинаем работу с bzr: базовый набор команд (Часть 2)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5572782052448718280</id><published>2009-03-11T07:51:00.005Z</published><updated>2009-03-12T08:16:47.966Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='команды'/><category scheme='http://www.blogger.com/atom/ns#' term='для начинающих'/><title type='text'>Начинаем работу с bzr: базовый набор команд (Часть 1)</title><content type='html'>&lt;div align="justify"&gt;Как вы помните, bzr является распределенной системой контроля версий и не требует никакого специального сервера для своей работы. Поэтому начать работу с ней очень просто: вы можете создать новый репозиторий и новую ветку в любом удобном локальном каталоге на вашем компьютере. Далее мы рассмотрим 8 базовых команд bzr, которые понадобятся для локальной одиночной работы.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Сценарий работы&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;&lt;i&gt;Инициализируем&lt;/i&gt; в локальном каталоге новую ветку для работы. В этом каталоге создадим несколько рабочих файлов. &lt;i&gt;Добавим&lt;/i&gt; эти файлы под контроль версий. &lt;i&gt;Зафиксируем&lt;/i&gt; начальное состояние файлов. Изменим некоторые из файлов. &lt;i&gt;Просмотрим изменения&lt;/i&gt; в файлах. &lt;i&gt;Зафиксируем&lt;/i&gt; новое состояние файлов. &lt;i&gt;Просмотрим историю&lt;/i&gt; изменений. &lt;i&gt;Создадим копию ветки&lt;/i&gt; для параллельной работы. Изменим некоторые файлы в старой и новой ветках и &lt;i&gt;зафиксируем&lt;/i&gt; новое состояние. &lt;i&gt;Объединим&lt;/i&gt; изменения в двух ветках.&lt;br&gt; &lt;br&gt; Этот сценарий иллюстрирует типичную работу с локальными ветками. Создавать новые ветки с нуля придется  для каждого нового проекта, который вы хотите поместить под контроль версий, но это относительно редкое действие. Остальные действия  вы будете выполнять в своей работе  достаточно часто.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Команды&lt;/b&gt; &lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;В вышеприведенном сценарии работы выделены действия, производимые при помощи bzr. Команды bzr используют английские термины, соответствующие выполняемым действиям:&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;table align="center" border="1" cellpadding="3" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;tt&gt;init&lt;/tt&gt;&lt;/td&gt;&lt;td valign="top"&gt;Инициализация&lt;/td&gt;&lt;td valign="top"&gt;Инициализация новой ветки&lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;add&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Добавить&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Добавить файлы под контроль версий&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;commit&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Зафиксировать&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Зафиксировать состояние файлов&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;status&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Состояние&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Показать состояние файлов, отобразить имена измененных файлов&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;diff&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Разница&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Показать изменения в файлах&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;log&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Журнал&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Просмотр журнала изменений, истории изменений&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;branch&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Ветка&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Создать новую ветку&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td valign="top"&gt;&lt;tt&gt;merge&lt;/tt&gt;&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Объединить&lt;br&gt;       &lt;/td&gt;       &lt;td valign="top"&gt;Объединить изменения из разных веток&lt;br&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt; &lt;br&gt; &lt;div align="justify"&gt;Используем команды из таблицы для "перевода" нашего сценария с русского языка на язык команд bzr. В примерах использовался bzr 1.12. Если вы используете другую версию, то сообщения bzr могут незначительно отличаться.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Инициализировать новую ветку&lt;br&gt; &lt;br&gt; &lt;/b&gt;Инициализировать новую ветку в текущем каталоге:&lt;br&gt; &lt;samp&gt;&lt;br&gt; C:\Temp\Test&amp;gt;bzr init&lt;br&gt; Created a standalone tree (format: pack-0.92)&lt;/samp&gt;&lt;br&gt; &lt;blockquote&gt;В качестве аргумента команде &lt;tt&gt;init&lt;/tt&gt; можно указать путь для создания новой ветки, новый каталог будет создан при необходимости.&lt;br&gt; &lt;/blockquote&gt; &lt;div align="justify"&gt;При инициализации создается служебный каталог с именем &lt;tt&gt;.bzr&lt;/tt&gt;, в котором хранятся служебные файлы и история изменений.&lt;br&gt; Новая ветка инициализирована — можно добавлять файлы.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;b&gt;Добавить новые файлы&lt;/b&gt;&lt;br&gt; &lt;br&gt; Для примера создадим два текстовых файла в рабочем каталоге:&lt;br&gt; &lt;br&gt; &lt;b&gt;&lt;code&gt;-------Файл hello.txt---------&lt;br&gt; &lt;/code&gt;&lt;/b&gt;&lt;code&gt;Привет&lt;br&gt; ------------------------------&lt;br&gt; &lt;/code&gt;&lt;b&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt; &lt;code&gt;------Файл goodbye.txt--------&lt;br&gt; &lt;/code&gt;&lt;/b&gt;&lt;code&gt;Пока&lt;/code&gt;&lt;b&gt;&lt;code&gt;&lt;br&gt; ------------------------------&lt;br&gt; &lt;br&gt; &lt;/code&gt;&lt;/b&gt;Добавим файлы под контроль версий:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr add&lt;br&gt; adding goodbye.txt&lt;br&gt; adding hello.txt&lt;br&gt; &lt;br&gt; &lt;/samp&gt; &lt;div align="justify"&gt;Команда &lt;tt&gt;add&lt;/tt&gt;, запущенная без аргументов, добавит все неизвестные файлы под контроль версий. Вы можете явно указать какие файлы нужно добавлять, если запустите команду &lt;tt&gt;add &lt;/tt&gt;с аргументами (именами файлов для добавления).&lt;br&gt; &lt;/div&gt; &lt;br&gt; Файлы добавлены — можно фиксировать их состояние.&lt;br&gt; &lt;br&gt; &lt;b&gt;Зафиксировать состояние файлов&lt;/b&gt;&lt;b&gt;&lt;code&gt;&lt;br&gt; &lt;br&gt; &lt;/code&gt;&lt;/b&gt; &lt;div align="justify"&gt; &lt;div align="justify"&gt; Фиксация запоминает текущее состояние файлов. Пользователь должен дать комментарий к фиксируемым изменениям. Этот комментарий затем можно будет увидеть при просмотре журнала изменений. Хорошей практикой является описание цели и сути изменений в комментарии: конкретные изменения можно просмотреть при помощи команд bzr, а вот мотивы и цели изменений знает только автор изменений. Со временем это знание утрачивается, поэтому старайтесь писать четкие комментарии, которые будут понятны и через неделю/месяц/год.&lt;br&gt; &lt;/div&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr commit -m "Начальное состояние файлов"&lt;br&gt; Committing to: C:/Temp/Test/&lt;br&gt; added goodbye.txt&lt;br&gt; added hello.txt&lt;br&gt; Committed revision 1.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;div align="justify"&gt;Опция &lt;tt&gt;-m (--message)&lt;/tt&gt; используется для указания комментария. Пользователь также может указать имя файла, из которого будет прочитан комментарий (используется опция &lt;tt&gt;--file, -F&lt;/tt&gt;). Либо можно не указывать ничего, в этом случае будет запущен текстовый редактор, в котором вы сможете ввести свой комментарий.&lt;br&gt; &lt;br&gt; &lt;b&gt;Просмотр изменений&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;В реальной работе файлы приходится менять, дописывать и корректировать достаточно часто. Закончив очередной логический этап (например, реализована новая функция в программе, исправлена ошибка, или проведен рефакторинг существующего кода) пользователь может проанализировать внесенные изменения и зафиксировать их. Продемонстрируем эти действия на простом примере.&lt;br&gt; &lt;br&gt; Изменим файл &lt;tt&gt;hello.txt&lt;/tt&gt; и создадим новый файл &lt;tt&gt;foo.txt&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;b&gt;&lt;code&gt;-------Файл hello.txt---------&lt;br&gt; &lt;/code&gt;&lt;/b&gt;&lt;code&gt;Привет, мир!&lt;br&gt; ------------------------------&lt;br&gt; &lt;/code&gt;&lt;b&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt; &lt;code&gt;--------Файл foo.txt----------&lt;br&gt; &lt;/code&gt;&lt;/b&gt;&lt;code&gt;Новый файл&lt;/code&gt;&lt;b&gt;&lt;code&gt;&lt;br&gt; ------------------------------&lt;br&gt; &lt;/code&gt;&lt;/b&gt;&lt;br&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; Для просмотра списка измененных файлов (состояние набора рабочих файлов) используется команда &lt;tt&gt;status&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr status&lt;br&gt; modified:&lt;br&gt;   hello.txt&lt;br&gt; unknown:&lt;br&gt;   foo.txt&lt;/samp&gt;&lt;br&gt; &lt;br&gt; &lt;tt&gt;bzr&lt;/tt&gt; показал, что файл &lt;tt&gt;hello.txt&lt;/tt&gt; был изменен, а также что появился неизвестный файл &lt;tt&gt;foo.txt&lt;/tt&gt;. Неизвестными (&lt;tt&gt;unknown&lt;/tt&gt;) считаются файлы, которые не находятся под контролем версий и не попадают в список игнорируемых (о списке игнорируемых файлов будет рассказано в других статьях). Поскольку команда &lt;tt&gt;commit&lt;/tt&gt; фиксирует состояние только тех файлов, которые находятся под контролем версий, то нам необходимо добавить новый файл командой &lt;tt&gt;add&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr add&lt;br&gt; adding foo.txt&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Теперь &lt;tt&gt;status&lt;/tt&gt; отрапортует о новом файле, как о добавленном:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr status&lt;br&gt; added:&lt;br&gt;   foo.txt&lt;br&gt; modified:&lt;br&gt;   hello.txt&lt;br&gt; &lt;/samp&gt;&lt;br&gt; Для того, чтобы увидеть не только имена изменных файлов, но и сами изменения в них, используется команда &lt;tt&gt;diff&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr diff&lt;br&gt; === added file 'foo.txt'&lt;br&gt; --- foo.txt     1970-01-01 00:00:00 +0000&lt;br&gt; +++ foo.txt     2009-03-10 13:13:56 +0000&lt;br&gt; @@ -0,0 +1,1 @@&lt;br&gt; +Новый файл&lt;br&gt; &lt;br&gt; === modified file 'hello.txt'&lt;br&gt; --- hello.txt   2009-03-10 09:06:24 +0000&lt;br&gt; +++ hello.txt   2009-03-10 13:14:11 +0000&lt;br&gt; @@ -1,1 +1,1 @@&lt;br&gt; -Привет&lt;br&gt; +Привет, мир!&lt;br&gt; &lt;br&gt; &lt;/samp&gt;Команда &lt;tt&gt;diff&lt;/tt&gt; отображает разницу между последним зафиксированным состоянием файла и текущим в формате &lt;tt&gt;unidiff&lt;/tt&gt; (изменения показываются в виде групп, знак минус в начале строки индицирует старый удаленный текст, знак плюс в начале строки индицирует новый добавленный текст).&lt;i&gt;&lt;br&gt; &lt;/i&gt; &lt;blockquote&gt;&lt;i&gt;Примечание для пользователей Windows&lt;/i&gt;: обычно русский текст в файлах сохраняется в кодировке &lt;tt&gt;cp1251&lt;/tt&gt; &lt;tt&gt;(ANSI)&lt;/tt&gt;, в то время как кодировка консоли &lt;tt&gt;cp866&lt;/tt&gt; &lt;tt&gt;(DOS/OEM)&lt;/tt&gt;. Для того, чтобы увидеть русский текст в выводе команды &lt;tt&gt;diff&lt;/tt&gt; нормально, а не ввиде иероглифов, переключите кодировку консоли командой:&lt;br&gt;   &lt;br&gt;   &lt;tt&gt;chcp 1251&lt;/tt&gt;&lt;br&gt;   &lt;br&gt; Обратное переключение осуществляется командой:&lt;br&gt;   &lt;br&gt;   &lt;tt&gt;chcp 866&lt;/tt&gt;&lt;br&gt; &lt;/blockquote&gt; Если пользователя удовлетворяют эти изменения, то он может их зафиксировать:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr commit -m "Внесены изменения для иллюстрации команд status и diff"&lt;br&gt; Committing to: C:/Temp/Test/&lt;br&gt; added foo.txt&lt;br&gt; modified hello.txt&lt;br&gt; Committed revision 2.&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;b&gt;Просмотр истории&lt;/b&gt;&lt;br&gt; &lt;br&gt; Для просмотра журнала изменений (зафиксированных ревизий) используется команда &lt;tt&gt;log&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;pre&gt;C:\Temp\Test&amp;gt;bzr log&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 2&lt;br&gt; committer: Alexander Belchenko &amp;lt;alexander.belchenko@gmail.com&amp;gt;&lt;br&gt; branch nick: Test&lt;br&gt; timestamp: Tue 2009-03-10 15:38:19 +0200&lt;br&gt; message:&lt;br&gt;   Внесены изменения для иллюстрации команд status и diff&lt;br&gt; ------------------------------------------------------------&lt;br&gt; revno: 1&lt;br&gt; committer: Alexander Belchenko &amp;lt;alexander.belchenko@gmail.com&amp;gt;&lt;br&gt; branch nick: Test&lt;br&gt; timestamp: Tue 2009-03-10 11:06:24 +0200&lt;br&gt; message:&lt;br&gt;   Начальное состояние файлов&lt;br&gt; &lt;/pre&gt;&lt;br&gt; &lt;div align="justify"&gt;Для каждой ревизии выводится информация о номере, о том кто и когда зафиксировал изменения (поля &lt;tt&gt;committer&lt;/tt&gt; и &lt;tt&gt;timestamp&lt;/tt&gt;), название ветки (&lt;tt&gt;branch nick&lt;/tt&gt;), а также комментарий (&lt;tt&gt;message&lt;/tt&gt;). Журнал изменений — это важный инструмент для анализа прошлых изменений.&lt;br&gt; &lt;br&gt; При запуске команды &lt;tt&gt;bzr log&lt;/tt&gt; с опцией &lt;tt&gt;--verbose (-v)&lt;/tt&gt; для каждой ревизии будет выведен список измененных файлов, аналогично команде &lt;tt&gt;status&lt;/tt&gt;. Впрочем, вы можете использовать и команды &lt;tt&gt;status&lt;/tt&gt; и &lt;tt&gt;diff&lt;/tt&gt; для просмотра зафиксированных изменений. У этих команд есть опция &lt;tt&gt;--change (-c)&lt;/tt&gt;, которая позволяет просмотреть изменения зафиксированные в определенной ревизии:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr status -c 2&lt;br&gt; added:&lt;br&gt;   foo.txt&lt;br&gt; modified:&lt;br&gt;   hello.txt&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;/div&gt; Также можно указать произвольный диапазон ревизий для просмотра внесенных изменений. Например, те же самые изменения во второй ревизии можно увидеть, если указать диапазон ревизий &lt;tt&gt;1..2&lt;/tt&gt;:&lt;br&gt; &lt;br&gt; &lt;samp&gt;C:\Temp\Test&amp;gt;bzr status -r 1..2&lt;br&gt; added:&lt;br&gt;   foo.txt&lt;br&gt; modified:&lt;br&gt;   hello.txt&lt;br&gt; &lt;/samp&gt;&lt;br&gt; &lt;br&gt; Итак, мы рассмотрели базовый набор команд для работы с одной локальной веткой. Конечно, это далеко не все полезные команды, но это тот минимум без которого работать не получится вовсе.&lt;br&gt; Во второй части статьи мы рассмотрим совместную работу с несколькими ветками.&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-5572782052448718280?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/5572782052448718280/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-1.html#comment-form' title='Комментарии: 13'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5572782052448718280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/5572782052448718280'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-1.html' title='Начинаем работу с bzr: базовый набор команд (Часть 1)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-4642482538427754434</id><published>2009-03-04T20:32:00.053Z</published><updated>2009-03-07T19:44:54.066Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='исправление ошибок'/><title type='text'>Исправление ошибок при работе с Bazaar</title><content type='html'>&lt;span style="font-style: italic;"&gt;Errare humanum est (человеку свойственно ошибаться)&lt;/span&gt; — утверждение, с которым невозможно поспорить. Мудрый подход состоит не в том, чтобы пытаться избегать ошибок, а в том, чтобы научиться их исправлять.

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

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

Плюс ко всему этому, Bazaar предлагает свои подходы и команды для работы над ошибками, которые мы и рассмотрим ниже в приложении к типичным ситуациям.

Если вы случайно ошиблись при создании ветки Bazaar из дерева исходного кода (с помощью команды &lt;tt&gt;bzr init&lt;/tt&gt;) и превратили в ветку не то дерево, самое простое, что можно сделать - это удалить появившуюся служебную директорию &lt;tt&gt;.bzr&lt;/tt&gt;. Конечно, здесь нужно быть внимательным чтобы не удалить нужную служебную директорию.

Другая типичная ситуация - добавление под контроль версий (с помощью команды &lt;tt&gt;bzr add&lt;/tt&gt;) не того файла. Часто в рабочей директории могут находится временные файлы, журналы тестовых запусков, или другие файлы, которые не нужно хранить под контролем версий. Но в случае выполнения команды &lt;tt&gt;bzr add&lt;/tt&gt; без параметров, под контроль версий попадут все неизвестные файлы (исключая файлы указанные для игнорирования). Эту ситуацию можно исправить с помощью команды &lt;tt&gt;bzr remove&lt;/tt&gt;. При этом команда &lt;tt&gt;remove&lt;/tt&gt; без опций не будет удалять неизвестный, или измененный файл:
&lt;pre&gt;$ bzr add
$ bzr remove file.tmp
bzr: ERROR: Can't safely remove modified or unknown files:
added:
    file.tmp
Use --keep to not delete them, or --force to delete them regardless.&lt;/pre&gt;
Здесь мы можем использовать опцию &lt;tt&gt;--keep&lt;/tt&gt; что бы оставить файл как неизвестный и удалить его только из под контроля версий. Или можно использовать опцию &lt;tt&gt;--force&lt;/tt&gt; для полного удаления файла. Но, если файл уже был зарегистрирован и не изменялся, то команда &lt;tt&gt;remove&lt;/tt&gt; удалит его без необходимости указания дополнительных опций, т.к. файл может быть восстановлен на момент предыдущей ревизии с помощью команды &lt;tt&gt;revert&lt;/tt&gt;, которую мы рассмотрим ниже:
&lt;pre&gt;$ bzr add TODO
$ bzr commit -m "Добавлен TODO"
$ bzr remove TODO&lt;/pre&gt;
В случае, если не использовать команды Bazaar, а просто удалить файл с помощью команды операционной системы, то файл автоматически будет удален и из под контроля версий.

Теперь представим, что мы решили попробовать какой-то новый вариант в проекте, изменили несколько файлов, но попытка не удалась и хочется просто вернуться к состоянию на момент последней фиксации изменений. В этом случае мы можем использовать команду &lt;tt&gt;revert&lt;/tt&gt;:
&lt;pre&gt;$ bzr revert&lt;/pre&gt;

Эта команда отменит все изменения в рабочей директории с момента последней фиксации (в том числе будут восстановлены удаленные файлы). В этом случае хорошей практикой является предварительное использование команд &lt;tt&gt;bzr status&lt;/tt&gt; и &lt;tt&gt;bzr diff&lt;/tt&gt;, что бы быть уверенным, что при отмене изменений не пропадет что-то нужное. Команда &lt;tt&gt;revert&lt;/tt&gt; также позволяет указывать имена файлов для которых нужно отменить изменения:
&lt;pre&gt;$ bzr revert file.txt&lt;/pre&gt;
При этом все остальные измененные файлы останутся нетронутыми.

Еще одна уникальная для Bazaar функция (по крайней мере я не видел в других системах такого простого интерфейса) для работы надо ошибками — команда &lt;tt&gt;uncommit&lt;/tt&gt;. С ее помощью можно отменить последнюю фиксацию и вернуть рабочее дерево в состояние на момент до выполнения фиксации. Незаменимая вещь на случай опечатки в сообщении о фиксации:
&lt;pre&gt;$ bzr commit -m "Очепятка"
$ bzr uncommit
$ bzr commit -m "Опечатка"
&lt;/pre&gt;
Кроме этого, с &lt;tt&gt;uncommit&lt;/tt&gt; можно использовать опцию &lt;tt&gt;-r&lt;/tt&gt; для отмены сразу нескольких ревизий:
&lt;pre&gt;$ bzr uncommit -r -3&lt;/pre&gt;

При этом рабочее дерево останется в том же состоянии что и до выполнения отмененных фиксаций. С командой &lt;tt&gt;revert&lt;/tt&gt; также можно использовать опцию &lt;tt&gt;-r&lt;/tt&gt; для возврата рабочего дерева в состояние до указанной ревизии, но ревизии при этом не удаляются:
&lt;pre&gt;$ bzr commit -m "Исправления"
(выпуск релиза)
$ bzr revert -r -2
$ bzr commit -m "Отменено исправление"
(выпуск следующего релиза)&lt;/pre&gt;

Также рассмотрим исправления, связанные с метками. Если вы поставили для ревизии метку с помощью команды &lt;tt&gt;bzr tag&lt;/tt&gt;, но после этого обнаружили, что ее лучше перенести на более позднюю ревизию, то можно воспользоваться опцией &lt;tt&gt;--force&lt;/tt&gt;:

&lt;pre&gt;$ bzr tag 1.0
(еще рано для первой версии, нужно сделать несколько изменений)
$ bzr tag 1.0 --force&lt;/pre&gt;

Метка также может быть удалена с помощью опции &lt;tt&gt;--delete&lt;/tt&gt;:
&lt;pre&gt;$ bzr tag 1.0
(еще рано для первой версии, нам пока не нужна метка)
$ bzr tag 1.0 --delete&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-4642482538427754434?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/4642482538427754434/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bazaar.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4642482538427754434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/4642482538427754434'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bazaar.html' title='Исправление ошибок при работе с Bazaar'/><author><name>Dmitry Vasiliev</name><uri>http://www.blogger.com/profile/00061696491069141929</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='http://2.bp.blogspot.com/_IMMKOFdsrBs/SaVM6sgwSlI/AAAAAAAAAAM/w5eRtt_fGyo/s1600-R/dmitry_vasiliev.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-3336588026572442081</id><published>2009-03-01T21:11:00.002Z</published><updated>2009-03-07T14:37:29.496Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='справка'/><title type='text'>bzr help: встроенная справочная служба класса "люкс" (Часть 2)</title><content type='html'>Рассмотрим вывод справочной информации на примере команды &lt;tt&gt;branch&lt;/tt&gt;, и посмотрим какую информацию мы там можем найти.&lt;br&gt; &lt;pre&gt;C:\&amp;gt;bzr help branch
Purpose: Create a new copy of a branch.
Usage:   bzr branch FROM_LOCATION [TO_LOCATION]

Options:
  --stacked             Create a stacked branch referring to the source
                        branch. The new branch will depend on the availability
                        of the source branch for all operations.
  -v, --verbose         Display more information.
  --standalone          Do not use a shared repository, even if available.
  -h, --help            Show help message.
  -q, --quiet           Only display errors and warnings.
  --hardlink            Hard-link working tree files where possible.
  -r ARG, --revision=ARG
                        See "help revisionspec" for details.

Description:
  If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
  be used.  In other words, "branch ../foo/bar" will attempt to create ./bar.
  If the FROM_LOCATION has no / or path separator embedded, the TO_LOCATION
  is derived from the FROM_LOCATION by stripping a leading scheme or drive
  identifier, if any. For example, "branch lp:foo-bar" will attempt to
  create ./foo-bar.

  To retrieve the branch as of a particular revision, supply the --revision
  parameter, as in "branch foo/bar -r 5".

Aliases:  get, clone
See also: checkout
&lt;/pre&gt; Здесь:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;Purpose — назначение команды&lt;/li&gt;   &lt;li&gt;Usage — командная строка с указанием ожидаемых аргументов&lt;br&gt;   &lt;/li&gt;   &lt;li&gt;Options — опции командной строки&lt;/li&gt;   &lt;li&gt;Description — подробное описание команды и вариантов использования&lt;/li&gt;   &lt;li&gt;Aliases — встроенные псевдонимы для команды&lt;/li&gt;   &lt;li&gt;See also — ссылки на схожие по тематике разделы справки&lt;/li&gt; &lt;/ul&gt; &lt;b&gt;Аргументы командной строки&lt;/b&gt;&lt;br&gt; &lt;br&gt; Необязательные аргументы отобажаются в квадратных скобках. Если ожидается один или больше аргументов, то вы увидите многоточие после имени аргумента.&lt;br&gt; &lt;br&gt; &lt;b&gt;Опции командной строки&lt;/b&gt;&lt;br&gt; &lt;br&gt; Опции могут использоваться вперемешку с аргументами, стоять до или после них. Очень удобно.&lt;br&gt; &lt;br&gt; Опции &lt;tt&gt;-v&lt;/tt&gt; и &lt;tt&gt;-q&lt;/tt&gt; отображаются для всех команд, однако для некоторых команд они не имеют эффекта.&lt;br&gt; &lt;br&gt; &lt;b&gt;Псевдонимы&lt;/b&gt;&lt;br&gt; &lt;br&gt; &lt;div align="justify"&gt;Некоторые команды могут иметь псевдонимы. Это сделано для удобства и для имитации поведения других систем контроля версий, чтобы пользователям при переходе на Базар было легче осваиваться. Во многих случаях псевдонимы предлагают более короткую форму записи имени для часто используемых команд. Так например, команда &lt;tt&gt;status&lt;/tt&gt; имеет псевдоним &lt;tt&gt;st&lt;/tt&gt;, а команда &lt;tt&gt;diff&lt;/tt&gt; имеет псевдоним &lt;tt&gt;di&lt;/tt&gt;.&lt;br&gt; &lt;br&gt; В дополнение к встроенным псевдонимам Базар поддерживает также псевдонимы определяемые пользователем. О них мы расскажем в следующих статьях.&lt;br&gt; &lt;br&gt; &lt;b&gt;See also (см. также)&lt;/b&gt;&lt;br&gt; &lt;br&gt; Многие справочные разделы (не только справка к командам) дают подсказку и наводку на материалы, схожие по тематике либо отражающие другой вариант использования. Часто так можно найти ценные советы и подсказки.&lt;br&gt; &lt;br&gt; Итак, теперь вы знаете об использовании справки достаточно, чтобы не растеряться в ответственный момент. Помните, что аргументы и опции можно записывать вперемешку, и что опция &lt;tt&gt;-h (--help)&lt;/tt&gt; выводит справку по команде без запуска самой команды. Так что если вы начали писать команду и вдруг решили перечитать справку по ней, то можете просто дописать -h в конце и нажать Enter. А прочитав справку, вызовите предыдущую команду (в большинстве командных процессоров это делается просто нажатием стрелки вверх) и отредактируйте ее нужным образом.&lt;br&gt; &lt;br&gt; Также не забывайте, что справка ко многим командам довольно обширна, поэтому помните про использование программ типа &lt;tt&gt;more&lt;/tt&gt; или &lt;tt&gt;less&lt;/tt&gt;.&lt;br&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-3336588026572442081?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/3336588026572442081/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-help-2.html#comment-form' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3336588026572442081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3336588026572442081'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/03/bzr-help-2.html' title='bzr help: встроенная справочная служба класса &quot;люкс&quot; (Часть 2)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-137167474480120536</id><published>2009-02-25T20:56:00.003Z</published><updated>2009-03-07T14:37:29.497Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='справка'/><title type='text'>bzr help: встроенная справочная служба класса "люкс" (Часть 1)</title><content type='html'>&lt;div align="justify"&gt;Любому пользователю bzr (от новичка до профи) время от времени нужна справочная информация: всего не упомнишь, всех нюансов в голове не удержишь, тем более если речь идет о мало используемых или незнакомых командах и опциях. В таких ситуациях нужно помнить главное: справка у вас всегда под руками. И я говорю не про &lt;tt&gt;man bzr&lt;/tt&gt;, а про встроенный механизм справки, вызываемый по команде &lt;tt&gt;bzr help&lt;/tt&gt;.

Команда &lt;tt&gt;bzr help&lt;/tt&gt;, помимо очевидных вещей типа справки к командам и опциям, имеет также неплохой каталог дополнительной справочной информации о базовых концепциях, настройках и конфигурации bzr, и даже такой материал как объяснение типов конфликтов объединения и как с ними бороться. Должен сказать, что разработчики bzr уделяют справке внимание, что положительно сказывается на ее количестве и качестве. Многие пункты справки содержат информации на несколько экранов, так что для удобства чтения используйте программы типа &lt;tt&gt;more&lt;/tt&gt; или &lt;tt&gt;less. &lt;/tt&gt;
&lt;/div&gt; &lt;div align="justify"&gt; &lt;blockquote&gt;&lt;i&gt;Полезный совет для пользователей Windows: &lt;/i&gt;скачайте и установите программу &lt;tt&gt;&lt;a href="http://gnuwin32.sourceforge.net/packages/less.htm"&gt;less&lt;/a&gt;&lt;/tt&gt;, которая значительно превосходит по функциональности стандартную &lt;tt&gt;more&lt;/tt&gt;. После установки добавьте папку с программой в список в переменную окружения &lt;tt&gt;PATH&lt;/tt&gt;.
&lt;/blockquote&gt; &lt;/div&gt; Итак, посмотрим, что же может предложить &lt;tt&gt;bzr help&lt;/tt&gt;. Запускаем и видим краткую сводку по базовым командам:
&lt;blockquote&gt;&lt;pre&gt;C:\&amp;gt;bzr help
Bazaar -- a free distributed version-control tool
http://bazaar-vcs.org/

Basic commands:
bzr init           makes this directory a versioned branch
bzr branch         make a copy of another branch

bzr add            make files or directories versioned
bzr ignore         ignore a file or pattern
bzr mv             move or rename a versioned file

bzr status         summarize changes in working copy
bzr diff           show detailed diffs

bzr merge          pull in changes from another branch
bzr commit         save some or all changes
bzr send           send changes via email

bzr log            show history of changes
bzr check          validate storage

bzr help init      more help on e.g. init command
bzr help commands  list all commands
bzr help topics    list all help topics
&lt;/pre&gt;&lt;/blockquote&gt; Команды сгруппированы по назначению:
&lt;ul&gt;   &lt;li&gt;&lt;tt&gt;init, branch&lt;/tt&gt; — создание новой ветки с нуля или путем клонирования существующей
&lt;/li&gt;   &lt;li&gt;&lt;tt&gt;add, ignore, mv&lt;/tt&gt; — процесс добавления файлов под контроль версий, информирование об игнорируемых объектах, переименование через bzr&lt;/li&gt;   &lt;li&gt;&lt;tt&gt;status, diff&lt;/tt&gt; — просмотр изменений в файлах&lt;/li&gt;   &lt;li&gt;&lt;tt&gt;merge, commit, send&lt;/tt&gt; — фиксация изменений (commit), объединений изменений в двух ветках (merge), отправка патчей по электронной почте (send)&lt;/li&gt;   &lt;li&gt;&lt;tt&gt;log &lt;/tt&gt;— просмотр истории изменений&lt;/li&gt; &lt;/ul&gt; Ниже вы видите пример того, как получить справку по конкретной команде — например, вызывая &lt;tt&gt;bzr help init &lt;/tt&gt;либо используя опцию &lt;tt&gt;-h&lt;/tt&gt; или &lt;tt&gt;--help&lt;/tt&gt; после имени команды&lt;tt&gt;: bzr init -h&lt;/tt&gt;.

Для того, чтобы получить список всех доступных команд, запустите &lt;tt&gt;bzr help commands&lt;/tt&gt;; рекомендую использовать less для просмотра:
&lt;blockquote&gt;&lt;tt&gt;bzr help commands | less
&lt;/tt&gt;&lt;/blockquote&gt; Будет выведен список всех команд в алфавитном  порядке с кратким описанием для каждой команды.

Обратите внимание на команду &lt;tt&gt;bzr help topics&lt;/tt&gt;.

&lt;div align="justify"&gt;Эта команда выводит оглавление всех доступных материалов встроенной справки в виде списка: слева названия статей, справа — краткое описание материала. Ниже приведены первые несколько строк из списка статей (для bzr 1.12):
&lt;/div&gt; &lt;blockquote&gt;&lt;pre&gt;C:\&amp;gt;bzr help topics
authentication       Information on configuring authentication
basic                Basic commands
branches             Information on what a branch is
bugs                 Bug tracker settings
checkouts            Information on what a checkout is
commands             Basic help for all commands
configuration        Details on the configuration settings available
conflicts            Types of conflicts and what to do about them
&lt;/pre&gt;&lt;/blockquote&gt; Используйте название статьи для доступа к ее тексту. Например, команда &lt;tt&gt;
&lt;/tt&gt; &lt;blockquote&gt;&lt;tt&gt;bzr help &lt;/tt&gt;&lt;tt&gt;configuration&lt;/tt&gt;
&lt;/blockquote&gt; выведет справку по имеющимся настройкам для bzr.

Во второй части мы рассмотрим подробнее назначение дополнительных полей справочной информации.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-137167474480120536?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/137167474480120536/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr-help-1.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/137167474480120536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/137167474480120536'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr-help-1.html' title='bzr help: встроенная справочная служба класса &quot;люкс&quot; (Часть 1)'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-7679209709218485</id><published>2009-02-24T00:51:00.001Z</published><updated>2009-03-07T14:37:19.827Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='настройки'/><title type='text'>Настройки bzr: whoami или как меня зовут</title><content type='html'>После установки bzr сразу можно приступать к работе, однако стоит потратить пару минут на настройку некоторых важных параметров.

Одним из таких параметров является ваша личная идентификация. Другими словами — ваше имя, ваш идентификатор для bzr. Это имя будет использоваться bzr для подписывания изменений, которые вы будете фиксировать. И поскольку история ваших фиксаций будет оставаться неизменной все время, то стоит позаботиться о том, чтобы ваше имя отображалось правильно.

Чтобы узнать ваш текущий идентификатор используйте команду: &lt;tt&gt;
&lt;/tt&gt; &lt;blockquote&gt;&lt;tt&gt;bzr whoami&lt;/tt&gt;
&lt;/blockquote&gt; Запущенная без параметров эта команда для типичного Василия Пупкина, работающего на своем домашнем компьютере, выведет нечто похожее на:
&lt;blockquote&gt;&lt;tt&gt;vasya@home&lt;/tt&gt;
&lt;/blockquote&gt; Если подобный идентификатор вас устраивает, то можете ничего не менять. Иначе задайте свое настоящее имя при помощи этой же команды &lt;tt&gt;whoami&lt;/tt&gt;, но с соответствующим аргументом:
&lt;blockquote&gt;&lt;tt&gt;bzr whoami "Василий Пупкин &lt;a class="moz-txt-link-rfc2396E" href="mailto:vasya.pupkin@gmail.com"&gt;&amp;lt;vasya.pupkin@gmail.com&amp;gt;&lt;/a&gt;"
  &lt;/tt&gt;&lt;/blockquote&gt; Здесь в кавычкаx задается имя и дополнительно может задаваться электронный почтовый адрес (в угловых скобках). Проверим установки:
&lt;blockquote&gt;&lt;tt&gt;$ bzr whoami
  &lt;/tt&gt;&lt;tt&gt;Василий Пупкин &lt;a class="moz-txt-link-rfc2396E" href="mailto:vasya.pupkin@gmail.com"&gt;&amp;lt;vasya.pupkin@gmail.com&amp;gt;&lt;/a&gt;
  &lt;/tt&gt;&lt;/blockquote&gt; Настройка вашего идентификатора сохраняется &lt;a href="http://doc.bazaar-vcs.org/latest/en/user-reference/bzr_man.html#configuration-settings"&gt;в файле глобальных настроек &lt;tt&gt;bazaar.conf&lt;/tt&gt;&lt;/a&gt; (в вашем домашнем каталоге). Этот идентификатор будет использоваться для фиксации всех веток. О том, как задать отличающийся идентификатор для некоторых веток будет рассказано в следующих статьях.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-7679209709218485?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/7679209709218485/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr-whoami.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/7679209709218485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/7679209709218485'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr-whoami.html' title='Настройки bzr: whoami или как меня зовут'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-3728682867734647263</id><published>2009-02-23T21:16:00.000Z</published><updated>2009-03-07T14:37:57.357Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Установка bzr</title><content type='html'>Для установки bzr в вашей системе нужно выбрать соответствующий пакет или дистрибутив из перечисленных на странице &lt;a  href="http://bazaar-vcs.org/Download"&gt;Download&lt;/a&gt;.&lt;br&gt; Кратко рассмотрим варианты установки для различных операционных систем.&lt;br&gt; &lt;br&gt; &lt;b&gt;Установка из исходных кодов&lt;br&gt; &lt;br&gt; &lt;/b&gt;Система контроля версий Bazaar написана на языке программирования Python (Питон), что облегчает ее установку и использование: достаточно иметь установленный интерпретатор языка Python в вашей системе (версии 2.4–2.6, рекомендуется 2.5). Опытные пользователи Python могут использовать стандартное "заклинание": &lt;tt&gt;python setup.py install&lt;/tt&gt; для установки. Более подробно об опциях установки можно прочитать в файле &lt;tt&gt;INSTALL&lt;/tt&gt;.&lt;b&gt;&lt;br&gt; &lt;br&gt; Установка для ОС Linux&lt;br&gt; &lt;br&gt; &lt;/b&gt;Для большинства популярных дистрибутивов Linux имеются готовые пакеты для установки bzr. Каждый конкретный дистрибутив имеет свои особенности, поэтому ознакомьтесь с детальными инструкциями  на странице &lt;a href="http://bazaar-vcs.org/DistroDownloads"&gt;DistroDownloads&lt;/a&gt;. &lt;br&gt; &lt;br&gt; Если вы используете Ubuntu Linux, то скорее всего bzr уже будет установлен в вашей системе. Однако вам имеет смысл ознакомиться с процессом обновления bzr, для того, чтобы регулярно устанавливать свежую версию. Разработка bzr идет достаточно интенсивно и примерно каждый месяц выпускается новая версия. Новые версии как правило работают быстрее и содержат значительное количество исправлений известных ошибок.&lt;br&gt; &lt;br&gt; &lt;b&gt;Установка для ОС Windows&lt;/b&gt;&lt;br&gt; &lt;br&gt; Наиболее оптимальным и рекомендуем способом установки bzr в ОС Windows является использование инсталлятора автономной версии (Windows Standalone Installer). Автономная версия содержит скомпилированную программу bzr.exe для Windows, и поставляется с набором всех необходимых библиотек. Также инсталлятор автономной версии предлагает установить набор популярных плагинов для bzr, а также программу TortoiseBzr, которая предоставляет интеграцию bzr-команд в Explorer.&lt;br&gt; &lt;br&gt; Альтернативным вариантом установки является использование инсталляторов питон-версии bzr (python installer). Для работы питон-версии вам потребуется установленный интерпретатор Python (версии 2.4–2.6, рекомендуется 2.5), а также набор дополнительных библиотек. См. &lt;a class="moz-txt-link-freetext" href="http://bazaar-vcs.org/WindowsInstall"&gt;http://bazaar-vcs.org/WindowsInstall&lt;/a&gt; для дополнительных инструкций.&lt;br&gt; &lt;br&gt; В большинстве случаев выбор автономной версии bzr.exe — это оптимальный вариант. Однако, если вам понадобится интегрировать bzr с другими питон-программами, то установка питон-версии может оказаться единственным работающим вариантом.&lt;br&gt; &lt;br&gt; &lt;b&gt;Установка для ОС Mac OS X&lt;/b&gt;&lt;br&gt; &lt;br&gt; Для компьютеров фирмы Apple также имеются готовые инсталляторы, а также специальные репозитории портированных программ: MacPorts и Fink. См. ссылки на подробные инструкции на странице &lt;a  href="http://bazaar-vcs.org/Download"&gt;Download&lt;/a&gt;.&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2343702891633188276-3728682867734647263?l=bzr-day.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bzr-day.blogspot.com/feeds/3728682867734647263/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3728682867734647263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2343702891633188276/posts/default/3728682867734647263'/><link rel='alternate' type='text/html' href='http://bzr-day.blogspot.com/2009/02/bzr.html' title='Установка bzr'/><author><name>bialix</name><uri>http://www.blogger.com/profile/03276301722234350242</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2343702891633188276.post-5984666235096538220</id><published>2009-02-23T19:40:00.000Z</published><updated>2009-03-07T14:37:57.357Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='общее'/><title type='text'>Bazaar: зачем и почему</title><content type='html'>Сегодня о распределенных системах контроля версий слышали и знают многие. Несмотря на то, что &lt;a href="http://subversion.tigris.org"&gt;svn&lt;/a&gt; по-прежнему лидирует и все еще является наиболее часто используемой системой контроля версий (особенно в корпоративном секторе), однако распределенные системы нового поколения продолжают набирать популярность.&lt;br&gt; &lt;br&gt; К распределенным системам нового поколения относят &lt;a  href="http://git-scm.com"&gt;Git&lt;/a&gt; (Гит), &lt;a  href="http://www.selenic.com/mercurial"&gt;Mercurial&lt;/a&gt; (Меркуриал) и &lt;a  href="http://bazaar-vcs.org"&gt;Bazaar&lt;/a&gt; (Базар). Все три системы появились на свет более-менее в одно время (конец 2004 – начало 2005 года). Список современных распределенных систем контроля версий также дополняют &lt;a href="http://darcs.net"&gt;Darcs&lt;/a&gt; и &lt;a  href="http://monotone.ca"&gt;Monotone&lt;/a&gt;.&lt;br&gt; &lt;br&gt; В распределенных системах каждая копия репозитория является самодостаточной сущностью: пользователь может производить все операции над файлами или историей изменений без необходимости подключаться к некоторому центральному серверу. В дополнение к этому пользователь может свободно объединять изменения из разных копий одного репозитория. Вместе с тем распределенные системы могут поддерживать и централизованную модель работы с использованием некоторого центрального сервера, что позволяет назвать их надмножеством централизованных систем контроля версий.&lt;br&gt; &lt;br&gt; Развитию распределенных систем контроля версий способствуют два основных фактора:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;бурное развитие глобальной сети интернет&lt;/li&gt;   &lt;li&gt;наличие доступных по цене переносных компьютеров (ноутбуков и нетбуков)&lt;/li&gt; &lt;/ul&gt; Первый фактор способствует образованию множества географически распределенных команд, работающих над одним проектом; в первую очередь это касается проектов с открытым кодом (Open source projects). Второй фактор позволяет разработчикам использовать долгие путешествия (поезд, самолет) для того, чтобы продолжать работать над своими проектами. Поскольку полная копия репозитория всегда доступна локально (на жестком диске компьютера разработчика) и практически все операции можно делать без соединения с сервером, то это с одной стороны позволяет достичь более высокой скорости работы, а с другой стороны работать в условиях отсутствия подключения к сети.&lt;br&gt; &lt;br&gt; Все современные распределенные системы контроля версий имеют свои достоинства и недостатки. Поэтому у каждой системы есть свой круг приверженцев. Выбрать систему, наиболее полно удовлетворяющую вашим требованиям и привычкам, может оказаться нелегко. В любом случае надо будет поработать с одной-двумя выбранными системами, чтобы увидеть их в действии и оценить степень пригодности.&lt;br&gt; &lt;br&gt; Гит и Меркуриал изнача
