Git入門:バージョン管理のきほん
タグでリリースに印をつける
このレッスンで分かること
- タグが「動かない目印」であることと、ブランチとの決定的な違い
- 軽量タグと注釈付きタグの使い分け、v1.2.3 というバージョン番号の読み方
- タグを push し忘れて共有されない事故と、その直し方
タグは動かない目印
ここまでのレッスンでブランチを扱ってきました。ブランチは、新しいコミットを作るたびに先端が前へ進みます。main で 3 回コミットすれば、main が指す場所は 3 回移動します。
タグはその逆です。あるコミットに名前をつけたら、そのあと何回コミットしても、タグは最初につけたコミットを指し続けます。動かない目印です。
これが役に立つのは、リリースの瞬間を残したいときです。「お客さまに公開したのは、あのときのこの状態です」と後から特定できることには実務上の価値があります。バグ報告を受けたときに、報告者が使っているバージョンのコードをそのまま手元に再現できます。
コミットのハッシュ (9f3c1a2f...) でも同じことはできますが、人間はハッシュを覚えられません。「v1.2.0 で入ったバグ」と言えば全員に通じますが、「9f3c1a2 で入ったバグ」と言われて分かる人はいません。タグは、機械にしか読めない番号に人間の言葉を貼り付ける仕組みです。
| 目印 | 動くか | 主な用途 |
|---|---|---|
| ブランチ | 進む | 作業中の場所を指す |
| タグ | 動かない | 公開した時点を残す |
HEAD | 進む | いま自分がいる場所を指す |
HEAD はここまで何度か出てきましたが、いま自分がチェックアウトしている場所を指す特別な目印です。タグの話でも、HEAD は「現在地」として登場します。
タグを作ってみる
まずいちばん単純な作り方から見ます。
ターミナル
$ git tag v0.1.0これで、いま HEAD がいるコミットに v0.1.0 という名前がつきました。何も出力されないのが成功のしるしです。
一覧を見ます。
ターミナル
$ git tag
v0.1.0過去のコミットに後からつけることもできます。コミットのハッシュを指定します。
ターミナル
$ git log --oneline
9f3c1a2 (HEAD -> main) ログイン画面のバリデーションを追加
4b8d0e7 ユーザー登録 API を実装
1a2b3c4 プロジェクトの初期設定
$ git tag v0.0.1 1a2b3c4タグがついたコミットは git log にも表示されます。
ターミナル
$ git log --oneline
9f3c1a2 (HEAD -> main, tag: v0.1.0) ログイン画面のバリデーションを追加
4b8d0e7 ユーザー登録 API を実装
1a2b3c4 (tag: v0.0.1) プロジェクトの初期設定タグが増えてきたら、絞り込んで一覧します。-l にパターンを渡します。
ターミナル
$ git tag -l "v1.*"
v1.0.0
v1.1.0
v1.1.1作業に集中していると、いま自分がいるコミットが最後のリリースからどれだけ進んだのかが分からなくなります。git describe が教えてくれます。
ターミナル
$ git describe --tags
v1.0.0-12-g9f3c1a2これは「直近のタグは v1.0.0、そこから 12 コミット進んでいて、いまのコミットは 9f3c1a2」という意味です。先頭の g は Git を表す記号で、ハッシュの一部ではありません。
軽量タグと注釈付きタグ
さきほど作った v0.1.0 は軽量タグと呼ばれるものです。中身は、コミットのハッシュを書いたただのファイルです。それ以上の情報を持ちません。
もうひとつ、注釈付きタグがあります。-a と -m をつけて作ります。
ターミナル
$ git tag -a v1.0.0 -m "初回リリース"注釈付きタグは、Git の中でコミットと同じくひとつの独立したオブジェクトとして保存されます。そこには作成者の名前とメールアドレス、作成日時、メッセージが入ります。
違いは git show で確認できます。まず注釈付きタグです。
ターミナル
$ git show v1.0.0
tag v1.0.0
Tagger: Taro Yamada <taro@example.com>
Date: Mon Mar 3 10:12:44 2025 +0900
初回リリース
commit 9f3c1a2f8e6d5c4b3a2918f7e6d5c4b3a2918f7e (tag: v1.0.0)
Author: Taro Yamada <taro@example.com>
Date: Mon Mar 3 09:58:12 2025 +0900
ログイン画面のバリデーションを追加軽量タグだと、タグ自身の情報は出ません。いきなりコミットの情報から始まります。
ターミナル
$ git show v0.1.0
commit 9f3c1a2f8e6d5c4b3a2918f7e6d5c4b3a2918f7e (tag: v0.1.0)
Author: Taro Yamada <taro@example.com>
Date: Mon Mar 3 09:58:12 2025 +0900
ログイン画面のバリデーションを追加| 種類 | 作り方 | 記録される情報 | 向いている場面 |
|---|---|---|---|
| 軽量タグ | git tag v0.1.0 | コミットの位置だけ | 自分用の一時的な目印 |
| 注釈付きタグ | git tag -a v1.0.0 -m "..." | 作成者・日時・メッセージ | 公開するリリース |
公開するリリースには注釈付きタグを使ってください。半年後に「このバージョンは誰がいつ出したのか」を調べる場面が必ず来ます。そのとき軽量タグだと何の手がかりも残っていません。
v1.2.3 という番号の読み方
タグの名前は自由につけられますが、多くのプロジェクトはセマンティックバージョニングという共通の決まりに従っています。v1.2.3 の 3 つの数字にはそれぞれ意味があります。
| 位置 | 呼び名 | 上げるとき |
|---|---|---|
| 1 (メジャー) | major | 使い方が変わって、そのままでは動かなくなる変更 |
| 2 (マイナー) | minor | 機能が増えたが、これまでの使い方はそのまま動く |
| 3 (パッチ) | patch | バグ修正だけ。使い方は何も変わらない |
具体例で見ます。v1.2.3 から次に進む場合を考えます。
- ボタンの色を直すバグ修正だけ →
v1.2.4 - 検索機能を新しく追加した。既存の画面はそのまま動く →
v1.3.0 - 設定ファイルの書式を変えたので、古い設定では起動しない →
v2.0.0
メジャーが上がるときだけ、右の数字はゼロに戻ります。v1.3.0 の次にメジャーを上げるなら v2.0.0 であって v2.3.0 ではありません。
この決まりが役に立つのは、他人のライブラリを使うときです。v1.2.3 から v1.2.9 への更新は安心して当てられますが、v2.0.0 への更新は自分のコードを直す必要があるかもしれない、と番号だけで判断できます。
正式公開の前に試験的な版を出したいときは、うしろにハイフンで印をつけます。v1.0.0-beta.1 や v2.0.0-rc.1 のような形です。この印がついたものは、番号の順序としては v1.0.0 より前に来る扱いになります。まだ本番ではない、というしるしです。
数字の頭に
vをつけるかどうかは、プロジェクトによって分かれます。どちらでも構いませんが、途中で変えないでください。v1.0.0と1.1.0が混ざったタグ一覧は非常に読みにくくなります。
タグを共有する
ここがいちばんの落とし穴です。
タグは git push では送られません。ブランチのコミットだけが送られ、タグは手元に残ったままになります。
origin は、手元のリポジトリが覚えているリモート先の別名です。多くの場合 GitHub 上のリポジトリを指しています。タグを送るには、この origin に対してタグ名を明示します。
ターミナル
$ git push origin v1.0.0
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 168 bytes | 168.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:example/myapp.git
* [new tag] v1.0.0 -> v1.0.0複数のタグをまとめて送るなら次の通りです。
ターミナル
$ git push origin --tagsやりがちな失敗
よくあるのは次の流れです。手元で git tag -a v1.0.0 -m "初回リリース" を打ち、git push をして、GitHub のリリース一覧を開いても何も出てこない。「タグを作ったのに消えた」と思い込む。
消えてはいません。手元にはあります。確認してみます。
ターミナル
$ git tag
v0.1.0
v1.0.0リモート側に何があるかは、別のコマンドで見ます。
ターミナル
$ git ls-remote --tags origin
9f3c1a2f8e6d5c4b3a2918f7e6d5c4b3a2918f7e refs/tags/v0.1.0v1.0.0 がありません。送っていないからです。git push origin v1.0.0 を打てば解決します。
もうひとつの事故は、名前を間違えたタグを送ってしまう場合です。v1.0.0 のつもりが v.1.0.0 になっていた、というような取り違えです。この場合は手元とリモートの両方から消します。
ターミナル
$ git tag -d v.1.0.0
Deleted tag 'v.1.0.0' (was 9f3c1a2)
$ git push origin --delete v.1.0.0
To github.com:example/myapp.git
- [deleted] v.1.0.0すでに他の人が取り込んだタグを消したり、同じ名前で付け直したりするのは避けてください。相手の手元には古いタグが残り続け、同じ名前が別のコミットを指す状態になります。間違えたと気づいたら、消すより新しい番号で付け直すほうが安全です。
タグの時点に戻って確認する
過去のリリースの中身を見たいときは、タグ名を指定してチェックアウトします。
ターミナル
$ git checkout v1.0.0
Note: switching to 'v1.0.0'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.detached HEAD と出ますが、壊れたわけではありません。HEAD がブランチではなくコミットを直接指している状態です。中身を眺めるだけならこのままで問題ありません。
戻るときはブランチ名を指定します。
ターミナル
$ git switch mainこのタグの時点から修正版を出したい場合は、ブランチを切ってから作業します。
ターミナル
$ git switch -c hotfix-1.0.1 v1.0.0これで v1.0.0 の状態を起点にした新しいブランチができました。ここで修正をコミットし、v1.0.1 のタグを付けてリリースする、という流れになります。
GitHub のリリースとの関係
GitHub には Releases という画面があります。ここに並んでいるのは、実はタグそのものです。タグを push すると、GitHub 側では自動的にタグの一覧に載ります。
Releases 画面でできるのは、そのタグに対して説明文や配布用のファイルを追加することです。つまり Git のタグが土台にあり、GitHub がその上に表示用の情報を足している構造です。
| 場所 | 実体 | 誰が作るか |
|---|---|---|
| Git のタグ | コミットへの目印 | git tag で自分が作る |
| GitHub の Releases | タグ + 説明文 + 添付ファイル | GitHub の画面で追記する |
この関係が分かっていると、「Releases に出てこない」という相談のほとんどがタグの push 忘れだと判断できます。GitHub 側の設定を疑う前に、まず git ls-remote --tags origin を打ってください。
実務では、次の順番で進めるのが素直です。
- リリースしたい内容が
mainに全部入っていることを確認する git switch mainとgit pullで手元を最新にするgit tag -a v1.2.0 -m "検索機能を追加"でタグを打つgit push origin v1.2.0で送る- GitHub の Releases で説明文を書く
3 番の前に 2 番を必ず入れてください。手元が古い状態でタグを打つと、リリースしたつもりのない古いコミットに v1.2.0 がついてしまいます。
- タグはコミットにつける動かない目印で、ブランチと違って新しいコミットを作っても移動しない
- 公開するリリースには注釈付きタグ (
git tag -a) を使う。作成者・日時・メッセージが記録に残る v1.2.3はメジャー・マイナー・パッチの順。壊れる変更でメジャー、機能追加でマイナー、バグ修正でパッチを上げる- タグは
git pushでは送られない。git push origin v1.0.0で明示的に送る