Pull to refresh

Subversion: чеклист по правильным коммитам

Lumber room
Предполагаем, что читатель: а) работает в коллективе; и б) осознал необходимость правильной работы с системами контроля версий или хотя бы поставлен перед необходимостью использовать таковую.

В примерах будет использоваться Subversion, хотя все рекомендации полностью применимы к любой другой системе контроля версий.

Грубо разделим фазы разработки проекта на три — дебют, миттельшпиль и эндшпиль.

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

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

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



В дебюте коммиты делаются относительно редко. Например, хорошей точкой коммита может стать создание нового класса, нового отношения или же написание предварительной версии достаточно большого куска кода. Для некоторых программистов, особенно высокопроизводительных, может быть даже удобным коммит, привязанный ко времени — два-три раза в день. Репозиторий может быть в достаточно «разобранном» состоянии, вплоть до того, что извлеченный код попросту не компилируется.

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

Наконец, в эндшпиле коммиты так или иначе контролируются достаточно жестко. Вообще сам факт работы над проектом в этой фазе должен иметь некоторое обоснование — обычно это баг или перенесенная за релиз важная фича. Коммиты на этой фазе достаточно быстро уходят на продакшн, поэтому они: чётко привязаны к баг-трекеру; относительно мелкие; хорошо документированы; хорошо оттестированы и продуманы — внесение дополнительных багов на этой стадии наносит серьёзный кармический удар).

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

Вообще, на наш взгляд, глубина понимания программистом проекта, над которым он работает, сильно коррелирует с качеством коммитов, которые он делает в процессе работы.

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

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

Коммиты должны быть протестированными (за исключением дебютной фазы). Идеально если изменение вообще протестировано юнит-тестами. В крайнем случае коммит нужно хотя бы раз проверить — даже самые безобидные исправления могу привести к катастрофическим для кармы последствиям. Безусловно, коммит должен быть синтаксически валидным — фикс к фиксу наносит удар по имиджу.

Коммиты должны быть хорошо документированными. Мы молчим про пустые журнальные сообщения — это вообще худшее что может быть. Это допустимо только для совершенно далеких от программирования сотрудников (типа дизайнеров), которые на этот ваш сабвершен с трудом вообще согласились. И то, имеет смысл работать над культурным уровнем даже таких людей! Коммит с описанием «Fix» или «Fixed» допустим только если в диффе не более двух-трёх строчек. Если больше — надо писать более развернуто.

Отдельно надо рассмотреть вопрос журнального сообщения, состоящего из нескольких не связанных друг с другом пунктов. Понятно, что такое сообщение — это симптом истинной проблемы — той, что ваш коммит состоит из нескольких не связанных друг с другом частей. Лучшим решением в данном случае было бы отменить попытку коммита и постараться расщепить его на несколько частей.

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

Перед коммитом необходимо просматривать диффы, а также следить за новыми файлами, не добавленными в репозиторий, и добавлять их. Если вы пользуетесь TortoiseSVN, то в ней есть специальный пункт меню под названием «Check for modifications». В комманд-лайновом клиенте для этой цели служат команды svn st (нет ли болтающихся файлов) и svn diff | more (для отсмотра изменений перед коммитом).

Это правило необходимо соблюдать, чтобы не закоммитить случайно что-нибудь не то. Известно, что например в процессе исправления ошибок субъективно кажется, что «было много работы». Однако, при отсмотре диффа оказывается, что реально было исправлено одна-две строчки. Отсмотр также позволяет устранить мусор из коммитов — например, временные отладочные операторы и пустые изменения (добавление и удаление пробелов). Зачастую бывает, что в том или ином файле вообще остаются только пробельные изменения — их необходимо откатить в исходному состоянию (svn revert). В фазе эндшпиля отсмотр изменений перед коммитом строго обязателен.

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

Также более мелкие правила:

— при переименовании файла и внесении в него изменений следует отдельно закоммитить переименование, а отдельно изменение;

— при добавлении в код проекта стороннего компонента (плагина Rails, файла prototype.js) их следует коммитить отдельно;

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

Вопросы, пожелания, предложения?

P.S. У нас есть целая куча вакансий: undev.ru
Tags:
Hubs:
Total votes 42: ↑39 and ↓3 +36
Views 4K
Comments 59
Comments Comments 59

Posts