金曜日の午後、クライアントへの製品リリースの準備。かつての私たちのチームは、よく混乱に陥っていました。開発者Aが「このバージョンはv1.2だ」と言えば、開発者Bは「バグを直したばかりだからv1.2.1のはずだ」と反論します。その結果、サーバー上には source_code_final.zip、source_code_final_v2.zip、さらには source_code_FIX_CUOI_CUNG.zip(最終修正版)といった圧縮ファイルが山積みになりました。それらを見ても、どれが最も安定して動作するバージョンなのか誰にも分かりませんでした。
Git Tag と Semantic Versioning (SemVer) を導入したことで、すべてが変わりました。このプロセスは混乱を整理し、デプロイ作業をたった一度のpushコマンドへと変えてくれました。私とチームメイトの生活は、以前よりもずっと楽になりました。
バージョン管理における「典型的」な間違い
現在でも多くのチームが、リリースの節目を記録するために以下の3つの手動プロセスを行っています:
- フォルダのコピー&ペースト: ソースコードを日付ごとに圧縮する方法です。これは非常にストレージを消費します。5人が同じことをすれば、すぐにコントロールを失うでしょう。
- リリースブランチの乱用: リリースごとに
release-v1.0のようなブランチを作成する方法です。Gitのグラフは絡まった電線のようになり、管理が非常に困難になります。 - 手動のメモ: CHANGELOGファイルにのみバージョンを記述する方法です。この方法はコンピューターが理解できないため、CI/CDプロセスを自動化することができません。
以前、8人のチームでプロジェクトを行っていた際、ブランチを乱用したことでコードのマージが地獄のようになりました。誰も削除する勇気がなく、1年も放置されたブランチもありました。その時、Git Tagが必須のソリューションであると確信したのです。
Git Tagとブランチの違いは何でしょうか?
Gitを学び始めたばかりの人は、よくこの2つの概念を混同します。こう想像してみてください。ブランチ(Branch)は「建設中の道路」のようなもので、常に変化し、前方へと進んでいきます。一方、タグ(Tag)は、その道路上にある「固定されたキロポスト(距離標)」のようなものです。あるコミットにタグを付けると、その後にどれだけコードを追加しても、タグは永遠にその地点に留まります。
なぜタグを使うべきなのか?
- 不変性 (Immutable): タグ
v1.0.0は常にその特定のコミットを指します。誰かが誤って上書きコミットをすることはありません。 - 超軽量: タグは実質的に小さなポインタに過ぎず、リポジトリを重くすることはありません。
- 高速なアクセス: バグ修正のために、3秒で旧バージョンのコード状態に戻ることができます。
実践的なSemantic Versioning (SemVer) の適用
タグ名を v1 や v2 のように適当に付けてはいけません。MAJOR.MINOR.PATCH(例:1.2.3)という標準を使いましょう。これにより、誰もが変更の規模を一目で理解できるようになります:
- MAJOR(最初の数字): 互換性を損なう大きな変更(ブレーキングチェンジ)があった場合に増やします。例:APIの構造を全面的に変更し、旧アプリが呼び出せなくなった場合など。
- MINOR(真ん中の数字): 既存のコードと互換性を保ちつつ、新機能を追加した場合に増やします。例:「チャットで画像を送る」ボタンを追加した場合など。
- PATCH(最後の数字): バグ修正(Bug fixes)のみの場合に増やします。機能追加もなく、既存の動作も壊しません。
このルールを導入してから、テストチームの効率が格段に上がりました。PATCHの数字だけが増えたなら、彼らはクイックテストを行うだけで済みます。MAJORが増えたなら、システム全体の総点検が必要だと判断できるからです。
Git Tagの実装:覚えておくべきコマンド
タグには2つの種類があります。Lightweight(単なる名前)と Annotated(作成者情報や日付を含む)です。リリースの際は、よりプロフェッショナルで情報量が多い Annotated tag を優先的に使用することを推奨します。
1. 新しいタグの作成
表示バグを修正し、バージョン v1.0.1 に上げたい場合を想定します:
# 説明付きのAnnotated Tagを作成
git tag -a v1.0.1 -m "Safariでの表示バグ修正およびAPIエンドポイントの更新"
# 既存のタグ一覧を表示
git tag
2. タグをサーバーにプッシュする
注意:通常の git push コマンドではタグは GitHub/GitLab に送信されません。専用のコマンドを使う必要があります:
# 特定のタグをプッシュ
git push origin v1.0.1
# すべてのタグをプッシュ(取り扱いに注意)
git push origin --tags
3. 間違えてタグを付けた時の対処法
誤ってタグを付けてしまっても心配いりません。以下の手順で削除して再作成できます:
# ローカルのタグを削除
git tag -d v1.0.1
# サーバー上のタグを削除
git push --delete origin v1.0.1
Git TagによるCI/CDの自動化
これが作業時間を大幅に節約するための鍵です。サーバーにログインして手動でコマンドを打つ代わりに、システムが自動でビルドするように設定します。以下は GitHub Actions の例です:
name: Deploy Production
on:
push:
tags:
- 'v*' # 'v'で始まるタグがプッシュされた時にスクリプトを実行
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build and Push Docker
run: |
docker build -t my-app:${{ github.ref_name }} .
docker push my-app:${{ github.ref_name }}
この設定により、タグ v1.1.0 をプッシュするたびに、システムが自動的にパッケージングして本番環境へデプロイします。プログレスバーを眺めて待つ代わりに、ゆっくりとコーヒーを飲む時間が生まれます。
現場からのアドバイス
長年、大規模なプロジェクトを管理してきた経験から、3つの黄金律を導き出しました:
- タグ上で直接コードを修正しない: もし
v1.0.0にバグが見つかったら、hotfixブランチを作成して修正し、その後にv1.0.1としてタグを打ち直しましょう。 - 常に接頭辞 ‘v’ を付ける:
1.0.0ではなくv1.0.0と命名することで、自動化スクリプトがより正確に動作するようになります。 - 意味のあるメッセージを書く:
-m "Update"だけで済ませないでください。主な変更点を要約しておくことで、後にクライアント向けのChangelogを自動生成する際に役立ちます。
Git TagとSemVerは単なる技術ではなく、管理の考え方です。すべてが明確になれば、開発者、テスター、そしてクライアント間のコミュニケーションはより円滑になります。もしあなたのチームがいまだにzipファイルで苦労しているなら、今日からTagへの移行を試してみてください。

