Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
hgbook.pdf
Скачиваний:
50
Добавлен:
17.03.2015
Размер:
3.15 Mб
Скачать

Управление релизами и ветками

summary:

Added tag v1.1 for changeset 36034fbfb874

 

 

8.1.1. Обработка конфликтов слияния тегов

Вы не должны особо заботиться о файле .hgtags, но иногда он дает о себе знать при слиянии изменений. Формат файла очень прост: он состоит из строк. Каждая строка начинается с хеша набора изменений, за который через пробел следует имя тега.

Если вы исправляете конфликт в файле .hgtags, есть одно замечание про его модификацию: когда Mercurial читает теги в репозитории, он никогда не читает рабочую копию файла .hgtags. Вместо этого он читает наиболее старшую ревизию этого файла.

Неудачное последствие такого дизайна состоит в том, что вы не можете проверить правильность вашего файла

.hgtags после слияния до тех пор, пока вы не закомитите изменения. Таким образом, если вы решаете конфликт

в.hgtags во время слияния убедитесь что вы запустили hg tags после слияния. Если эта команда найдет ошибку

вфайле .hgtags, она сообщит о месте ее возникновения. Эта информация поможет вам в исправлении ошибки и повторном комите. Вы должны запустить hg tags вновь, как только будете уверены в правильности файла.

8.1.2. Теги и клонирование

Возможно вы обратили внимание, что команда hg clone имеет опцию -r, которая позволяет клонировать точную копию репозитория как частичные наборы изменений. Новый клон не будет содержать истории проекта, которая появилась позже указанной вами ревизии. Это относится и к тегам, что может стать неожиданностью для неосторожных.

Вспомните что тег сохранен как ревизия в файле .hgtags, так что когда вы создаете тег, набору изменений в котором он записан нужно обратиться к старшему набору изменений. Когда вы запускаете команду hg clone -r foo для клонирования репозитория по имени тега foo, новый клон не будет содержать истории создания клона. Результатом этого станет то, что вы получите полное подмножество истории проекта в новом репозитории, а не тег, который вы, возможно, ожидали.

8.1.3. Когда тегов становится слишком много

Итак, так как теги в Mercurial подвержены версионности и связаны с историей проекта, любой кто работает с ними может видеть созданые вами теги. Именованая ревизия 4237e45506ee будет доступна по простому тегу v2.0.2. Если же вы пытаетесь отыскать сложноуловимую ошибку, вы возможно захотите чтобы тег напоминал вам нечто вроде «Анна видела признаки ошибки в этой ревизии» (речь тут идет о «пометках на полях для себя», прим. переводчика).

Для подобных целей вы можете захотеть использовать локальные теги. Вы можете создать локальный тег используя опцию -l команды hg tag. Это позволит записать тег в файл .hg/localtags, вместо .hgtags. Версия файла .hg/localtags не отслеживается. Любые теги созданые с опцией -l остаются локальными для вашего репозитория.

8.2. Поток изменений — «большая картинка» против «маленькой»

Вернёмся к схеме, которую я нарисовал в начале главы и в то же время подумаем о проекте как о множественных конкурирующих кусках работы под разработкой.

Это может быть толчком для нового «основного» релиза; нового «небольшого» релиза с исправленными багами для последнего «основного» релиза; и неожиданного «горячего» изменения для старого релиза, который сейчас ещё поддерживается.

Обычно люди называют разные конкурирующие направления «ветками». Однако мы уже видели несколько раз, что Mercurial обрабатывает всю историю как серию «веток» и «слияний». На самом дела у нас есть 2 идеи, которые плохо связаны, но имеют одинаковые названия.

83

Управление релизами и ветками

«Большие картинки» веток представляют собой вариацию проекта; люди дают им имена и говорят о них.

«Маленькие картинки» веток являются артефактами каждодневной разработки и слияния изменений. Они показывают, как код разрабатывался.

8.3. Управление ветками «больших картинок» в репозитории (хранилище)

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

$ cd myproject $ hg tag v1.0

Затем вы можете клонировать новое хранилище проекта в myproject-1.0.1.

$ cd ..

$ hg clone myproject myproject-1.0.1 updating to branch default

2 files updated, 0 files merged, 0 files removed, 0 files unresolved

После этого, если кому-то будет нужно работать для устранения багов к предстоящему 1.0.1 релизу, то можно клонировать хранилище myproject-1.0.1, сделать нужные изменения и вернуть их обратно.

$ hg clone myproject-1.0.1 my-1.0.1-bugfix updating to branch default

2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-1.0.1-bugfix

$ echo 'I fixed a bug using only echo!' >> myfile $ hg commit -m 'Important fix for 1.0.1'

$ hg push

pushing to /tmp/branch-repookUgeL/myproject-1.0.1 searching for changes

adding changesets adding manifests adding file changes

added 1 changesets with 1 changes to 1 files

