Руководство по командной разработке с Git

Это руководство по разработке с git написано на основе статьи “Как внедрить свои изменения в ядро Linux”, информации из раздела справки по git и различных техниках, которые популярны в сообществе.

Ветви

  • Старайтесь давать ветвям в git короткие, описательные названия:
    # хорошее название
    $ git checkout -b oauth-migration
    
    # плохое название - слишком расплывчатое
    $ git checkout -b login_fix
  • Для этой цели также прекрасно подойдут разнообразные идентификаторы задач (например, задача, созданная в сервисе Github):
    # задача №15 в гитхабе
    $ git checkout -b issue-15
  • Если в названии несколько слов, для разделения используйте дефис «-».
  • Когда несколько человек одновременно работают над одним функционалом, возможно, было бы удобно создать отдельную ветку на каждого разработчика и общую ветвь, в которой хранятся все изменения, используя такое именование:
    $ git checkout -b feature-a/master # общая ветка
    $ git checkout -b feature-a/maria  # личная ветка Марии
    $ git checkout -b feature-a/nick   # личная ветка Ника

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

  • Если нет необходимости хранить изменения, сделанные в ветке, то после слияния ее необходимо удалить из удаленного репозитория.
  • Совет: чтобы просмотреть список ветвей, которые были “слиты” в master, используйте следующую команду:
    $ git branch --merged | grep -v "\*"

Коммиты

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

Сообщения к коммитам

  • Для написания сообщения к коммиту лучше использовать текстовый редактор, а не консоль:
    # хороший стиль
    $ git commit
    
    # плохой стиль
    $ git commit -m "Quick fix"

    Сохранение изменений в консоли заставляет писать сообщения длинной не более одной строки, что в итоги выливается в неинформативные и неоднозначные сообщения к коммиту.

  • Сообщение должно быть описательным и лаконичным. В идеале, оно не должно быть более 50 символов и начинаться с большой буквы. Также в конце сообщения не нужно ставить точку, ведь оно, в какой-то степени, является названием  коммита:
    # хорошее сообщение - начинается с заглавной буквы, длина менее 50 символов
    Помечаем большие записи устаревшими для устранения ошибок при очистке 
    
    # плохое сообщение
    устранили сообщения об устаревших ActiveModel::Errors когда ActiveRecord используется вне Rails.
  • После названия необходимо дать более полное описание изменений, сделанных в коммите. При этом название и описание надо разделить пустой строкой. Описание должно быть ограничено 72 символами, кроме того, в нем нужно пояснить, для чего именно были внесены эти изменения, как это изменение решает поставленную задачу и какие побочные эффекты возможны при этом.
    Кроме того, в описание необходимо включить связанные с коммитом ресурсы (например, ссылку на соответствующую задачу в системе для отслеживания ошибок):

    Короткое (не более 50 символов) описание.
    
    Для необходимости, более детальное объяснение, ограниченное 72 символами. 
    Иногда первая строка коммита трактуется как тема электронного письма, а остальное - как
    его тело. Пустая линия, которая разделяет "тему" от "тела" письма необходима, иначе такие 
    команды как rebase воспримут их как одну. 
    
    - Можно использовать ненумерованные списки с точкой, дефисом либо звездочкой в качестве маркера, 
    отделяя при этом пункты пустыми строками.
    Источник http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
    

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

  • Если коммит необходимо добавить к другому коммиту, для этого нужно использовать флаги --squash и --fixup:
    $ git commit --squash f387cab2

    (Совет: Используйте флаг --autosquash при перемещении ваших изменений. При этом помеченные коммиты будут “слиты” автоматически.)

Слияние изменений

  • Не переписывайте историю репозитория, если она уже опубликована. По ней можно понять, что произошло на самом деле. Изменение истории репозитория может обернуться большими проблемами для всех, кто с ним работает.
  • Однако есть случаи, в которых изменение истории вполне обоснованно:
    • Вы в одиночку работаете в ветке и ваш код не проходит ревью.
    • Вы хотите “убрать” у себя в ветке (слить некоторые коммиты в один) и переместить изменения в ветку master, чтобы слить эти изменения позже.
  • Не нужно переписывать историю ни master, ни каких либо других специальных веток (особенно тех, которые используются серверами непрерывной интеграции).
  • Старайтесь поддерживать историю коммитов ясной и простой. Перед слиянием изменений из вашей ветки:
    • Если изменения не соответствуют вышеописанным нормам, то исправьте это (измените порядок следования коммитов, “сожмите” несколько коммитов в один, переформулируйте сообщения). Далее переместите изменения в ветку, в которую необходимо их внедрить:
      $ git fetch [my-branch]
      $ git rebase origin/master
      # а только потом проводите слияние
  • Эти команды создают ветку, которую можно присоединить в конец master, что значительно упрощает историю коммитов. (Примечание: этот способ хорошо использовать для проектов с относительно небольшими ветками. В противном случае, более правильным подходом было бы просто провести слияние веток.)
  • Если у вас в ветке больше одного коммита, не стоит делать автоматическое слияние:
    # хороший стиль - коммит со слиянием будет создан
    $ git merge --no-ff my-branch
    # плохой стиль
    $ git merge my-branch

Дополнительные рекомендации

  • Существуют различные способы организации командной разработки и у каждого есть свои достоинства и недостатки. Какой подойдет именно вам, зависит от команды, проекта и процесса разработки. Самое важное здесь — это выбрать свой способ и придерживаться его.
  • Будьте последовательны. Это относится к организации разработки, но также касается таких вещей, как: сообщения к коммитам, названиям, которые вы даете ветвям, и именам тэгов. Следуйте выбранному стилю по всему репозиторию, так как это улучшает понимание проекта в целом.
  • Перед отправкой изменений на удаленный сервер протестируйте ваш функционал. Не нужно отправлять полуготовый продукт.
  • Используйте аннотированные метки чтобы отметить релиз продукта или другие важные точки в истории изменений проекта.
  • Используйте подписанные метки для личного использования, в качестве “закладок” для коммитов.
  • Поддерживайте в вашем репозитории чистоту при помощи выполнения этих команд:

Перевод статьи «Git Style Guide»