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

Начинаем работу с bzr: базовый набор команд (Часть 1)

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

Сценарий работы

Инициализируем в локальном каталоге новую ветку для работы. В этом каталоге создадим несколько рабочих файлов. Добавим эти файлы под контроль версий. Зафиксируем начальное состояние файлов. Изменим некоторые из файлов. Просмотрим изменения в файлах. Зафиксируем новое состояние файлов. Просмотрим историю изменений. Создадим копию ветки для параллельной работы. Изменим некоторые файлы в старой и новой ветках и зафиксируем новое состояние. Объединим изменения в двух ветках.

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

Команды

В вышеприведенном сценарии работы выделены действия, производимые при помощи bzr. Команды bzr используют английские термины, соответствующие выполняемым действиям:

initИнициализацияИнициализация новой ветки
add
Добавить
Добавить файлы под контроль версий
commit
Зафиксировать
Зафиксировать состояние файлов
status
Состояние
Показать состояние файлов, отобразить имена измененных файлов
diff
Разница
Показать изменения в файлах
log
Журнал
Просмотр журнала изменений, истории изменений
branch
Ветка
Создать новую ветку
merge
Объединить
Объединить изменения из разных веток

Используем команды из таблицы для "перевода" нашего сценария с русского языка на язык команд bzr. В примерах использовался bzr 1.12. Если вы используете другую версию, то сообщения bzr могут незначительно отличаться.

Инициализировать новую ветку

Инициализировать новую ветку в текущем каталоге:

C:\Temp\Test>bzr init
Created a standalone tree (format: pack-0.92)

В качестве аргумента команде init можно указать путь для создания новой ветки, новый каталог будет создан при необходимости.
При инициализации создается служебный каталог с именем .bzr, в котором хранятся служебные файлы и история изменений.
Новая ветка инициализирована — можно добавлять файлы.

Добавить новые файлы

Для примера создадим два текстовых файла в рабочем каталоге:

-------Файл hello.txt---------
Привет
------------------------------

------Файл goodbye.txt--------
Пока
------------------------------

Добавим файлы под контроль версий:

C:\Temp\Test>bzr add
adding goodbye.txt
adding hello.txt

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

Файлы добавлены — можно фиксировать их состояние.

Зафиксировать состояние файлов

Фиксация запоминает текущее состояние файлов. Пользователь должен дать комментарий к фиксируемым изменениям. Этот комментарий затем можно будет увидеть при просмотре журнала изменений. Хорошей практикой является описание цели и сути изменений в комментарии: конкретные изменения можно просмотреть при помощи команд bzr, а вот мотивы и цели изменений знает только автор изменений. Со временем это знание утрачивается, поэтому старайтесь писать четкие комментарии, которые будут понятны и через неделю/месяц/год.

C:\Temp\Test>bzr commit -m "Начальное состояние файлов"
Committing to: C:/Temp/Test/
added goodbye.txt
added hello.txt
Committed revision 1.

Опция -m (--message) используется для указания комментария. Пользователь также может указать имя файла, из которого будет прочитан комментарий (используется опция --file, -F). Либо можно не указывать ничего, в этом случае будет запущен текстовый редактор, в котором вы сможете ввести свой комментарий.

Просмотр изменений

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

Изменим файл hello.txt и создадим новый файл foo.txt:

-------Файл hello.txt---------
Привет, мир!
------------------------------

--------Файл foo.txt----------
Новый файл
------------------------------

Для просмотра списка измененных файлов (состояние набора рабочих файлов) используется команда status:

C:\Temp\Test>bzr status
modified:
  hello.txt
unknown:
  foo.txt


bzr показал, что файл hello.txt был изменен, а также что появился неизвестный файл foo.txt. Неизвестными (unknown) считаются файлы, которые не находятся под контролем версий и не попадают в список игнорируемых (о списке игнорируемых файлов будет рассказано в других статьях). Поскольку команда commit фиксирует состояние только тех файлов, которые находятся под контролем версий, то нам необходимо добавить новый файл командой add:

C:\Temp\Test>bzr add
adding foo.txt

Теперь status отрапортует о новом файле, как о добавленном:

C:\Temp\Test>bzr status
added:
  foo.txt
modified:
  hello.txt

Для того, чтобы увидеть не только имена изменных файлов, но и сами изменения в них, используется команда diff:

C:\Temp\Test>bzr diff
=== added file 'foo.txt'
--- foo.txt     1970-01-01 00:00:00 +0000
+++ foo.txt     2009-03-10 13:13:56 +0000
@@ -0,0 +1,1 @@
+Новый файл

=== modified file 'hello.txt'
--- hello.txt   2009-03-10 09:06:24 +0000
+++ hello.txt   2009-03-10 13:14:11 +0000
@@ -1,1 +1,1 @@
-Привет
+Привет, мир!

Команда diff отображает разницу между последним зафиксированным состоянием файла и текущим в формате unidiff (изменения показываются в виде групп, знак минус в начале строки индицирует старый удаленный текст, знак плюс в начале строки индицирует новый добавленный текст).
Примечание для пользователей Windows: обычно русский текст в файлах сохраняется в кодировке cp1251 (ANSI), в то время как кодировка консоли cp866 (DOS/OEM). Для того, чтобы увидеть русский текст в выводе команды diff нормально, а не ввиде иероглифов, переключите кодировку консоли командой:

chcp 1251

Обратное переключение осуществляется командой:

chcp 866
Если пользователя удовлетворяют эти изменения, то он может их зафиксировать:

C:\Temp\Test>bzr commit -m "Внесены изменения для иллюстрации команд status и diff"
Committing to: C:/Temp/Test/
added foo.txt
modified hello.txt
Committed revision 2.

Просмотр истории

Для просмотра журнала изменений (зафиксированных ревизий) используется команда log:

C:\Temp\Test>bzr log
------------------------------------------------------------
revno: 2
committer: Alexander Belchenko <alexander.belchenko@gmail.com>
branch nick: Test
timestamp: Tue 2009-03-10 15:38:19 +0200
message:
  Внесены изменения для иллюстрации команд status и diff
------------------------------------------------------------
revno: 1
committer: Alexander Belchenko <alexander.belchenko@gmail.com>
branch nick: Test
timestamp: Tue 2009-03-10 11:06:24 +0200
message:
  Начальное состояние файлов

Для каждой ревизии выводится информация о номере, о том кто и когда зафиксировал изменения (поля committer и timestamp), название ветки (branch nick), а также комментарий (message). Журнал изменений — это важный инструмент для анализа прошлых изменений.

При запуске команды bzr log с опцией --verbose (-v) для каждой ревизии будет выведен список измененных файлов, аналогично команде status. Впрочем, вы можете использовать и команды status и diff для просмотра зафиксированных изменений. У этих команд есть опция --change (-c), которая позволяет просмотреть изменения зафиксированные в определенной ревизии:

C:\Temp\Test>bzr status -c 2
added:
  foo.txt
modified:
  hello.txt

Также можно указать произвольный диапазон ревизий для просмотра внесенных изменений. Например, те же самые изменения во второй ревизии можно увидеть, если указать диапазон ревизий 1..2:

C:\Temp\Test>bzr status -r 1..2
added:
  foo.txt
modified:
  hello.txt


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

