読者です 読者をやめる 読者になる 読者になる

gitでタグ名に日付を含めているのはダサい

この記事は私の考えるタグの使い方なので、もし間違っている事や反論のある方は ぜひコメントやブログを書いてください。読みます!

タグを打つ意味

そもそも、なぜgitでタグを打つのか? これは下記のような理由だと思う。

  • sha1でコミュニケーションするのは一般的に難しい*1
  • コミットとは別にデプロイなどのイベントをリポジトリ内で扱うため

そもそも、gitのタグとは

gitのタグはタグオブジェクトという形でgitのリポジトリ内に保存されます。*2

タグオブジェクトには下記の情報が含まれます。

  • タグを作成した日時
  • タグ作成者
  • タグを作成した理由
  • タグを付けたコミットのsha1

日付つきのタグとは

タグの名前に日付情報がつけられたものです。

$ git tag -m "bump tag" 1.0.0-`date "+%Y%m%d_%H%M%S"`
$ git tag -l
1.0.0-20140601_194744

こういうの。

なぜ日付つきタグが使われるのか

おそらく「タグ名がユニークになる」「デプロイ日時をタグにすると分かり易い」ことが理由だと思う。

なぜ日付つきのタグがダメか

ダメ理由1: 冗長

先に説明した通り、タグオブジェクトには日時情報が含まれています。 タグ名にわざわざ日付を入れるのは冗長です。無駄です。

ダメ理由2: 読みづらい、伝えづらい

「前回リリースしたのは 1.0.0-20140601_194744です」
「前回リリースしたのは 1.0.0.12です」

後者の方が10倍は分かり易い。

日付つきタグを打つより、普通にインクリメントしたタグ名にしよう。

ありそうな反論1: デプロイの日時が分かりにくい

タグの日時を確認する場合

$ git show v1.0.12

特定の日時以降のタグを表示する場合

$ git log --no-walk --tags --since="2014/03/17"

こんなに簡単!更に

$ git log --no-walk --tags --since="2 weeks ago"

とかも出来て、むしろ日付つきタグより便利。

ありそうな反論2: インクリメントが面倒

またまた、ご冗談を。 エンジニアならこのくらいのシェルを簡単に書けるから問題ないですよね。

  • version_up.sh
#!/bin/sh
version=`awk '{print $1}' < /dev/stdin`
command=$1
major=`echo $version | awk -F '.' '{print $1}'`
minor=`echo $version | awk -F '.' '{print $2}'`
bugfix=`echo $version | awk -F '.' '{print $3}'`
build=`echo $version | awk -F '.' '{print $4}'`

if [ -z "$version" ]; then
  echo "USAGE: echo 1.0.0 | version_up.sh [major|minor|bugfix|build]"
  exit 1
fi

if [ "$command" = '' ]; then
  if [ -n "$build" ]; then
    build=`expr $build + 1`
  elif [ -n "$bugfix" ]; then
    bugfix=`expr $bugfix + 1`
  fi
elif [ "$command" = 'major' ]; then
  major=`expr $major + 1`
  minor=0
  bugfix=0
elif [ "$command" = 'minor' ]; then
  minor=`expr $minor + 1`
  bugfix=0
elif [ "$command" = 'bugfix' ]; then
  minor=`expr $bugfix + 1`
elif [ "$command" = 'build' ]; then
  minor=`expr $build + 1`
fi

if [ "$command" = "major" -o "$command" = 'minor' -o "$command" = 'bugfix' ]; then
  if [ -n "$build" ]; then
    build=0
  fi
fi

if [ -n "$build" ]; then
  echo ${major}.${minor}.${bugfix}.${build}
else
  echo ${major}.${minor}.${bugfix}
fi

上記のようなshellを用意すれば、インクリメントは簡単に出来ます。*3

$ git tag -l
1.0.0.0
1.0.0.1
1.0.0.2
$ git tag -l | tail -n 1 | version_up.sh
1.0.0.3

まとめ

こうやって、少しずつ日付つきタグはダサいという風潮を広めたい。

とはいえ、既存の開発環境が日付タグを前提とした運用になっていると変えるのは結構面倒なんですよね('A`)

*1:エンジニアならsha1で会話できる可能性もあるが、デザイナーとかPMなどの方とsha1で話すのは無理だと思う

*2:gitには軽量タグもありますが、ここではアノテーションタグについての説明です

*3:v1.0.0.0 にしたり、RC-01 などをつける場合はもう少し大変。まぁ、すぐスクリプト書けると思いますが