[Перевод] Идеальная длина pull request-а – пятьдесят строк
Большинство программистов интуитивно понимают, что изменения в коде лучше делать небольшими порциями, чем большими. Логические аргументы легко приходят на ум: с небольшими pull request-ами (PR) проще работать, в них реже встречаются баги, и период от написания до развертывания у них обычно бывает короче. На этот счет написано несколько статей, которые мне очень нравятся — посмотрите список в конце текста, если захотите почитать еще что-то на данную тему.
Но что мы подразумеваем под «небольшими»? Может ли PR оказаться слишком маленьким? И если небольшие PR действительно лучше, то насколько велика разница?
Гипотеза: идеальный PR содержит пятьдесят строк
По итогам расчетов, мы пришли к выводу, что оптимальным является такой объем изменений в коде, который укладывается в 50 строк. Обработка и слияние у таких PR происходит на 40% быстрее, чем у фрагментов кода в 250 строк. Их откатывают на 15% реже, чем фрагменты кода в 250 строк, и они получают на 40% больше комментариев на строку кода. Если медианная длина PR у вас составляет 50 строк, то вы, вероятно, суммарно выдаете на 40% больше кода, чем ваш коллега, который пишет PR в 200 строк и больше.
Пятьдесят строк — это оптимальная величина с точки зрения скорости, количества комментариев, процента откатов и общего объема кода. Если вас устроит диапазон, то я бы рекомендовал придерживаться нормы от 25 до 100 строк на PR. Наши данные показывают, что и время инспекции, и скорость слияния, и число комментариев на строку кода — все показатели улучшаются с урезанием размера PR. Но есть предел: опустившись ниже границы в 25 строк, вы начнете чаще сталкиваться с откатами и выдавать меньший объем кода в целом.
Наша выборка данных
Все утверждения в этой статье основываются на работе с данными из приватных и открытых PR и репозиториев, которые синхронизированы с Graphite. При расчете наилучшей длины PR я опирался на четыре метрики, отслеживая, как они соотносятся с размером PR:
- Время инспекции / скорость слияния
- Частота откатов
- Среднее число встроенных комментариев
- Общий объем кода, который подвергся изменениям за год
Оговорки
Как это всегда бывает с данными, есть некоторые оговорки, которые следует учитывать при осмыслении числовых показателей:
- Я выстроил непоследовательную нелинейную шкалу размеров PR в соответствии со своими интуитивными представлениями. Если строить ее линейно, получилось бы слишком дробно, если по экспоненте — потерялось бы слишком много тонкостей.
- Я использовал медианный, а не средний размер PR, чтобы статистические погрешности в виде рефакторов не искажали картину.
- Откаты определялись как те PR, у которых в заголовке проставлено слово Revert. Подобный критерий представляется надежным, поскольку в сгенерированных на GitHub откатах это слово добавляется автоматически.
- Как выяснилось, пользователи Graphite в целом склонны делать PR небольших размеров, так как многие организации используют метод TBD, который поощряет короткие PR.
Время инспекции и время до слияния
Давайте покопаемся в данных. Начнем с продолжительности инспекции и скорости слияния; здесь мы видим, что самые маленькие PR обнаруживают скорость почти в пять раз выше, чем PR длиной от 2000 до 5000 строк. Это интуитивно представляется логичным — в маленьких PR меньше строк кода, меньше кода значит меньше вероятности чего-то разрушительного или требующего особой тщательности, соответственно, инспекция проходит быстрее.
Но вот что любопытно: за границей в пять тысяч строк PR снова начинают ускоряться. Могу только предположить, что это влияние пропусков вслепую, рефакторов, которые считаются безопасными по умолчанию, пакетов дополнений или сгенерированных изменений. Возможно, за тем пределом, когда даже долистать до конца файла становится сложно, и те, кто пишет код, и те, кто его инспектирует, просто машут рукой.
Примечание: мы исходим из предположения, что для нас важнее время, затраченное на весь PR, а не на строку кода. Если мы хотим протащить PR как можно скорее, данные подсказывают нам, что нужно сделать его как можно короче. Если же мы хотим протащить максимально возможный объем кода как можно скорее, то PR в 2000 строк будет двигаться к слиянию со скоростью 12 строк в час, а PR в 10 строк — со скоростью от 0,25 до 2 строк в час.
Частота откатов
Показатели частоты откатов подводят к тому же глобальному выводу: небольшие PR откатывают реже, чем крупные; меньше всего им подвержены PR длиной от 25 до 50 строк кода. Но, опять же, тут интересно взглянуть на крайние точки шкалы. Откаты PR, в которых меньше 10 строк, случаются значительно чаще, чем у PR длиной от 10 до 100 строк. Я бы дал такое объяснение: PR с числом строк меньше десятка заступают на территорию опасных изменений конфигурации. Но было бы любопытно проверить, подтвердится ли это заключение при нормализации по языкам.
Когда размер PR превышает 10 000 строк, они понемногу становятся «безопаснее». Полагаю, из-за того, что на правую границу графика попадают рефакторы, которые, вероятно, несут в себе меньше изменений функциональности и, соответственно, создают несколько меньше риска, что всё сломается. Или же программистам нарастающе сложно решиться откатить PR в более 10 000 строк из-за эмоциональной привязки и конфликтов слияния.
Среднее число комментариев на строку
Вы можете решать, разбивать ли PR на короткие фрагменты исходя из того, какую цель преследуете — быстро слияние или подробный разбор кода. Если хотите получить максимум обратной связи на каждый PR, пишите по 1000–2000 строк. Если хотите повысить вероятность, что изменения пропустят не глядя, укладывайтесь в 10 строк. Эта информация полезна для тех случаев, когда вам только и нужно, что пропихнуть одно конкретное изменение с минимумом пререканий.
Также мы видим здесь, что у огромных PR вовлеченность инспектирующих пропорционально снижается. На практике существует предел того, сколько кода человек, проводящий инспекцию, готов прочитать. Подозреваю, что 2000 строк — эта та черта, за которой чтение PR превращается в просматривание PR.
Если для вас важно, получить как можно больше вовлеченности и обратной связи в долгосрочной перспективе, лучше всего делать предельно короткие PR. Они более удобоваримы, и у вас есть шанс выйти на максимальный показатель — один комментарий на 39 строк кода. С другой стороны, если вы не выносите обратную связь в письменной форме, можете начать выдавать PR длиной более 10 000 строк. Тогда вам станут попадаться лишь залетные комментарии раз в 6000 строк. Впрочем, не принимайте это слишком всерьез — люди ведь редко отправляют PR с единственной целью получить реакцию.
Общий объем кода
Кто-то, возможно, задается вопросом: не приводит ли создание небольших PR к тому, что суммарно кода набирается меньше. Мы все, конечно, мечтаем о высокой скорости, но бывают случаи, когда приходится работать с большим объемом. Если стабильно писать PR меньше 20 строк, это существенно скажется на вашей общей способности выдавать код — однако, что интересно, такой же эффект даст и написание PR длиной больше 100 строк. У разработчиков и репозиториев с наибольшими объемами кода медианная длина на изменение составляет не более 40–80 строк. Причина, как я предполагаю, в том, что объем выдачи рассчитывается как объем фрагментов, помноженный на скорость обработки. Если изменений слишком мало, быстрое слияние не покроет недостачу. Если их слишком много, начнут перевешивать возрастающая длина цикла слияния и замедленная инспекция.
На первом графике представлены средние значения по репозиториям, на втором — по авторам
Вывод
Среднему разработчику, который пишет код в составе команды в технической компании, следует ориентироваться на медианную длину PR в 50 строк — именно такого размера мы и стараемся придерживаться в Graphite. Само собой, здесь могут быть исключения — о них говорилось выше, и изменения определенного рода могут потребовать увеличения или сокращения размеров. Но имейте в виду, что это может привести к заметным издержкам в отношении качества инспекции, скорости и рисков отката изменений.
Другие материалы
Small patches get in!
Do small code changes merge faster? A multi-language empirical investigation