13 комментариев:

  1. А с русскими именами файлов как дела обстоят ;)?

    ОтветитьУдалить
  2. С русскими именами файлов все в порядке. Внутри Базар работает с именами файлов как unicode строками. Поэтому ситуация гораздо лучше чем в git или hg ;-)

    Попробуйте и убедитесь сами:

    C:\Temp\Test>echo > Тест

    C:\Temp\Test>bzr status
    unknown:
    Тест

    C:\Temp\Test>bzr add
    adding "Тест"

    C:\Temp\Test>bzr status
    added:
    Тест

    ОтветитьУдалить
  3. Или такой пример:

    C:\Temp\Test>echo > Привет

    C:\Temp\Test>bzr add
    adding "Привет"

    C:\Temp\Test>bzr status
    added:
    Привет

    ОтветитьУдалить
  4. Проделать эксперимент с созданием foo изменением hello, в результате когда проделываю bzr diff выводится иероглифами, пробовал менять кодовою страницу с помощью chcp толку никакого. Пробловал использовать bzr qdiff открывается окно, но в нем сравнения тоже иероглифами

    ОтветитьУдалить
  5. > Проделать эксперимент с созданием foo изменением hello, в результате когда проделываю bzr diff выводится иероглифами, пробовал менять кодовою страницу с помощью chcp толку никакого.

    Щелкните правой кнопкой мыши по кнопке окна консоли на панели задач, выберите в появившемся меню "Свойства", перейдите на вкладку "Шрифт", выберите шрифт Lucida Console и нажмите OK. После этого chcp 1251 будет работать как положено. Пробуйте.

    > Пробловал использовать bzr qdiff открывается окно, но в нем сравнения тоже иероглифами

    Пробуйте так: bzr qdiff --encoding cp1251

    ОтветитьУдалить
  6. Хотелось бы узнать «из первых рук» ответ на пару вопросов:
    1. Есть ли принципиальные ограничения на размер добавляемых файлов? Т.е. начиная с какого размера файла, падение СУВ не будет считаться багом?
    Ну например подлый Hg начинает жаловаться на добавляемые файлы начиная с 10Мб (что полный позор).

    2. Есть ли возможность обьяснить Bazaarу про бинарность файлов (по расширениям) на уровне проекта? Просто в проекте появляются новые файлы, bzr add без аргументов их весело подхватывает, и бинарные файлы ложатся как текстовые, со всеми вытекающими…

    Заранее благодарен за ответ,
    С уважением, Стас Фомин

    ОтветитьУдалить
  7. 2Stas:

    1. Есть ли принципиальные ограничения на размер добавляемых файлов? Т.е. начиная с какого размера файла, падение СУВ не будет считаться багом?
    Ну например подлый Hg начинает жаловаться на добавляемые файлы начиная с 10Мб (что полный позор).

    Hg начинает жаловаться потому что на больших файлах начинает заметно падать производительность работы. И чтобы всякие умники не рассказывали потом о тормознутом Hg, его разработчики и ввели такое предупреждение. В моей практике Меркуриал справлялся с файлами размером 100+ МБ.

    Для Bazaar размер допустимого бинарного файла можно определить так: размер доступного ОЗУ разделить на 4. Будет 2 больших файла -- соответственно в вычислениях используйте суммарный объем. Однако работать с файлами больше пары десятков МБ будет сильно не комфортно.


    2. Есть ли возможность обьяснить Bazaarу про бинарность файлов (по расширениям) на уровне проекта? Просто в проекте появляются новые файлы, bzr add без аргументов их весело подхватывает, и бинарные файлы ложатся как текстовые, со всеми вытекающими…

    Нет, объяснить сегодня ничего нельзя. Что такое: "со всеми вытекающими" -- я не понял. Признак бинарного файла -- наличие байта 0x00 в теле файла. По этому признаку бинарные файлы автодетектируются в тех случаях когда для выполняемой операции это требуется знать.

    ОтветитьУдалить
  8. Спасибо за ответ!

    Для Bazaar размер допустимого бинарного файла можно определить так: размер доступного ОЗУ разделить на 4. А текстового? Условно машина с 3GB ОЗУ и попытка добавить один текстовый 250Мб файл — падение оправдано?
    И насчет суммы обьемов — непонятно. Получается есть предельные размеры репозитария или одного changesetа?

    Нет, объяснить сегодня ничего нельзя. Что такое: "со всеми вытекающими" -- я не понял.
    Вытекающие — это попытки merge с маркерами конфликта, вместо того, чтобы заметив конфликт из просто не трогать…
    Жаль, что нельзя. Жаль.
    Полно всего, что не имеет 0x00 в теле, но никак не предназначены для слияний.

    ОтветитьУдалить
  9. > А текстового?

    Нет разницы.

    > один текстовый 250Мб файл — падение оправдано?

    Вот у меня 3Гб ОЗУ, я взял и добавил файл в 350Мб и все нормально. Мне кажется, что в данном случае достаточно легко проверить как Bazaar будет работать для вашей задачи. Хотя есть вероятность, что выбран неверный инструмент.

    > Получается есть предельные размеры репозитария или одного changesetа?

    Как известно, у всего есть предельные размеры, но Bazaar не накладывает на это жестких ограничений.

    ОтветитьУдалить
  10. 2Stas:

    > А текстового? Условно машина с 3GB ОЗУ и попытка добавить один текстовый 250Мб файл — падение оправдано?

    Если Питон 32х битный, то он по определению не сможет использовать больше 2ГБ памяти (по крайней мере на Windows). Если падает на 250МБ, то значит что реально процессу было выделено около 1ГБ памяти. Либо были еще большие файлы, которые съели остальную память.

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

    > И насчет суммы обьемов — непонятно. Получается есть предельные размеры репозитария или одного changesetа?

    Речь о сумме размеров измененных файлов, которые учавствуют в операции: по сути это размер для определения diff. Эта операция используется при diff и commit. При воссоздании файлов (branch, pull, merge) используются другие алгоритмы.

    Т.е. говоря вашими терминами -- changeset. Но в Bazaar этот термин практически не используется. Это термин из svn/hg.

    > Вытекающие — это попытки merge с маркерами конфликта, вместо того, чтобы заметив конфликт из просто не трогать…

    Кроме маркеров конфликта еще создаются файлы BASE THIS OTHER. Никто не мешает использовать их для получения требуемого результата. Я не вижу проблемы с макреками конфликта, если честно.

    Гораздо хуже когда конфликт не возникает там, где должен быть.

    ОтветитьУдалить
  11. Падение не оправдано, и над уменьшением потребления памяти работает один из команды главных разработчиков. Но пока порадовать ничем не смогу.
    Ну то, что над этим работает главный разработчик, меня уже радует, спасибо.

    Т.е. говоря вашими терминами -- changeset.
    Сорри, я действительно не изучил еще документацию, думал, что терминология во всех DVCS одинаковая.

    Кроме маркеров конфликта еще создаются файлы BASE THIS OTHER. … Я не вижу проблемы с макреками конфликта, если честно.
    Для бинарных файлов (у меня их тысячи, некая распределенная база на питоновских picklах) я ожидал поведения — видишь конфликт, не трогай сам файл, положи версии сбоку (т.е. старый файл, лучше сломанного маркерами конфликта).

    Еще раз спасибо за ответы!

    ОтветитьУдалить
  12. Мне кажется, что в данном случае достаточно легко проверить как Bazaar будет работать для вашей задачи. Хотя есть вероятность, что выбран неверный инструмент.
    Ну в целом да, я интересуюсь ограничениями по ресурсам, ибо есть мысли применять DVCS в несколько нехарактерных областях.…
    Спасибо за проделанный эксперимент!

    ОтветитьУдалить