Тем временем разработчики следующего «большого» релиза могут продолжать работать, изолированные в хранилище myproject.

$ cd ..

$ hg clone myproject my-feature updating to branch default

2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd my-feature

$ echo 'This sure is an exciting new feature!' > mynewfile $ hg commit -A -m 'New feature'

adding mynewfile $ hg push

pushing to /tmp/branch-repookUgeL/myproject searching for changes

adding changesets adding manifests adding file changes

added 1 changesets with 1 changes to 1 files

8.4. Не повторяйте сами себя: слияния между «ветками»

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

84

Управление релизами и ветками

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

В простейшнм случае всё, что вам нужно сделать — это извлечь изменения с «основной» ветки в вашу локальную копию этой ветки.

$ cd ..

$ hg clone myproject myproject-merge updating to branch default

3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd myproject-merge

$ hg pull ../myproject-1.0.1 pulling from ../myproject-1.0.1 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)

Затем вам нужно соединить заголовки 2-х веток и вернуться к «основной» ветке.

$ hg merge

1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit)

$ hg commit -m 'Merge bugfix from 1.0.1 branch' $ hg push

pushing to /tmp/branch-repookUgeL/myproject searching for changes

adding changesets adding manifests adding file changes

added 2 changesets with 1 changes to 1 files

8.5. Наименование веток в одном репозитории(хранилище)

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

Если вы (как и ваши коллеги) «продвинутый пользователь», то вы можете рассматривать другой способ трактовки веток. Я уже упоминал разницу человеческого уровня между «маленькой картинкой» и «большой картинкой» веток. Пока Mercurial всё время работает с несколькими «маленькими картинками» в хранилище (например, когда вы отослали изменения, но ещё не соединили), Mercurial также может работать с несколькими ветками «больших картинок».

Ключ к работе в этом направлении в том, что Mercurial позволяет вам дать постоянное имя ветке. И всегда существует ветка, названная default (по-умолчанию). Даже перед тем, как вы переименуете ветку сами, вы можете найти историю ветки default, если поищите.

И как пример, когда вы запускаете команду hg commit, и вы попадаете в редактор, где вы можете ввести commit, посмотрите на верхнюю линию, которая содержит текст «HG: branch default». Это говорит вам о том, что ваш commit случится с веткой, названной default.

Чтобы начать работу с именованными ветками используйте команду hg branches. Эта команда покажет вам список именованных веток, которые есть в хранилище, расскажет, какая ветка есть изменение другой.

$ hg tip

 

changeset:

0:f9dffe1ca22e

tag:

tip

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:29 2012 +0000

85

 

 

Управление релизами и ветками

 

 

 

 

 

 

summary:

Initial commit

 

 

 

 

$ hg branches

 

 

 

default

0:f9dffe1ca22e

 

 

 

 

 

Пока вы не создали ни одной именованной ветки, существует только одна, названная default.

 

Найти, какая «текущая» ветка сейчас, запустите команду hg branch без аргументов. Вы узнаете, какая ветка является «родительской» для «текущей».

$ hg branch default

Чтобы создать новую ветку запустите команду hg branch снова. В этот раз с аргументом: именем ветки, которую вы создаёте.

$ hg branch foo

marked working directory as branch foo $ hg branch

foo

После создания новой ветки вы спросите, что сделала команда hg branch? Что показывают команды hg status и hg tip?

$ hg status

 

$ hg tip

 

changeset:

0:f9dffe1ca22e

tag:

tip

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:29 2012 +0000

summary:

Initial commit

 

 

Ничего не изменилось в рабочей папке и не было создано новой истории. Запуск команды hg branch не производит постоянного эффекта; она только говорит Mercurial, ветку с каким именем использовать для последующих фиксаций изменений (commit).

Когда вы подтверждаете изменения, Mercurial записывает имя ветки, которую вы изменяете. Один раз переключив ветку default на другую и подтвердив, вы увидите имя новой ветки в результатах hg log, hg tip, и других комманд, которые показывают эту информацию.

$ echo 'hello again' >> myfile $ hg commit -m 'Second commit'

$ hg tip

 

changeset:

1:5dc3c3ccfa6d

branch:

foo

tag:

tip

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:29 2012 +0000

summary:

Second commit

Команды как hg log напечатают имя ветки для каждого изменения, которое не в ветке default. Как результат, если вы никогда не именовали ветки — вы никогда не увидите эту информацию.

Один раз дав имя ветке и подтвердив изменение с этим именем каждое последующее изменение будет иметь то же имя ветки. Вы можете сменить имя ветки в любое время, используя команду hg branch.

$ hg branch foo

$ hg branch bar

marked working directory as branch bar $ echo new file > newfile

$ hg commit -A -m 'Third commit' adding newfile

$ hg tip

changeset: 2:1536e3edee0d branch: bar

tag: tip

86

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]