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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам