Как правильно закрыть ветку объектов в Mercurial?

240

Я закончил работу над веткой функций feature-x. Я хочу объединить результаты обратно в defaultветку и закрыть feature-x, чтобы избавиться от нее в выводе hg branches.

Я придумал следующий сценарий, но у него есть некоторые проблемы:

$ hg up default
$ hg merge feature-x
$ hg ci -m merge
$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch

Таким образом, feature-xветвь (changets 40- 41) закрыта, но есть один новый заголовок 44, changeset закрывающей ветки , который будет перечисляться hg headsкаждый раз:

$ hg log ...
o  44 Closed branch feature-x
|
| @  43 merge
|/|
| o  42 Changeset C
| |
o |  41 Changeset 2
| |
o |  40 Changeset 1
|/
o  39 Changeset B
|
o  38 Changeset A
|

Обновление : Похоже, что начиная с версии 1.5 Mercurial больше не показывает заголовки закрытых ветвей в выводе hg heads.

Можно ли закрыть объединенную ветку, не оставив еще одной головы? Есть ли более правильный способ закрыть ветку объектов?

Смежные вопросы:

Андрей Власовских
источник
@Andrey: но указанная статья НЕ только говорит о "--close-branch". Здесь показаны четыре способа обрезки вашей ветки. Если вы действительно не хотите этого больше, вы можете клонировать, как описано в статье. Единственная «проблема» в том, что если по какой-то причине вы хотите закрыть ее, сохраните ее.
СинтаксисT3rr0r
1
@WizardOfOdds Да, я прочитал всю статью об обрезке мертвых веток. Я хочу, чтобы ветка оставалась в истории ревизий, а не выбрасывала ее. Ранее я просто объединял ветки объектов, defaultне закрывая их. Это привело к 0 новым головам, но такие ветви были видны hg branchesнавсегда (как неактивные ветви).
Андрей Власовских
Для разработки функций я склонен клонировать весь репозиторий, а затем объединить его, как только функция будет завершена. Я не люблю иметь остатки (закрытых) ветвей в истории.
DanMan

Ответы:

218

Один из способов - просто оставить объединенные ветки объектов открытыми (и неактивными):

$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
feature-x  41:...
    (2 branches)

$ hg branches -a
default    43:...
    (1 branch)

Другой способ - закрыть ветку объектов перед слиянием, используя дополнительный коммит:

$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch
$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
    (1 branch)

Первый проще, но оставляет открытую ветвь. Второй не оставляет открытых голов / веток, но требует еще одного вспомогательного коммита. Можно использовать последний фактический коммит в ветви функции с использованием этого дополнительного коммита --close-branch, но нужно заранее знать, какой коммит будет последним.

Обновление : Так как Mercurial 1.5 вы можете закрыть филиал в любое время , поэтому он не будет отображаться в обоих hg branchesи hg headsбольше. Единственное, что может вас раздражать, это то, что технически граф ревизий будет иметь еще одну ревизию без детей.

Обновление 2 : Начиная с Mercurial 1.8 закладки стали основной особенностью Mercurial. Закладки более удобны для ветвления, чем именованные. Смотрите также этот вопрос:

Андрей Власовских
источник
2
Это не обязательно так Bookmarks are more convenient for branching than named branches. Hg закладки - это не то же самое, что ветки Git. Они полны многих крайних случаев, которые делают их непригодными в качестве ответвлений. Например: когда вы клонируете репозиторий, вы получите последний коммит в defaultветке. Если вы используете закладки, этот набор изменений соответствует случайной (нестабильной) закладке. Если вы используете именованные ветви, вы получите последний коммит в стабильной / стандартной ветке, что обычно и является тем, что вам нужно. Закладки попадут туда однажды, но их пока нет.
Гили
Я использую закладки как личные теги, которые видны только в моем локальном хранилище. Они действуют как напоминание о наборе изменений, которые мне нужно посетить.
Гили
Я пытался следовать этому подходу, но я все еще получаю ошибку при попытке нажатия: abort: push creates new remote branches:. Что я мог сделать не так?
Касперд
79

imho есть два случая для веток, которые забыли закрыть

Случай 1: ветвь не была объединена с дефолтом

в этом случае я обновляюсь до ветви и делаю еще один коммит с --close-branch, к сожалению, он выбирает ветку, чтобы стать новым наконечником, и, следовательно, перед тем, как отправить его в другие клоны, я проверяю, что реальный совет получает еще некоторые изменения и другие не запутайся насчет этого странного совета.

hg up myBranch
hg commit --close-branch

Случай 2: ветвь была объединена по умолчанию

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

в этом случае я обновляюсь до набора изменений ветви, делаю еще один коммит с --close-branch и объединяю новый набор изменений, который стал подсказкой по умолчанию. последняя операция создает новый совет в ветке по умолчанию - HOORAY!

hg up myBranch
hg commit --close-branch
hg up default
hg merge myBranch

Надеюсь, это поможет будущим читателям.

Нахбарс Лумпи
источник
3
Хороший четкий ответ для новичка Mercurial, как я. И спасибо за то, что вы не используете "ci", который не указан в качестве одной из команд hg help, поэтому я не знаю, что это значит :)
МБ.
8
@MB .: в таких случаях, hg help ciобъясню вам.
Крис Морган
Я верю, что, как скажет команда 'hg merge', в конце еще один коммит
Chip
11

РЕДАКТИРОВАТЬ ой, слишком поздно ... Я знаю, что прочитал ваш комментарий, в котором говорится, что вы хотите сохранить ревизию Feature-X, так что подход клонирования здесь не работает.

Я все еще позволю ответ здесь, поскольку это может помочь другим.

Если вы хотите полностью избавиться от «функции X», потому что, например, она не работает, вы можете клонировать. Это один из методов, описанных в статье, и он работает, и он говорит конкретно о руководителях.

Насколько я понимаю, у вас есть это и вы хотите избавиться от головы "feature-x" раз и навсегда:

@    changeset:   7:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| | o  changeset:   5:013a3e954cfd
| |/   summary:     Closed branch feature-x
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Итак, вы делаете это:

hg clone . ../cleanedrepo --rev 7

И у вас будет следующее, и вы увидите, что feature-x действительно отсутствует:

@    changeset:   5:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Возможно, я неправильно понял, что вы хотели, но, пожалуйста, не выключайте мод, я потратил время на воспроизведение вашего варианта использования:)

SyntaxT3rr0r
источник
7

Странно, что никто еще не предложил самый надежный способ закрытия ветвей объектов ... Вы можете просто объединить коммит слияния с флагом --close-branch (т.е. зафиксировать измененные файлы и закрыть ветку одновременно):

hg up feature-x
hg merge default
hg ci -m "Merge feature-x and close branch" --close-branch
hg branch default -f

Так что это все. Ни одной лишней головы на ревграфе. Никакой дополнительной фиксации.

тав
источник
Я упомянул об этом в своем ответе: "" "Последний фактический коммит в ветви функции можно объединить с этим дополнительным коммитом, используя --close-branch, но нужно заранее знать, какой коммит будет последним." " "
Андрей Власовских
Да я вижу. Я просто не совсем понимаю последнюю часть предложения («но надо знать ...»), поэтому я подумал, что это означает что-то другое. Также я хотел бы отметить, что этот метод не поддерживается большинством инструментов GUI (TortoiseHG, SourceTree и т. Д.).
Тав
@AndreyVlasovskikh Смысл этого ответа - закрыть ветку в слиянии, а не в последнем коммите ветви функции.
Касперд
@tav Перед выполнением mergeкоманды может быть полезно использовать ее, hg branchчтобы убедиться, что имя ветви слияния является тем, которое вы хотите оставить открытым.
Касперд
2
При ближайшем рассмотрении кажется, что слияние всегда будет на закрытой ветви. Желаемым результатом будет то, что находится на ветке одного из его родителей и закрывает ветку другого его родителя. Кажется, это невозможно. Так что это не похоже на работоспособное решение в конце концов. Жаль, я действительно хотел использовать слияние в качестве точки закрытия ветки.
Касперд