2013-11-11 2 views
2

У нас есть три основных выпуска в год, с ответными ветвями: например. 2013A, 2013B и 2013C. Когда мы создаем каждую ветвь, она запускается из значения по умолчанию. Изменения в каждой ветви должны быть объединены только вперед, т.е. 2013A -> 2013B -> 2013C -> по умолчанию. У нас есть нажимной крючок на сервере, который проверяет, находится ли толкаемое слияние в неправильном направлении, то есть по умолчанию -> 2013C, 2013C -> 2013B и т. Д.Поиск слияний в неправильном направлении

У нас также есть ветви, специфичные для команды, некоторые из которых работа над функциями для выпуска и другие, которые работают над следующим выпуском, например по умолчанию. Пока команда работает над выпуском, они объединяются в/из ветви релиза. Когда команда готова к работе над следующим выпуском, они начинают сливаться в/из ветви по умолчанию.

На днях у нас сложилась ситуация, когда разработчик слил дефолт в свою ветку своей команды, прежде чем команда была готова перейти к следующей версии, а затем объединила ветку команды в предыдущий выпуск, то есть по умолчанию -> TeamBranch -> 2013B. К сожалению, наш крючок не учитывал эту ситуацию.

По сути, это то, что случилось:

2013B  A---o---o---o---o---B---o 
     / \   / \ 
Team /  o---o---o---C---o---o 
     /    /  \ 
Default D---o---o---o---o---o---o---o---o 

A = Создание 2013B ветви
B = Объединить в релизе ветвь
C = Плохие слияния. Мы хотим обнаруживать и предотвращать их, когда мы объединяемся в ветвь релиза.
D = Первый общий предок ветви выпуска и значение по умолчанию.

Итак, я переписал наш крючок, чтобы проверить, что, когда изменение будет объединено в ветвь освобождения, оно не сливается назад. Для каждого слияния в ветви релиза я проверяю, что какой-либо предок не сливается с передовой ветвью. Вот вопрос об отсрочке, который я использую:

> hg log -r "limit(descendants(p1(first(branch('2013B')))) and reverse(p2(ancestors(branch('2013B'))) and branch('default')),1)" 

Это работает. Однако у нас есть большой репозиторий (111 000+ наборов изменений), и проверка занимает 30-40 секунд. Я хотел знать, есть ли более быстрый/более быстрый/более эффективный способ написания моего запроса на отсрочку или другого подхода, который я не вижу.

ответ

2

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

Вместо использования branch() я перешел к использованию descendants() и ancestors():

limit(children(p2(2013BBaseline:: and ::2013B and merge()) and branch(default)) and reverse(::2013B)) 
  • p2(2013BBaseline:: and ::2013B and merge()) and branch(default) захватывает второй родитель (входящий филиал) для всех сливается между началом 2013B ветви и его головой, и возвращает только те, которые указаны в ветке по умолчанию. [1]
  • Затем приведенное выше предложение завернуто в children(), чтобы вернуться к дочерним элементам этого родителя.
  • and reverse(::2013B) затем получает детей, которые являются предками ветви 2013B, то есть плохих слияний (-ов).
  • limit() затем возвращает только первое из этих плохих слияний.

Запрос занимает около 1,5 секунд.

Благодаря Matt Mackall за предложение решения.

  1. 2013BBaseline является тег, который идентифицирует ревизию в default ветви, из которого был создан 2013B филиал, в противном случае мне пришлось бы заменить 2013BBaseline:: с:

    p1(first(branch(2013B))):: 
    

    обнаружить базовую Ветвь релиза, в и это не очень хорошо.

0

Для обнаружения слияния C, вы должны быть в состоянии использовать

$ hg log -r "parents(branch(Team) and merge()) and branch(default)" 

Это дает ревизии на default, которые были объединены в Team. Если они есть, то кто-то ошибся. Я думаю, вам нужно атаковать это с точки зрения ветви команды: вы не можете запрещать слияние с/из ветки релиза, поскольку некоторые из них будут законными.

Если ваши ветви вашей команды следуют согласованной схеме именования (они должны), вы можете использовать регулярное выражение с предикатом branch(), чтобы выбрать их. Что-то вроде

$ hg log -r "branch('re:team-.*')" 

будет соответствовать веткам, начиная с team-.

+0

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

+0

Не можете ли вы соответствовать ветвям команды, используя шаблон, как я предложил? –

+0

Нет. Командные ветви имеют произвольные имена. Никакое регулярное выражение не будет захватывать все возможные комбинации. Кроме того, предложение 'branch()' является узким местом, поэтому мне нужно избегать его использования, по крайней мере, до тех пор, пока запрос уже не изменит набор наборов изменений. –

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