Pull to refresh

Comments 23

А что, есть те, кто не осилили оригинал и им надо перевод?

Здесь переводят не для тех, кто не осилил перевод.

Как мне кажется, возможно, связанный с небольшим опытом работы с Git, у длинных ветвей разработки есть недостаток. Когда между форком и принятым PR проходит значительно времени и мастер в этих двух точках отличается (другие программисты работают над другими ветвями). Если вы не владелец мастера, то этот недостаток не будет стоять перед вами, а перед тем, кто проводит Merge, но он все равно есть. Или потихоньку доливать в свою ветку код из мастера и готовить свой PR к Merge самостоятельно.
В таких случаях периодический rebase может спасти отца русской демократии. Не смотря на то, что многие боятся rebase как огня, попробуйте с ним разобраться, в особенности с его интерактивной составляющей. Оно того стоит.

Как я уже говорил в обсуждении ThreeFlow (начало здесь) просто разрешите merge, и никогда не делайте rebase для больших ветвей, за исключением редактирования истории (в смысле rebase --interactive, но без собственно rebase; у mercurial на это есть histedit, для git’а пришлось написать длинный alias, который определяет, с каким аргументами нужно вызвать rebase --interactive, чтобы ничего никуда не переносить и, к тому же, не уничтожить случайно слияния). «Периодический rebase» с лёгкостью незаметно переведёт пачку коммитов в ещё менее рабочее состояние, чем они были до этого, что отрицательно скажется на точность bisect, если в ветке найдутся ошибки.

А зачем мерджить пачку коммитов? Как в этом случае вообще гарантировать работоспособность каждого коммита в отдельности? CI обычно запускается на ветку, то есть на последний коммит.
Сливание пачки в один коммит решает эту проблему.
Что касается rebase, его делает автор изменений, убедившись, что все работает на свежем мастере. Разрешение конфликтов мало чем отличается от такового в случае merge, но в последнем мы получаем два коммита на одно изменение, что добавляет хаоса в проект.

Куда сливать пачку коммитов? Предполагается сливать master в длинную ветку, пока она не готова, если такое слияние зачем‐то требуется (возникли конфликты, был проведён рефакторинг, …), а не длинную ветку в master. Гарантировать работоспособность коммитов не нужно, но не нужно и делать их менее рабочими, чем они есть. Полный squash — это та же самая потеря точности bisect. А при rebase без squash будут цепочки конфликтов.


Относительно хаоса: а зачем вы используете историю, что оно вас волнует? Я вижу основные три применения: annotate, bisect при проблемах и создание списка изменений. Для bisect чем больше коммитов, тем лучше (если они, конечно, достаточно рабочие). Для annotate тоже. Для списка изменений git вполне позволяет вам пройтись только по «первым родителям», которыми будут слияния веток в master, а не слияния master в ветки, так что это только вопрос «насколько адекватны описания слияний».

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

Может и кажется, что легче, но если вы не делаете ещё и squash, то это абсолютно бесполезно, потому как вы анализируете не то, что реально было, а конфликты никуда не деваются, просто теперь размазаны и логику их разрешений опять никто не объснит. А если вы делаете, то вы получаете последовательность огромных патчей, из описания которой значительная часть логики автора пропала при squash; и, дополнительно, логику автора для разрешения конфликтов никто не объясняет и тут, просто теперь все притворяются, что никаких конфликтов не было.


И, самое весёлое, последовательность сплюснутых огромных коммитов в виде патчей соответствует последовательности разниц (в виде патчей) между первыми родителями при использовании слияний. Т.е. вы для «лёгкости анализа» зазря выкидываете кучу информации, ничего взамен реально не получая.

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

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

На review идёт уже результат слияния, он ничем не отличается от результата rebase+squash, кроме того, что вместо одного коммита с одним описанием есть последовательность. История со слияниями более подробна, понятность также ограничена авторами изменений и не всегда сильно страдает, а усилий нужно делать меньше. Понять «о чём думал автор» в случае спорных решений легче при последовательности изменений с описаниями, а сама модель более лояльна к большим изменениям, которые нельзя минимизировать.

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

Однако большие изменения возникают не сами по себе, а из подхода к разработке. Введение feature-toggle'ов позволяет коммитить частично готовый функционал (например набор оттестированных классов/функций), что способствует работе со свежим мастером и быть в курсе изменений в нем. Также большие изменения почти неизбежны при работе с legacy (читай «говно-») кодом, который требует обширного рефакторинга, но после некоторого времени, при правильном подходе, эта проблем уходит.

Тут конечно дело вкуса. Для большого, динамично развивающегося проекта я выбираю trunk-based с feature-toggle'ми.

Feature-toggl’ы не всегда возможны и увеличивают затраты на разработку — их нужно создавать, их нужно убирать, с ними нужно научить работать CI. Review тоже придётся делать чаще, при этом не обладая всей картиной: уже готовые классы и описание задачи reviewer увидит сразу, а насколько готовые классы оптимальны для задачи — нет, нужно выспрашивать у автора, какая картина у него в голове; к тому же я не удивлюсь, если в ходе работы над сложной задачей разработчик часто сначала будет допиливать что может до включения в master, а потом выпиливать это обратно. И это в дополнение к затратам на поддержание «чистоты» истории. А refactoring требуется не только legacy, хотя обширный, может, и реже — смотря что не учли при разработке архитектуры. В trunk-based с флагами я пока вижу только «давайте увеличим трудозатраты программистов и reviewer’ов (часто — других программистов) на то, чтобы тимлид смог читать „чистую“ историю».

Возможно у вас другая практика ревью и структура команды, размер проекта, время жизни проекта…

У нас плоская структура (Scrum), тимлида как такового нет, есть более опытные разработчики и менее опытные. Историю читают все. Знания шарятся между всеми разработчиками проекта (уменьшаем bus-factor) в том числе посредством код ревью. Для эффективности этого процесса нужно минимизировать изменения, иначе код ревью превращается в проверку код-стайла, так как понять суть изменений слишком сложно.

Для долгоживущего проекта время разработки не критично, критично время внесения изменений. И feature toggl'ы — позволяют поддерживать это время на приемлемом уровне, так же как и SOLID, юнит тесты, TDD.

CI можно гонять для всех юнит тестов и для интеграционных тестов продакшн конфигурации. Но это отдельная тема.
Относительно хаоса: а зачем вы используете историю, что оно вас волнует?

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

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

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

Такой перевод очень больно читать. Я пока понял, что "фиксация" — это коммит, думал, что я вообще в Алису в стране чудес попал

А «запрос слияния» и «ствол» как вам? ))))

У автора фиксация на переводе фиксаций. Фиксация такое русское слово, что назвать коммит коммитом никак нельзя.
Т.е. вы считаете PR в dev не делается?
Там ровно такое же код ревью, ровно такой же PR с обсуждением и так далее.
Master — продакшен
Dev — стейдж
GitFlow на хабре
В случае GitFlow проблема возникает только в dev'е, а мастер всегда рабочий (ну, во всяком случае чаще).
В вашем случае если ошибку упустили на ревью, если не обнаружили на тестах ДО слияния, то оно вполне может попасть на прод.

Да "дев" автор где-то потерял в самом начале. :)

Перешли в компании на этот подход, избавились от develop. Стало проще делать релизы.

Sign up to leave a comment.

Articles

Change theme settings