суббота, 20 марта 2010 г.
Джоел и Subversion, Mercurial, Git. Действительно антибиотик?
воскресенье, 31 января 2010 г.
Введение в Mercurial. Часть 4. Способы организации ветвей
Здравствуйте, уважаемые читатели. Я продолжаю свою серию постов про распределенную систему контроля версий Mercurial. В этой статье мы подробно поговорим об основных приемах организации ветвлений в Mercurial. В предыдущей статье мы рассмотрели "спонтанное" ветвление, возникающее в случае наличия в репозитории разных линий ревизий от разных разработчиков, хотя каждый из них работает в основной ветви разработки, в этой статье мы рассмотрим работу с ветвлениями, вызванную осознанной необходимостью разделения линий разработки. Также в этой статье я буду указывать какие преимущества и недостатки имеются у обсуждаемых способов организации ветвей. Указанные преимущества и недостатки являются моим личным мнением, и вполне могут не совпадать с вашим.
Для начала дадим определения ветви, чтобы начинать с единого понимания процесса. Обратившись к wiki меркуриала я нашел определение, которое мне кажется вполне корректным: ветвь (branch) - это связанная последовательность ревизий (changeset) являющаяся отдельным направлением разработки. Таким образом, ветвь - это в первую очередь логическое понятие, так как в случае с распределенными системами контроля версий она будет содержать значительное число "спонтанных" ветвлений-слияний.
Рисунок 1. Исходное состояние репозитория
Рисунок 2. Новая анонимная ветвь в репозитории
В этой статье продолжим работу над нашим примером. На рисунке показано состояние нашего репозитория после операций с ним в предыдущих частях цикла. И хотя формально в репозитории уже имеется одно ветвление, Mercurial нам говорит что ветвь одна:
$ hg branches default 4:6d6c634e2e20
Команда hg branches выводит список всех именованных ветвей в репозитории. Как мы видим основная ветвь разработки называется default. Если быть точным, так называется ветвь в которую происходит первый коммит в репозиторий, так сказать название по умолчанию. На рисунке 1 приведено текущее состояние репозитория и граф ревизий в нем находящихся. Я буду красным кружком отмечать "вершину" (tip) репозитория, как сказано в документации Mecurial, вершина - это самая свежая ревизия в репозитории. Команда hg branches не выводит анонимные ветви, хотя разработчики могут их использовать при необходимости, и создавать самостоятельно.
Анонимное ветвление
На самом деле, создание ветви при работе с Mercurial не является чем-то из ряда вон выходящим, для распределенной модели контроля версий это стандартная операция, и поэтому может быть произведена крайне просто, фактически, простым коммитом. То есть мы должны привести рабочую копию в состояние отличное от "вершины" (tip), внести изменения и выполнить коммит. Ничего больше. Для этого локальную копию исходного кода вернем в состояние ревизии 2:66c5686e355e:
$ hg update -r 66c5 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ ls -l -rw-r--r-- 1 mike mike 22 2010-01-07 22:22 first.txt -rw-r--r-- 1 mike mike 61 2009-11-27 11:15 other.txt -rw-r--r-- 1 mike mike 57 2009-11-27 00:03 readme.txt
После этого создадим в локальной копии файл branch.txt, добавим его в репозиторий и выполним коммит:
$ ls -l -rw-r--r-- 1 mike mike 61 2010-01-31 18:55 branch.txt -rw-r--r-- 1 mike mike 22 2010-01-07 22:22 first.txt -rw-r--r-- 1 mike mike 61 2009-11-27 11:15 other.txt -rw-r--r-- 1 mike mike 57 2009-11-27 00:03 readme.txt $ hg add adding branch.txt $ hg commit created new head $ hg branches default 5:ff8ffd5270cb
И Mercurial нам честно сообщает что создал новую "голову". На рисунке 2 показано текущее состояние репозитория. Отмечу два момента: во-первых, ветвь default осталась на своем месте, и теперь заканчивается ревизией 5:ff8ffd5270cb, то есть "вершиной" (tip); а во-вторых все эти ветвления находятся локально в нашем репозитории. Локальность производимых ветвлений - это главное, коренное, отличие от централизованных систем контроля версий, в том числе от Subversion. Никто не увидит вашей ветви до тех пор пока вы не синхронизируете свой репозиторий с удаленным (обычно командой push). С другой стороны выполнение pull приведет к появлению в вашем репозитории всех ветвей, имеющихся в удаленном.
Преимущества
Основным преимуществом этого способа является крайняя простота. Не нужно ничего придумывать, выполнять сложных операций, оповещать других участников команды - просто апдейт и коммит.
Недостатки
Недостатки вытекают из анонимности ветви. Фактически, понять, что у вас есть ветвь разработки, исходя из вывода стандартных операций Mercurial, затруднительно. Особенно после 2-3 месяцев активной работы с репозиторием, когда количество таких мелких ветвлений приближается к сотне. Соответственно вам придется писать информативные подписи к коммитам, если анонимные ветви предполагается использовать в дальнейшем. Для переключения между ветвями разработки вам придется использовать номер ревизии, который, как известно, простой хэш - очень удобен для машины, но крайне неудобен для человека.
Таким образом, анонимные ветви - это отличный механизм для внесения быстрых (по количеству ревизий) исправлений, логически сильно связанных с направлением основной ветви разработки, то есть для организации ветвления на 2-3 ревизии с последующим слиянием с основной ветвью. Для организации больших ветвей, логически необходимых для разделения направлений разработки следует использовать именованные ветви.
Именованное ветвление
Рисунок 3. Именованные ветви в репозитории
Вполне естественно, что в Mercurial предусмотрен способ создания ветвей разработки с некоторыми именами, задаваемыми пользователем. Для организации подобных ветвлений предназначена команда hg branch. С помощью этой команды версия, находящаяся в локальной копии помечается ветвью с новым именем, при этом сама ветвь будет создана только после того, как вы выполните коммит. Попробуем сейчас сделать именованную ветвь, родительской ревизией для которой будет ff8f:
$ hg branch new_feature marked working directory as branch new_feature $ hg commit $ hg branches new_feature 6:4d530267d302 default 5:ff8ffd5270cb
Итак мы видим, что Mercurial уже знает про две именованные ветви, "вершинами" для которых являются ревизии ff8f и 4d53, хотя на графе ревизий это одна ветвь. На рисунке 3 я показал, что именно понимается под именованной ветвью в Mercurial, при этом, фактически, для каждой ветви есть своя "вершина" (tip), хотя hg log это не показывает (я приведу только смысловой отрывок):
$ hg log changeset: 6:4d530267d302 branch: new_feature tag: tip user: mike@mike-vbox date: Sun Jan 31 21:31:07 2010 +0300 summary: Создаие именованной ветви в репозитории changeset: 5:ff8ffd5270cb parent: 2:66c5686e355e user: mike@mike-vbox date: Sun Jan 31 18:56:23 2010 +0300 summary: Создание анонимной ветви changeset: 4:6d6c634e2e20 parent: 3:6872fa960507 parent: 2:66c5686e355e user: mike@mike-vbox date: Sun Jan 10 20:34:21 2010 +0300 summary: Выполнен мерж двух веток changeset: 3:6872fa960507 parent: 1:270e49e72f4b user: mike@mike-vbox date: Sun Jan 10 19:40:45 2010 +0300 summary: Файл second.txt создан во втором репозитории
Убедиться в том, что "вершины" все таки существуют можно с помощью hg update, то есть переключившись на другую ветвь:
$ hg update default 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg ident ff8ffd5270cb
А затем переключится обратно:
$ hg update new_feature 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg ident 4d530267d302 (new_feature) tip
При этом в нашем репозитории сложилась интересная ситуация. tip ветви default не совпадает с "головой" (head) этой же ветви. В этом легко убедиться попросив Mercurial сказать какие же "головы" в нашем репозитории:
$ hg heads changeset: 6:4d530267d302 branch: new_feature tag: tip user: mike@mike-vbox date: Sun Jan 31 21:31:07 2010 +0300 summary: Создаие именованной ветви в репозитории changeset: 4:6d6c634e2e20 parent: 3:6872fa960507 parent: 2:66c5686e355e user: mike@mike-vbox date: Sun Jan 10 20:34:21 2010 +0300 summary: Выполнен мерж двух веток
Отмечу лишь один очень важный факт - ветвление произведено в вашем локальном репозитории, и вы можете работать с ним так, как вам угодно, при этом вы не боитесь поломать чужой код своим коммитом, или вызвать у тимлида приступ головной боли своими ветвлениями. Вот именно так концепция распределенной системы контроля версий позволяет решить стандартные болячки централизованных систем.
Преимущества
Итак именованное ветвление лишь немногим сложнее анонимного, однако позволяет организовать работу над сложным проектом с несколькими направлениями разработки наиболее эффективным образом. Имя ветви является метаданными каждой ревизии, что позволяет корректно отслеживать изменения, произошедшие в проекте. Хотя принципиальных отличий от анонимных ветвей, на самом деле, нет.
Недостатки
К недостаткам, в некоторой степени, можно отнести синдром разрастания ветвей. То есть, если вы будете использовать именованные ветви при каждой необходимости отпочковаться от основной, вывод команды hg branches будет просто гиганским через некоторое время. Хотя ветви можно закрывать при коммитах (опция --close-branch), не стоит делать именованные ветви там где они не нужны.
Ветвление в клонах репозитория
Последний способ организации ветвления о котором я расскажу - ветвление в клонах. На самом деле способ очевиден, и вытекает из третьей части этого цикла. Ничто не мешает пользователю лично создать клон репозитория и в нем вести отдельную ветвь разработки. Таким образом, для каждой ветви потребуется отдельный репозиторий. Безусловно модель распределенной системы контроля версий Mercurial позволяет подобную трактовку ветвления разработки, однако рассмотрим аспекты подобного подхода:
Преимущества
Немного более безопаснее чем при других способах. На самом деле в данном случае способ выстрелить себе в ногу только один - запушить что нибудь этакое в удаленный репозиторий, тогда как при локальном ветвлении способов выстрелить себе в ногу немного больше.
Недостатки
На мой взгляд недостатки перевешивают все преимущества. Самый главный недостаток - при каждом клонировании вам придется вытягивать весь репозиторий, то есть, если вам захотелось получить доступ к некоторой ветви вам придется вытянуть весь репозиторий относящийся к этой ветви, и так для каждой. Второй недостаток - бекапить вам придется не один репозиторий, а несколько. Что не логично.
На этом я заканчиваю рассматривать ветвления в Mercurial. Думаю следующая статья будет посвящена способам слияния ветвей, а также сложным моментам при слиянии, при упоминании которых у пользователей Subversion резко падает давление и начинают трястись руки. :)
Уважаемые читатели. Просьба комментировать посты. Возможно я упустил какие-то моменты, требующие разъяснения, о которых стоило бы написать.
воскресенье, 10 января 2010 г.
Введение в Mercurial. Часть 3. Начинаем ветвиться и сливаться
Продолжаю писать про систему контроля версий Mercurial. В этой части начну речь про сложные операции с репозиториями, а именно - создание ветвей и работа с ними. Работа с ветвями разработки пользователям Subversion доставляет немало головной боли, поэтому многие из них, когда видят во всех статьях про Mercurial, что им чуть ли не каждый день придется мержить (merge) ветки сильно пугаются, и теряют всякое желаение переходить на него. Однако я постараюсь переубедить всех недоброжелателей и консерваторов, поскольку в Mercurial работа с ветвлениями является не намного более сложной операцией чем коммит.
Перед тем как продолжить разбираться с Mercurial поздравляю всех своих читателей с наступившим новым годом, желаю всяческих успехов в различных аспектах жизни, гармонии и добра во внутреннем мире, а также постоянного интеллектуального и духовного роста! С новым годом, уважаемые!
Итак, мы уже разбирали основы работы с репозиториями Mercurial в предыдущей части, и у нас сформировалось 2 готовых репозитория, сегодня мы продолжим взаимодействовать с ними и разберем, как организовать ветвление, и как потом с ним "бороться". В этой части мы рассмотрим самое частое ветвление в Mercurual, которое можно даже назвать "спонтанным".
Первым ветвлением, с которым столкнется команда работающаяя с Mercurial - это ветвление при пулле новых изменений. Ситуация возникает когда в вашем локальном репозитории имеются закоммиченные но не запушенные изменения, и один (а то и несколько) ваших соратников закоммитили и запушили в "центральный" репозиторий свои изменения. Попробуем смоделировать ситуацию на имеющихся у нас трех репозиториях, с которыми мы начинали работать во второй части. Напомню читателям, что у нас в обоих репозиториях сохранено по две ревизии, при этом оба репозитория были синхронизированы с "центральным". Попробуем внести в репозитории различные изменения и посмотреть что из этого выйдет.
Для начала создадим файл first.txt в первом репозитории, закоммитим его и запушим:
$ echo "new text to first.txt" > first.txt $ hg status ? first.txt $ hg add first.txt $ hg commit $ hg outgoing comparing with /home/mike/Repositories/newProject searching for changes changeset: 2:66c5686e355e tag: tip user: mike@mike-vbox date: Thu Jan 07 22:28:39 2010 +0300 summary: Коммит файла first.txt в первом репозитории $ hg push pushing to /home/mike/Repositories/newProject searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files
А теперь сэмулируем ситуацию, когда наш товарищ также внес изменения, отличающиеся от наших, и посмотрим как такая ситуация разруливается средствами Mercurial, ведь подобная ситуация в случае командной разработки будет достаточно частой. Для этого переместимся в имеющийся у нас второй репозиторий, создадим в нем новый файл, и посмотрим что будет:
$ echo "file created in second repository" > second.txt $ hg status ? second.txt $ hg add adding second.txt $ hg commit $ hg log changeset: 2:6872fa960507 tag: tip user: mike@mike-vbox date: Sun Jan 10 19:40:45 2010 +0300 summary: Файл second.txt создан во втором репозитории changeset: 1:270e49e72f4b user: mike@mike-notebook date: Fri Nov 27 10:39:35 2009 +0300 summary: Записан файл other.txt в другом репозитории changeset: 0:8fae369766e9 user: mike@mike-notebook date: Fri Nov 27 08:58:01 2009 +0300 summary: Файл readme.txt добавлен в репозиторий
Итак у нас уже имеется ситуация, когда в локалном репозитории и в удаленном отличаются "головы" разработки, то есть существуют две различные ревизии, производные от одной. В терминах любой системы контроля версий - это ветвление, пусть пока неявное, но скоро все тайное станет явным. Попробуем запушить имеющиеся ревизии в "центральный" репозиторий:
$ hg outgoing comparing with /home/mike/Repositories/newProject searching for changes changeset: 2:6872fa960507 tag: tip user: mike@mike-vbox date: Sun Jan 10 19:40:45 2010 +0300 summary: Файл second.txt создан во втором репозитории $ hg push pushing to /home/mike/Repositories/newProject searching for changes abort: push creates new remote heads! (did you forget to merge? use push -f to force)
Итак Mercurial нам запрещает пушить, говорит что пуш приведет к созданию новой головы в удаленном репозитории. И предлагает смержить репозитории. Ну чтож давайте это сделаем:
$ hg incoming comparing with /home/mike/Repositories/newProject searching for changes changeset: 2:66c5686e355e tag: tip user: mike@mike-vbox date: Thu Jan 07 22:28:39 2010 +0300 summary: Коммит файла first.txt в первом репозитории $ hg pull pulling from /home/mike/Repositories/newProject searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge)
Мы вытянули с "центрального" репозитория все имеющиеся изменения, и Mercuial нам сообщает, что в локальном репозитории теперь две "головы" которые требуют слияния (мержа от английского to merge). Можно даже попросить Mercurial показать некоторую картинку (используется дополнение graphlog о котором я ещё не писал, расширение есть в стандартной поставке):
$ hg glog o changeset: 3:66c5686e355e | tag: tip | parent: 1:270e49e72f4b | user: mike@mike-vbox | date: Thu Jan 07 22:28:39 2010 +0300 | summary: Коммит файла first.txt в первом репозитории | | @ changeset: 2:6872fa960507 |/ user: mike@mike-vbox | date: Sun Jan 10 19:40:45 2010 +0300 | summary: Файл second.txt создан во втором репозитории | o changeset: 1:270e49e72f4b | user: mike@mike-notebook | date: Fri Nov 27 10:39:35 2009 +0300 | summary: Записан файл other.txt в другом репозитории | o changeset: 0:8fae369766e9 user: mike@mike-notebook date: Fri Nov 27 08:58:01 2009 +0300 summary: Файл readme.txt добавлен в репозиторий
Наличие двух "голов" очевидно, и что-то с этим надо делать. Поскольку мы пока не планировали целенаправленно создавать две ветви разработки. Поэтому выполним слияние имеющихся ветвей:
$ hg merge 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ ls first.txt other.txt readme.txt second.txt
Итак, Mercurial, после нашей команды "hg merge" смержил рабочую копию и репозиторий, и напоминает нам, что эти изменения следовало бы закоммитить. Так сделаем это:
$ hg commit $ hg glog @ changeset: 4:6d6c634e2e20 |\ tag: tip | | parent: 2:6872fa960507 | | parent: 3:66c5686e355e | | user: mike@mike-vbox | | date: Sun Jan 10 20:34:21 2010 +0300 | | summary: Выполнен мерж двух веток | | | o changeset: 3:66c5686e355e | | parent: 1:270e49e72f4b | | user: mike@mike-vbox | | date: Thu Jan 07 22:28:39 2010 +0300 | | summary: Коммит файла first.txt в первом репозитории | | o | changeset: 2:6872fa960507 |/ user: mike@mike-vbox | date: Sun Jan 10 19:40:45 2010 +0300 | summary: Файл second.txt создан во втором репозитории | o changeset: 1:270e49e72f4b | user: mike@mike-notebook | date: Fri Nov 27 10:39:35 2009 +0300 | summary: Записан файл other.txt в другом репозитории | o changeset: 0:8fae369766e9 user: mike@mike-notebook date: Fri Nov 27 08:58:01 2009 +0300 summary: Файл readme.txt добавлен в репозиторий
На картинке которую нам показывает Mercurial неплохо видно что же именно происходило с репозиторием в течение этого, можно сказать урока. Также замечу, что у последней ревизии два "предка", в отличие от остальных. Вообще в Mercrurial у ревизии может быть не более двух предков, что вполне логично, и для меня очевидно. Отправим теперь изменения в "центральный" репозиторий, и посмотрим что же делать теперь с ними первому разработчику.
$ hg push pushing to /home/mike/Repositories/newProject searching for changes adding changesets adding manifests adding file changes added 2 changesets with 1 changes to 1 files
Теперь переместимся в каталог первого разработчика, и получим изменения и из центрального репозитория:
$ hg pull pulling from /home/mike/Repositories/newProject searching for changes adding changesets adding manifests adding file changes added 2 changesets with 1 changes to 2 files (run 'hg update' to get a working copy) $ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg glog @ changeset: 4:6d6c634e2e20 |\ tag: tip | | parent: 3:6872fa960507 | | parent: 2:66c5686e355e | | user: mike@mike-vbox | | date: Sun Jan 10 20:34:21 2010 +0300 | | summary: Выполнен мерж двух веток | | | o changeset: 3:6872fa960507 | | parent: 1:270e49e72f4b | | user: mike@mike-vbox | | date: Sun Jan 10 19:40:45 2010 +0300 | | summary: Файл second.txt создан во втором репозитории | | o | changeset: 2:66c5686e355e |/ user: mike@mike-vbox | date: Thu Jan 07 22:28:39 2010 +0300 | summary: Коммит файла first.txt в первом репозитории | o changeset: 1:270e49e72f4b | user: mike@mike-notebook | date: Fri Nov 27 10:39:35 2009 +0300 | summary: Записан файл other.txt в другом репозитории | o changeset: 0:8fae369766e9 user: mike@mike-notebook date: Fri Nov 27 08:58:01 2009 +0300 summary: Файл readme.txt добавлен в репозиторий
Как видно из вышеприведенного лога, все прошло без различных эксцессов и проблем. Что не может не радовать. И, как и в прошлый раз, мы в трех репозиториях получили идентичную ситуацию, несмотря на несколько более сложную исходную.
А теперь думаю самое главное - зачем же все это надо, ведь в SVN нет подобных проблем, да и мержить там не так часто... Ответ здесь очень простой - подобная модель взаимодействия с репозиторием провоцирует пользователя на частые коммиты, он не боится сломать код или репозиторий неудачным коммитом, не боится помешать другим пользователям и т.д. Коммит в Mercurial локален - пока вы не захотите отправить его в другой репозиторий, вся ветка коммитов останется у вас. К тому же слияние ревизий в Mercurial сделано намного проще и логичнее слияния ревизий в Subversion. Да, в поздних версиях и SVN научился более-менее нормально мержить, однако до Mercurial ему по прежнему далековато. И именно возможность частых локальных коммитов, в том числе когда у вас отстутствует подключение к интернету (а со мной такое случается нередко), меня так привлекла в Mercurial. Все остальные аспекты были на втором плане.
В заключении сделаю одно важное замечание. В случае командной разработки, у Mercurial есть одна особенность (назвать недостатком как-то язык не поворачивается): целочисленная нумерация ревизий может быть различна в различных репозиториях, поэтому не стоит использовать целочисленные номера для идентификации ревизий при общении внутри команды. Поскольку идентифиратором ревизии в Mercurial является SHA1-хеш, вероятность совпадения которого для различных ревизий крайне мала, то стоит использовать именно его. Причем как показывает практика различных пользователей Mercurial - вполне достаточно первых 4х символов этого самого хеша (когда вам перестанет хватать 4х символов - используйте 5 ;) ).
воскресенье, 27 декабря 2009 г.
Введение в Mercurial. Часть внеочередная. Конвертируемся из Subversion
Давненько я ничего не писал, но для того была достойная причина - 22 декабря я все таки защитил кандидатскую, что собственно и забирало уйму времени последние месяцы. Теперь я полноправный к.т.н.
Сегодня маленький пост о том как сконвертировать имеющийся репозиторий Subversion в репозиторий Mercurial. Думаю что в необходимости перехода на Mercurial я постепенно смогу убедить своих читателей. Итак исходная позиция:
1. Имеется репозиторий svn лежащий на диске, пусть здесь: /[svn_repos_path]/svnrepo;
2. Хочется заиметь репозиторий Mercurial /[hg_repos_path/hgrepo со всей историей накопленной в Subversion, фактически импортировать все ревизии из svn в Mercurial.
Нет ничего проще.
1. Создаем новый репозиторий Mercurial:
cd /[hg_repos_path/hgrepo
hg init
2. Разрешаем расширение convert. В Debian это делается так: в файл /[hg_repos_path/hgrepo/.hg/hgrc добавляем строчки:
[extensions]
convert=
3. А теперь выполняем собственно конвертирование:
cd /[hg_repos_path/hgrepo
hg convert file:///[svn_repos_path]/svnrepo .
Все. Mercurial выдает последовательность ревизий, и загоняет все что было в SVN репозитории в новый репозиторий Mercurial. Можно пользоваться ;)
пятница, 27 ноября 2009 г.
Введение в Mercurial. Часть 2. Основы работы
? readme.txt
Mercurial ответил, что он видит файл readme.txt, при этом этот файл пока не находится в системе контроля версий (символ «?» слева от имени файла). По команде status Mercurial выводит состояние рабочей копии в сравнении с состоянием локального репозитория. Для того, чтобы сказать Mercurial, что его необходимо версионировать скажем:
adding readme.txt
A readme.txt
changeset: 0:8fae369766e9
tag: tip
user: mike@mike-notebook
date: Fri Nov 27 08:58:01 2009 +0300
summary: Файл readme.txt добавлен в репозиторий
pushing to ~/repos/hgproject
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating working directory
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
? other.txt
> hg add
adding other.txt
> hg commit
> hg log
changeset: 1:270e49e72f4b
tag: tip
user: mike@mike-notebook
date: Fri Nov 27 10:39:35 2009 +0300
summary: Записан файл other.txt в другом репозитории
changeset: 0:8fae369766e9
user: mike@mike-notebook
date: Fri Nov 27 08:58:01 2009 +0300
summary: Файл readme.txt добавлен в репозиторий
comparing with ~/repos/hgproject
searching for changes
changeset: 1:270e49e72f4b
tag: tip
user: mike@mike-notebook
date: Fri Nov 27 10:39:35 2009 +0300
summary: Записан файл other.txt в другом репозитории
pushing to ~/repos/hgproject
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
comparing with ~/repos/hgproject
searching for changes
changeset: 1:270e49e72f4b
tag: tip
user: mike@mike-notebook
date: Fri Nov 27 10:39:35 2009 +0300
summary: Записан файл other.txt в другом репозитории
pulling from ~/repos/hgproject
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved