Gitのtagは「特定のコミットに固定ラベルを貼る」シンプルな機能ですが、実はソフトウェアリリース管理の骨格を担う重要な仕組みです。タグが雑に運用されると「どのコミットで本番に出したバージョンか不明」という致命的トラブルを招きます。
多くの入門記事はgit tagの作成・削除までで終わっていますが、実務で本当に役立つのはSemVer設計・GPG署名・CI/CDトリガー・GitHub Releases連携・semantic-release自動化・モノレポ戦略まで含めた運用知識です。
この記事では、軽量タグ/注釈付きタグの違いから始めて、バージョン命名規則(SemVer/CalVer)、git describeによる自動バージョニング、gh releaseでのアセット配布、GitHub Actionsでタグpushをトリガーに自動デプロイする実例、semantic-releaseでConventional Commitsから自動タグ付けする最先端ワークフロー、モノレポでのpackage@1.0.0戦略、Protected tagによる保護設定、そして「タグが消えた」「同名タグで衝突」などのトラブル対処まで、2026年のリリース管理スタンダードを網羅します。
この記事で学べること
- 30秒で使えるタグ操作クイックリファレンス
- 軽量タグと注釈付きタグの本質的な違いと使い分け
- Semantic Versioning (SemVer)の設計ルールとpre-release運用
git tag -sでGPG署名し改ざんを防ぐ方法git describeでビルドごとに一意なバージョン文字列を自動生成- GitHub Releases連携(
gh release create/アセット配布) - タグpushをトリガーにデプロイするGitHub Actions実例
- semantic-releaseでConventional Commitsから自動タグ付け
- モノレポの
package@versionタグ戦略 - Protected tagで本番タグ改変を物理禁止する設定
- 「タグが消えた」「同名タグ衝突」「detached HEAD」などのトラブル対処
- 30秒で使えるタグ操作クイックリファレンス
- 軽量タグと注釈付きタグ:本質的な違い
- タグ作成と確認の完全リファレンス
- タグをリモートに送受信する
- タグの削除と「移動」:注意点だらけ
- Semantic Versioning (SemVer):プロが使うバージョン設計
- GPG署名タグで改ざんを防ぐ
- git describe:ビルドごとに一意なバージョン文字列を自動生成
- GitHub Releases連携:gh release create実践
- GitHub Actions:タグpushで自動デプロイ
- semantic-release:Conventional Commitsから自動タグ付け
- モノレポのタグ戦略:package@versionパターン
- Protected tag:本番タグを物理的に守る
- よくあるタグのトラブルと対処
- よくある質問
- 関連記事
- まとめ
30秒で使えるタグ操作クイックリファレンス
日常でよく使う操作を最初にまとめておきます。詳細は後述のセクションで深掘りします。
原則:リリース用途は必ず-a(注釈付き)か-s(署名)を使う。軽量タグは一時的なブックマーク用途限定。GitHubのReleasesを生成するには注釈付きタグが必要です。
軽量タグと注釈付きタグ:本質的な違い
Gitのタグには2種類あり、実体が根本的に違います。軽量タグは単なるコミットへのポインタ、注釈付きタグは独立したGitオブジェクトとして作者・日付・メッセージ・署名を保持します。
# 軽量タグの場合(コミットそのものが返る) $ git cat-file -t v0.1-light commit # 注釈付きタグの場合(tagオブジェクトが独立で存在) $ git cat-file -t v1.0.0 tag # 注釈付きタグのメタ情報 $ git cat-file -p v1.0.0 object 3a8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b type commit tag v1.0.0 tagger Taro Yamada <taro@example.com> 1737859200 +0900 Release 1.0.0 - 初回リリース
実務では注釈付きタグ(-aまたは-s)が事実上の標準
Git公式ドキュメントでもリリース用途は注釈付きタグを推奨。作者・日付・メッセージが残り、監査証跡として使える上、GitHub/GitLabのリリース機能と自然に連携します。軽量タグは個人の作業ブックマークや、スクリプトから一時的に付けるマーカーとして限定的に使用。
タグ作成と確認の完全リファレンス
さまざまなタイミングでタグを作る
# 現在のHEADに注釈付きタグ git tag -a v1.0.0 -m "Release 1.0.0" # 過去の特定コミットにタグ git tag -a v0.9.0 3a8b2c1 -m "Beta release" # タグメッセージを外部エディタで書く git tag -a v1.0.0 # GPG署名タグ(推奨) git tag -s v1.0.0 -m "Signed release 1.0.0" # 既存タグを強制上書き(非推奨/注意) git tag -f v1.0.0 # 軽量タグ(ブックマーク用途) git tag nightly-2026-04-21
タグの一覧とフィルタ
# 全タグ git tag # パターン指定 git tag -l "v1.*" git tag -l "v1.0.*" git tag -l "*-rc.*" # pre-releaseのみ # バージョン順で並べる git tag -l --sort=-v:refname | head -10 # 新しい順 # タグの詳細一覧(メッセージ付き) git tag -n5 # 含まれるコミットを元にフィルタ git tag --contains a1b2c3d # 該当コミットを含むタグ git tag --no-contains a1b2c3d # 含まないタグ # タグ同士の差分 git diff v1.0.0..v1.1.0 git log v1.0.0..v1.1.0 --oneline # コミット一覧(リリースノート元ネタ)
タグの詳細を見る
# タグの全情報(タグメッセージ+コミット+diff) git show v1.0.0 # タグを含むログ表示 git log --tags --oneline --graph # 特定タグから現在までのコミット git log v1.0.0..HEAD --oneline # 2つのタグ間の変更ファイル一覧 git diff --name-only v1.0.0 v1.1.0
タグメッセージはリリースノートの母体として扱うのが鉄則。git log v1.0.0..v1.1.0 --onelineの出力をそのままタグメッセージに貼り付けると、GitHub Releasesで自動的にリリースノート化されます。
タグをリモートに送受信する
タグはデフォルトでgit pushされないのが最大の落とし穴です。明示的にpushしないと「ローカルにしかタグが無い」状態になります。
# 特定タグだけpush(推奨:意図が明確) git push origin v1.0.0 # 全タグpush(大規模リポジトリでは避ける) git push origin --tags # pushの際にタグも自動でpushする設定 git config --global push.followTags true # → git pushすると関連タグも自動送信される # リモートのタグを全部取得 git fetch --tags # リモートに存在しないローカルタグを削除(整理) git fetch --prune --prune-tags
git push --tagsは全タグを送信するため、大量の古いタグや試験用タグが混ざっているリポジトリでは思わぬタグまで公開されます。リリースでは必ずgit push origin v1.0.0のように個別指定するか、push.followTags=true設定で関連タグだけ送るのが安全。
タグ取得時のよくあるエラー
# エラー例(リモートのタグとローカルのタグが別物) $ git fetch ! [rejected] v1.0.0 -> v1.0.0 (would clobber existing tag) # 解決:強制的にリモートのタグで上書き git fetch --tags --force # または該当タグだけ削除して再取得 git tag -d v1.0.0 git fetch origin tag v1.0.0
タグの削除と「移動」:注意点だらけ
タグは削除・移動できますが、公開済みタグを動かすのは重大なアンチパターンです。
削除の正規ルート
# ローカルで削除 git tag -d v1.0.0 # リモートで削除(新しい書き方) git push origin --delete v1.0.0 # リモートで削除(昔の書き方・現役で動く) git push origin :refs/tags/v1.0.0 # 両方一気に git tag -d v1.0.0 && git push origin --delete v1.0.0
タグの「移動」は強制上書き
# 同じ名前で別コミットに作り直す(ローカル) git tag -f v1.0.0 a1b2c3d # リモートに強制push(--forceが必須) git push origin v1.0.0 --force
公開済みタグを移動するのは実質”履歴の書き換え”です。他の開発者・CI/CD・Dockerイメージレジストリ・パッケージレジストリ(npm等)がそのタグを信頼して参照しているため、移動するとビルドの再現性が崩壊します。タグは不変(immutable)として運用するのが鉄則。間違えたら削除せず、v1.0.1 としてパッチリリースするのが正規フロー。
削除したタグを復元する
# ローカルのreflogから探す git reflog --all | grep v1.0.0 # コミットハッシュが分かれば復元 git tag -a v1.0.0 a1b2c3d -m "Restore v1.0.0" # リモートに残っていればfetchで戻る git fetch origin tag v1.0.0
Semantic Versioning (SemVer):プロが使うバージョン設計
タグ名にはルールがあります。業界標準のSemVer(semver.org)は、npm/Composer/Cargo/Goなど主要パッケージマネージャが採用しているバージョン体系です。
基本フォーマット
v<MAJOR>.<MINOR>.<PATCH>
例: v1.2.3
│ │ └── PATCH : 後方互換のバグ修正
│ └──── MINOR : 後方互換の機能追加
└────── MAJOR : 破壊的変更(API互換性が壊れる)
pre-release/build metadata
v1.0.0-alpha.1 # アルファ版 v1.0.0-beta.2 # ベータ版 v1.0.0-rc.1 # リリース候補 v1.0.0 # 正式リリース v1.0.0+20260421 # ビルドメタデータ(順序に影響しない) v1.0.0-rc.1+exp.sha.5114f85 # pre-release + メタ複合 # SemVerでの並び順 # 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0
v-prefix論争:vをつけるか否か
結論:つける派が圧倒的多数
- vを付ける派:Kubernetes/Docker/Go(公式ツール)/Linux kernelなど
- vを付けない派:npm(
package.jsonのversion欄はvなし)/SemVer仕様自体 - 実務では:Gitタグ名にはvを付ける(
v1.0.0)、package.jsonには付けない("version": "1.0.0") - 混在を避けるためチーム内でルールを明文化しCONTRIBUTING.mdに記載
MAJOR/MINOR/PATCHの判断基準
CalVer(Calendar Versioning)という選択肢
# 年.月.パッチ 2026.04.1 v2026.04.1 # 年.リリース番号 2026.3 # Ubuntu風 (YY.MM) 26.04
CalVerは破壊的変更の概念があいまいなOS・SaaS・フレームワークで採用されます(Ubuntu/JetBrains製品/pip等)。ライブラリ開発ではSemVer一択。
GPG署名タグで改ざんを防ぐ
git tag -sで作成した署名タグは、作成者本人が正規の鍵でサインした証拠を持つため、リリース配布や企業配信で改ざん検出の要として使われます。
GPG鍵を用意する
# 鍵を生成(対話式) gpg --full-generate-key # RSA/ED25519 → 4096 → 無期限 or 2年 → 名前・メール入力 # 鍵IDを確認 gpg --list-secret-keys --keyid-format=long # sec ed25519/AB12CD34EF567890 ... # Gitに署名鍵を登録 git config --global user.signingkey AB12CD34EF567890 git config --global tag.gpgSign true # デフォルトで署名 # 公開鍵をエクスポート(GitHub/GitLabに登録) gpg --armor --export AB12CD34EF567890
署名タグを作成・検証
# 署名タグ作成 git tag -s v1.0.0 -m "Signed release 1.0.0" # 署名付きかどうか確認 git tag -v v1.0.0 # gpg: Good signature from "Your Name <you@example.com>" # 署名が無いタグは弾く(厳格なリリース時) if ! git tag -v v1.0.0 2>/dev/null; then echo "ERROR: v1.0.0 is not signed" >&2 exit 1 fi
GitHubでは署名タグにVerifiedバッジが表示されます。Linux kernelやGnuPGなどセキュリティ重視のプロジェクトでは署名タグが必須。企業配布ではsignatureを検証しないCI/CDはサプライチェーン攻撃の入口になるため要注意。
git describe:ビルドごとに一意なバージョン文字列を自動生成
git describeは最も近いタグ+それ以降のコミット数+短縮ハッシュを連結したバージョン文字列を出力します。CI/CDや--version出力に最適です。
# 最も近い注釈付きタグを取得 $ git describe v1.0.0 # タグ以降にコミットがある場合 $ git describe v1.0.0-3-ga1b2c3d # └────┘ └─┘ └───────┘ # タグ 差分 shortハッシュ # 軽量タグも対象にする git describe --tags # dirty(未コミット変更あり)時は-dirtyを付与 git describe --dirty # → v1.0.0-3-ga1b2c3d-dirty # 最初に見つかるタグのみ(matchパターン) git describe --match "v*" --tags git describe --exclude "*-rc.*" # RCを除外 # タグ完全一致(タグが付いていないコミットはエラー) git describe --exact-match
ビルド時のバージョン埋め込み
# Makefile VERSION := $(shell git describe --tags --always --dirty) build: go build -ldflags "-X main.version=$(VERSION)" ./cmd/myapp # 実行時確認 $ ./myapp --version myapp v1.0.0-3-ga1b2c3d-dirty
package.jsonやVite/Webpackでの利用
# package.json scripts
{
"scripts": {
"version": "git describe --tags --always > src/version.txt"
}
}
# または環境変数
VITE_APP_VERSION=$(git describe --tags --always) npm run build
GitHub Releases連携:gh release create実践
GitHubのReleases機能はタグに紐づくページを自動生成し、ビルド成果物(アセット)の配布やリリースノートの公開を行えます。CLIのgh(GitHub CLI)を使えば完全自動化が可能です。
# タグを作ってpush git tag -a v1.0.0 -m "Release 1.0.0" git push origin v1.0.0 # GitHubでReleaseを作成(メモを自動生成) gh release create v1.0.0 --generate-notes # タイトル・本文を指定 gh release create v1.0.0 \ --title "v1.0.0 - 初回リリース" \ --notes "主な変更点..." # アセットをアップロード gh release create v1.0.0 \ --generate-notes \ dist/myapp-linux-amd64.tar.gz \ dist/myapp-windows-amd64.zip # pre-release(RC/ベータ) gh release create v1.0.0-rc.1 --prerelease --generate-notes # 下書き gh release create v1.0.0 --draft
リリースノートの自動生成ルール
# .github/release.yml
changelog:
exclude:
labels:
- ignore-for-release
categories:
- title: "新機能"
labels:
- enhancement
- title: "バグ修正"
labels:
- bug
- title: "その他"
labels:
- "*"
GitHub Actions:タグpushで自動デプロイ
タグが付いたタイミングをトリガーに、ビルド・テスト・配布・デプロイを完全自動化できます。手動デプロイのミスを排除する最重要パターンです。
name: Release
on:
push:
tags:
- 'v*.*.*'
- '!v*.*.*-*' # pre-releaseは別jobで
permissions:
contents: write # gh release createに必要
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # git describeのためタグ含め全履歴取得
- name: Get version
id: version
run: echo "tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
- name: Verify signed tag
run: git tag -v ${{ steps.version.outputs.tag }}
- name: Build
run: |
npm ci
npm run build
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "${{ steps.version.outputs.tag }}" \
--generate-notes \
dist/*.tar.gz
pre-release用の分岐ジョブ
on:
push:
tags:
- 'v*.*.*-rc.*'
- 'v*.*.*-beta.*'
jobs:
prerelease:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create prerelease
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create "${GITHUB_REF_NAME}" \
--prerelease \
--generate-notes
タグ運用の自動化パターン
- タグpush→ビルド→Docker Hub:Dockerタグも自動でv1.0.0に
- タグpush→npm publish:公開ライブラリの自動配布
- タグpush→本番デプロイ(EC2/ECS/Cloud Run)
- Release公開→Slack通知:リリース通知の自動化
semantic-release:Conventional Commitsから自動タグ付け
semantic-releaseはコミットメッセージを解析して次のバージョンを自動計算し、タグ作成・Release作成・CHANGELOG更新まで行うツール。人間がバージョン番号を決める手間をゼロにする現代的なアプローチです。
Conventional Commitsルール
feat: 新機能を追加 → MINORアップ fix: バグを修正 → PATCHアップ docs: ドキュメント変更のみ → バージョン据え置き chore: ビルド雑務など → バージョン据え置き refactor: リファクタ → バージョン据え置き # 破壊的変更(MAJORアップ) feat!: 新認証方式に変更 feat: 認証を刷新 BREAKING CHANGE: 認証方式を OAuth2 に統一
semantic-releaseの設定例
{
"scripts": {
"release": "semantic-release"
},
"release": {
"branches": ["main", { "name": "beta", "prerelease": true }],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]"
}
]
]
}
}
name: Semantic Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
semantic-releaseを使うとmainへのmergeだけで自動的にタグが切られ、Releaseが作成され、CHANGELOG.mdが更新されます。人間がバージョン番号を決める必要がなくなり、リリース漏れやミスが激減。ただしConventional Commits運用が前提なので、PRタイトル規約+PRタイトルリントの併用がおすすめ。
モノレポのタグ戦略:package@versionパターン
1つのリポジトリに複数パッケージを含むモノレポ(Turborepo/Nx/Rush)では、単純なv1.0.0ではどのパッケージのバージョンか分かりません。プレフィックス付きタグでパッケージを識別します。
# Lerna/Changesets系 @myorg/core@1.2.0 @myorg/cli@0.5.3 @myorg/ui@2.0.0-beta.1 # プレフィックスだけ core-v1.2.0 cli-v0.5.3 # フラット運用(全パッケージ同期) v2.0.0 # 全パッケージが2.0.0にそろう
パッケージごとのタグを絞り込む
# @myorg/core のタグ履歴 git tag -l "@myorg/core@*" # 最新タグ git tag -l "@myorg/core@*" --sort=-v:refname | head -1 # describe でcore専用の最近タグ git describe --match "@myorg/core@*" --tags
モノレポ自動化のおすすめ
- Changesets:パッケージごとにSemVer管理、PR単位でchangeファイル追加
- Lerna:
lerna publishでバージョンUP+タグ付与が一気通貫 - Nx Release:Nx公式のリリース機構、独立版/固定版を選べる
Protected tag:本番タグを物理的に守る
誤ったタグ移動や悪意ある書き換えから本番を守るには、GitHub/GitLabのProtected tag機能を使います。設定するだけで--forceや削除を禁止できます。
GitHubの設定手順
# 保護パターン例 v*.*.* # 全SemVerタグ v*.*.* & !*-rc.* # rc除くすべての正式版 # 保護されると: # - タグの作成は指定ロールのみ # - タグの削除・force pushが禁止
GitLabの設定
# Settings → Repository → Protected tags Tag: v* Allowed to create: Maintainers
本番リリース用タグ(v*.*.*)は必ず保護。RCや試験用タグは保護せず柔軟に運用するのが実用的。保護設定はSettingsから5分で完了するので、リポジトリ立ち上げ時の初期設定タスクに組み込むと事故を未然に防げます。
よくあるタグのトラブルと対処
pushしたつもりが反映されない
# ダメな例:コミットと一緒にpushしたつもり git commit -am "Release 1.0.0" git tag v1.0.0 git push # ← タグはpushされない! # 正しい方法 git push origin v1.0.0 # または push.followTagsを有効化しておく git config --global push.followTags true
detached HEADになった
# タグをcheckoutするとdetached HEAD git switch --detach v1.0.0 # → HEAD is now at a1b2c3d Release 1.0.0 # この状態でコミットするとどのブランチにも紐づかない # → hotfix/パッチリリースしたい場合はブランチを切る git switch -c hotfix/v1.0.1 v1.0.0
タグ自体は移動できますがコミット履歴の分岐を作るにはブランチ化が必要です。「v1.0.0の地点からバグ修正→v1.0.1リリース」ならgit switch -c hotfix/v1.0.1 v1.0.0でhotfixブランチを作り、修正後にgit tag -a v1.0.1 -m "..."。detached HEADからの詳細復帰は【Git】detached HEAD状態から元の作業ブランチに戻す方法で解説しています。
タグ名を間違えた
# v1.00 → v1.0.0 に改名したい # 1) 新しいタグを同じコミットに付ける git tag -a v1.0.0 v1.00 -m "Release 1.0.0" # 2) 旧タグをローカル・リモート両方削除 git tag -d v1.00 git push origin --delete v1.00 # 3) 新タグをpush git push origin v1.0.0
CIが古いタグでビルドしてしまう
actions/checkoutはデフォルトで浅いクローン(fetch-depth: 1)のため、git describeが古いタグしか見つけられないケースがあります。タグ情報を完全に取得するにはfetch-depth: 0とfetch-tags: trueを指定。
- uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
よくある質問
-a)またはGPG署名タグ(-s)。軽量タグは一時的なブックマークや、個人の作業マーカーに限定します。GitHubのReleases機能は注釈付きタグ前提で動作するため、迷ったら-aにしておけば後悔しません。vを付けるべき?v1.2.3)。Kubernetes/Docker/Linuxカーネル/Goツールなど主要OSSはほぼ全てvあり。ただしnpmのpackage.jsonの"version"フィールドには付けない("1.2.3")。タグと内部バージョン文字列で扱いが違う点に注意。git log --onelineで対象コミットのハッシュを確認し、git tag -a v1.0.0 <ハッシュ> -m "Release 1.0.0"で付与。その後git push origin v1.0.0でリモートへ反映。git push origin v1.0.0で戻る。②リモートに残っていればgit fetch origin tag v1.0.0で取得。③どちらにも無ければgit reflog --all | grep v1.0.0でコミットを探し、同じコミットに再度git tag -aで付与。GitHubではAdminが90日以内の削除タグをサポートに依頼して復旧できる場合もある。v1.0.0-alpha.1→v1.0.0-beta.1→v1.0.0-rc.1→v1.0.0。識別子はalpha < beta < rcの順序が暗黙慣習。ドット区切りで番号を増やします(rc.1→rc.2)。on.push.tagsにパターン指定し、docker/build-push-actionを使うのが定番です。${{ github.ref_name }}でタグ名を取得し、Docker tagに使用。さらにdocker/metadata-actionを使うとv1.2.3、v1.2、v1、latestを自動生成できます。v1.0.1)を発行」。公開タグは不変(immutable)として扱い、再リリースで問題を解決するのがSemVerの哲学です。関連記事
- 【Git】よく使うgitコマンド決定版チートシート — tag操作を含む日常コマンド早見表
- 【Git】rebaseとmergeの違いと使い分け完全ガイド — リリース前の履歴整形に活用
- 【Git】detached HEAD状態から元の作業ブランチに戻す方法 — タグ参照時の落とし穴
- 【Git】pushを取り消す方法 — タグpush事故時のリカバリ
- 【Git】ブランチを削除する方法 — リリース後のブランチ整理
- 【Git】コミットメッセージの変更方法 — リリース前の履歴整形
- 【Git】pull後にマージコミットが大量発生する原因と履歴整理方法 — リリース前の履歴クリーンアップ
- 【Git】rebase中のエラー完全復旧ガイド — リリース前のrebase安全運用
まとめ
- リリース用途は注釈付きタグ(
-a)か署名タグ(-s)。軽量タグは一時ブックマーク用 - タグは自動pushされない。
git push origin v1.0.0またはpush.followTags=true設定 - 命名はSemVer(
v1.2.3)が業界標準。pre-releaseはv1.0.0-rc.1形式 - 改ざん対策はGPG署名タグ+
git tag -v検証。企業配布では必須 git describe --tags --dirtyでビルドごとに一意なバージョン文字列を自動生成- GitHub Actions+
gh release createでタグpushを起点に完全自動リリース - semantic-releaseとConventional Commitsでバージョン決定を自動化
- モノレポは
@org/pkg@1.0.0スタイルでパッケージ識別 - 本番タグはProtected tag設定で移動・削除を物理禁止
- 公開タグは不変(immutable)として扱い、間違えたら再リリースで解決
タグは「コミットにラベルを付ける」以上の意味を持ち、リリース管理・CI/CD・サプライチェーンセキュリティ・バージョン決定の自動化を支える基盤です。SemVer+注釈付きタグ+署名+Protected tag+GitHub Actions自動化、そしてモノレポではpackage@version戦略——これらを組み合わせれば、リリース作業は「mainへmergeするだけ」にまで自動化できます。2026年のGit運用では、タグはもはや手動管理するものではなく、自動化パイプラインで守り抜く成果物です。

