Полуавтоматическое выставление номера версии с помощью git

Гуляя по github'у я много раз видел в разных репозиториях одновременно и теги вида «v2.3.4» и коммиты с сообщениями типа «Bump version» и сменой номеров версии где-нибудь в lib/version.rb. И всегда мне казалось — что-то тут лишнее.

И когда пришло время задуматься и мне над расставлением номеров версий, я сказал: «Нет! Я не буду прописывать эти номера в файлы руками. Пусть это делает за меня моя система контроля версий!»

Итак, как вижу это я:


  1. Номер версии выглядит как тройка чисел: мажорная.минорная.патч-версия и увеличивается согласно рациональной политике назначений версий;
  2. При выпуске каждой новой минорной версии я для определённого коммита в истории создаю тег вида v<мажорная>.<минорная>;
  3. Git автоматически выдаёт мне номер версии, основываясь на последнем тэге (для этого коммита) и количестве коммитов, после него.


Как это работает:


В составе git есть много полезных команд, нас будут интересовать две:
  1. git describe — показывает информацию о самом последнем тэге, доступном из данного коммита;
  2. git show — отображает различные типы объектов (но нас будет интересовать только текущий коммит).


Вооружившись этими знаниями, я в свой rails проект в папку config/initializers поместил файл version.rb следующего содержания:

module AppName
  module Version
    Described = (IO::popen('git describe --long') { |gs| gs.read }).strip
    Number = Described.gsub('-', '.').gsub(/^v/, '').split('.')[0..-2].join('.')
    Date = Date.strptime( IO::popen('git show -s --format="%ct"') { |gs| gs.read } , "%s")
    Revision = (IO::popen('git show -s --format="%H"') { |gs| gs.read }).strip
  end
end


Здесь происходит следующее:

Команда git describe --long выводит сообщение примерно следующего вида: v0.8-3-g387f83f, где

Строчка Described.gsub('-', '.').gsub(/^v/, '').split('.')[0..-2].join('.') приводит это сообщение к виду 0.8.3

Командой git show -s --format="%ct" мы получаем дату создания текущего коммита в формате Unix.

А git show -s --format="%H" возвращает нам полный хэш коммита.

Результат


Теперь при старте приложения нам автомагически становится доступен текущий номер версии и дата выпуска. И теперь, где-нибудь на страничке мы можем написать:

"Приложение AppName. Версия #{AppName::Version::Number} от #{I18n.l AppName::Version::Date, :format => :long} года."

И получить
"Приложение AppName. Версия 0.8.3 от 27 марта 2012 года."


Плюсы и минусы


Плюсы

Минусы


Что почитать?


Ну, во-первых, мануалы по git describe и git show.

А вообще, поиск по "<CVS> autoversioning" (где <CVS> — название вашей любимой системы контроля версий) выдаст вам немалое количество рецептов для любых случаев, программ и технологий.

Успехов вам в наведении порядка (хотя бы в версиях).
@Envek
28.03.2012 09:43 UTC
Первоисточник