Получает ли bisect в управлении версиями пользу от использования рабочего процесса rebaseif?

Расширение rebaseif mercurial автоматизирует процесс перебазирования при извлечении только в том случае, если слияние может быть выполнено автоматически без конфликтов. (Если есть конфликты, которые нужно разрешить вручную, перебазирование не выполняется, и вы готовы выполнить ручное слияние двух ветвей.) Это упрощает и линеаризует историю, когда разработчики работают с разными частями кода, хотя любое перебазирование вызывает убрать некоторую информацию о состоянии мира, когда разработчик выполнял работу. Я склонен соглашаться с такими аргументами, как это и это, что в общем случае перебазирование не является хорошей идеей, но я нахожу философию перебазирования привлекательной для бесконфликтный случай. Я сомневаюсь в этом, хотя понимаю, что по-прежнему существуют риски логических ошибок, когда изменения происходят в разных частях кода (и автор расширения rebaseif пришел к выводу, что это плохая идея..)

Недавно я прошел через сложный и болезненный bisect, и я думаю, что наличие большого количества слияний коротких ветвей в нашем репозитории было основной причиной, по которой bisect не оправдал подразумеваемого обещания O(lg n). Я обнаружил, что мне нужно запускать bisect --extend много раз, чтобы растянуть диапазон за пределы слияния, проходя по паре наборов изменений за раз, по сути делая деление пополам O(n). Мне также было очень сложно отслеживать, как продвигается биссектриса, и понимать, какую информацию я получил на данный момент, потому что я не мог следить за ветвлением, глядя на графики репозитория.

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

Я помечаю это более общим тегом (не только mercurial), поскольку считаю, что rebaseif соответствует более типичному рабочему процессу git: пользователи git могли видеть подводные камни.


person Joshua Goldberg    schedule 08.10.2012    source источник
comment
Там есть хороший разговор о ценности предоставления hg максимально возможного диапазона (например, 0::tip) здесь.   -  person Edward    schedule 02.11.2012
comment
Я ценю это, но прав ли я в том, что вы не можете ожидать, что это сработает в тех случаях, когда тест не прошел в прошлом? Bisect может столкнуться с каким-то старым сбоем, который был исправлен, и назвать начало этого периода первым известным сбоем.   -  person Joshua Goldberg    schedule 03.11.2012
comment
Истинный. bisect остановится, когда найдет точку, в которой качество изменится с хорошего на плохое. Вы можете попытаться улучшить свой тест (если это возможно!), чтобы поймать только новый. Или вы можете инвертировать свой тест и использовать старый плохой результат в качестве начала, чтобы найти следующий переход от плохого к хорошему и начать с него. С моей точки зрения, проще начать с большего и сузить диапазон, чем постепенно расширять диапазон.   -  person Edward    schedule 03.11.2012


Ответы (2)


Я думаю, что ответ прост: вам нужно выбирать между жесткой делением пополам или рискованным перемещением базы.

Или что-то среднее: только перебазировать, если очень маловероятно, что перебазирование молча сломает что-то. Если перебазирование включает только несколько наборов изменений, которые дополнительно семантически далеки от изменений, на которых они перебазируются, обычно перебазирование безопасно.

Вот пример, когда бесконфликтное слияние ломает вещи:

Предположим, что из файла с таким содержимым начинаются две ветки:

def foo(a):
    # do
    # something
    # with a (an integer)

...

foo(4)

В ветке A это изменено на:

def foo(a):
    # now this function is 10 times faster, but only work with positive integers
    assert a > 0
    # do
    # something with
    # with a

...

foo(4)

В ветке B он меняется на:

def foo(a):
    # do
    # something
    # with a (an integer)

...

foo(4)

...

foo(-1) # now we have a use case where we need to call foo with -1

Семантически обе правки конфликтуют друг с другом. Однако Mercurial успешно объединяет их без конфликтов (в обоих случаях, при ребейзинге или при обычном слиянии):

def foo(a):
    # now this function is 10 times faster, but only work with positive integers
    assert a > 0
    # do
    # something with
    # with a

...

foo(4)

...

foo(-1) # now we have a use case where we need to call foo with -1

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

person Oben Sonne    schedule 08.10.2012
comment
Во-первых, спасибо за простой, конкретный пример, помогающий обсуждению. Я думаю, что понятие семантически удаленного от изменений, на которые они перебазируются, является хорошей политикой компромисса, которая позволит перебазировать во многих случаях, даже если это требует немного больше внимания и суждений разработчика, чем любая политика в чистом виде. (Я бы добавил в том же духе, что большие объемы работы, вероятно, следует оставить на ветвях и явно объединить.) - person Joshua Goldberg; 09.10.2012

Основной аргумент против git rebase кажется философским, касающимся «потери истории», но если бы меня это действительно заботило, я бы сделал последний шаг сборки чекином (или первым шагом сборки, чтобы отслеживать все неудачные сборки тоже!).

Я не особенно знаком с Mercurial или bisecting (за исключением того, что это немного похоже на git), но за месяц с git я придерживался исключительно перебазирования. Я также использую git rebase -i --autosquash и git add -p часто.

IME, также нет большой разницы между перебазированием и слиянием, когда дело доходит до устранения конфликтов — ответ, на который вы ссылаетесь, предполагает, что «rebaseif» плохой, потому что «если» определяет, прошло ли слияние без конфликтов, тогда как это должен зависеть от того, пройдены ли сборки и тесты кодовой базы.

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

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

person tc.    schedule 08.10.2012
comment
Я думаю, дело не в том, что if для перебазирования (по сравнению с ветвлением и слиянием) в идеале будет зависеть от того, все ли в программном обеспечении работает правильно. Лучше задать вопрос, несет ли это конкретное слияние (в отличие от новой работы в любой из ветвей) некоторый риск появления новых проблем. - person Joshua Goldberg; 09.10.2012