[インデックス 19482] ファイルの概要
このコミットは、Go言語のビルドツールであるcmd/dist
におけるバージョン文字列の生成ロジックの変更に関するものです。具体的には、go version
コマンドで表示されるバージョン文字列において、ベータ版タグ(beta
)が不適切に表示され続ける問題を修正しています。Go 1.3のリリース後も、その後のリビジョンでgo1.3beta2
のようなベータ版タグが表示されるのを防ぐための変更です。
コミット
commit 300f3c4913188c1c40b8ff91235e50d886c0d7ed
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Jun 2 08:48:20 2014 +1000
cmd/dist: only use beta tag in version string for the exact revision
Right now, any revision on the default branch after go1.3beta2 is
described by "go verson" as go1.3beta2 plus some revision.
That's OK for now, but once go1.3 is released, that will seem wrong.
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/98650046
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/300f3c4913188c1c40b8ff91235e50d886c0d7ed
元コミット内容
cmd/dist: only use beta tag in version string for the exact revision
Right now, any revision on the default branch after go1.3beta2 is
described by "go verson" as go1.3beta2 plus some revision.
That's OK for now, but once go1.3 is released, that will seem wrong.
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/98650046
変更の背景
Go言語のリリースプロセスでは、正式リリース前にベータ版が公開されます。例えば、Go 1.3の正式リリースに先立ってgo1.3beta1
、go1.3beta2
といったベータ版が提供されます。go version
コマンドは、現在使用しているGoのバージョン情報を表示しますが、この情報にはGitリビジョンやタグが含まれることがあります。
このコミットが作成された時点では、go1.3beta2
タグが付けられたリビジョン以降のすべてのリビジョンにおいて、go version
の出力が「go1.3beta2
+ その後のリビジョン情報」という形式になっていました。これは、ベータ版の期間中は問題ありませんが、Go 1.3が正式にリリースされた後も、その後の開発ブランチ上のリビジョンが「go1.3beta2
+ ...」と表示されるのは不適切であり、混乱を招く可能性がありました。
この変更の目的は、ベータ版タグがバージョン文字列に含まれるのは、そのベータ版タグが付けられた正確なリビジョンである場合に限定することです。これにより、正式リリース後の開発ブランチでは、ベータ版タグがバージョン文字列から除外され、より正確なバージョン情報が提供されるようになります。
前提知識の解説
cmd/dist
とは
cmd/dist
は、Go言語のソースコードからGoツールチェイン自体をビルドするためのコマンドラインツールです。Goのコンパイラ、リンカ、標準ライブラリなど、Go開発に必要なすべてのコンポーネントを構築する役割を担っています。go install
やgo build
といったコマンドがユーザーのGoプログラムをビルドするのに対し、cmd/dist
はGo言語のランタイムやツールをビルドする、より低レベルなツールです。
cmd/dist
の内部には、Goのバージョン情報を決定し、それをビルドされたツールに埋め込むためのロジックが含まれています。このバージョン情報は、go version
コマンドを実行した際に表示される文字列の元となります。
Goのバージョン管理とリリースサイクル
Go言語は、約6ヶ月ごとに新しいメジャーバージョンをリリースする、時間ベースのリリースサイクルを採用しています。各リリースサイクルには、開発フェーズと、テストおよび品質向上に特化した「リリースフリーズ」期間が含まれます。
- メジャーバージョン (例: Go 1.x): 新しい機能や改善が含まれます。Go 1以降は後方互換性が重視されており、既存のコードが新しいGoバージョンで動作しなくなることは稀です。
- マイナーバージョン (例: Go 1.x.y): 主にバグ修正やセキュリティパッチのためにリリースされます。
- ベータ版 (例: Go 1.xbetaN): 正式リリース前に、新しいメジャーバージョンのテストとフィードバック収集のために公開されます。
- リリース候補版 (例: Go 1.xrcN): ベータ版の後にリリースされ、正式リリースに非常に近い状態です。
go version
コマンドは、現在インストールされているGoのバージョンを表示します。開発中のGoのバージョンでは、Gitリビジョン情報や、ベータ版、リリース候補版といったタグが付加されることがあります。
findgoversion
関数
src/cmd/dist/build.c
内のfindgoversion
関数は、Goのバージョン文字列を決定する中心的な役割を担っています。この関数は、Gitリポジトリのタグ情報やコミット履歴を解析し、現在のリビジョンに最も近いバージョンタグ(例: go1.3
、go1.3beta2
など)を特定します。そして、そのタグからのコミット数(nrev
)や、現在のリビジョンがクリーンであるかどうか(変更がないか)などの情報を組み合わせて、最終的なバージョン文字列を生成します。
技術的詳細
このコミットは、src/cmd/dist/build.c
ファイル内のfindgoversion
関数におけるバージョン文字列生成ロジックを変更しています。
変更前のコードでは、findgoversion
関数がGitタグを走査する際に、hasprefix(p, "go")
という条件でGoのバージョンタグを識別していました。そして、コメントアウトされたhasprefix(p, "weekly.")
の部分は、かつてweekly
タグを考慮していた名残です。重要なのは、この条件に加えて、contains(p, "beta")
のようなベータ版タグの有無をチェックするロジックが不十分であったことです。
具体的には、変更前のコードは以下のようになっていました。
// NOTE: Can reenable the /* */ code when we want to
// start reporting versions named 'weekly' again.
if(/*hasprefix(p, "weekly.") ||*/ hasprefix(p, "go")) {
tag = xstrdup(p);
// ...
}
このロジックでは、go1.3beta2
のようなタグが見つかると、そのタグがtag
変数に設定されます。その後、現在のリビジョンがそのタグからどれだけ離れているかを示すnrev
(リビジョン数)が計算されます。問題は、go1.3beta2
タグが付けられたリビジョン以降のすべてのリビジョンで、tag
がgo1.3beta2
に設定され、それに+
とnrev
が追加されてしまうことでした。例えば、Go 1.3の正式リリース後に、go1.3beta2+100
のようなバージョン文字列が表示されることになります。
変更後のコードでは、この条件が以下のように修正されました。
// Only show the beta tag for the exact revision.
if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) {
tag = xstrdup(p);
// ...
}
この新しい条件は、以下の2つの部分から構成されています。
hasprefix(p, "go")
: これは以前と同様に、Goのバージョンタグであることを確認します。(!contains(p, "beta") || nrev == 0)
: この部分が変更の核心です。!contains(p, "beta")
: 現在のタグp
が「beta」を含まない場合、この条件は真となり、そのタグが採用されます。これは、正式リリース版のタグ(例:go1.3
)を優先的に選択するためのものです。nrev == 0
: 現在のタグp
が「beta」を含んでいても、nrev
が0である場合(つまり、現在のリビジョンがそのベータ版タグと完全に一致する場合)、この条件は真となり、そのベータ版タグが採用されます。
この論理和(||
)により、以下のいずれかの条件が満たされた場合にのみ、タグがtag
変数に設定されるようになります。
- タグがベータ版ではない(例:
go1.3
)。 - タグがベータ版であるが、現在のリビジョンがそのベータ版タグと完全に一致する(
nrev == 0
)。
これにより、go1.3beta2
がリリースされた後、そのリビジョンから少しでも進んだリビジョン(nrev > 0
)では、go1.3beta2
のようなベータ版タグがバージョン文字列に採用されなくなります。代わりに、より適切な(例えば、正式リリース版の)タグが選択されるか、あるいはタグが見つからない場合はリビジョン情報のみが表示されるようになります。
コアとなるコードの変更箇所
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -290,9 +290,8 @@ findgoversion(void)
tp = tags.p[i];
if(streq(p, "+"))
nrev++;
- // NOTE: Can reenable the /* */ code when we want to
- // start reporting versions named 'weekly' again.
- if(/*hasprefix(p, "weekly.") ||*/ hasprefix(p, "go")) {
+ // Only show the beta tag for the exact revision.
+ if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) {
tag = xstrdup(p);
// If this tag matches the current checkout
// exactly (no "+" yet), don't show extra
コアとなるコードの解説
変更された行は、findgoversion
関数内のif
文の条件式です。
-
変更前:
if(/*hasprefix(p, "weekly.") ||*/ hasprefix(p, "go")) {
この条件は、タグ
p
が"go"
で始まる場合に真となります。これにより、go1.3beta2
のようなベータ版タグも無条件に採用され、その後のリビジョンでもこのタグがベースとなってバージョン文字列が生成されていました。コメントアウトされたweekly
に関する部分は、過去のバージョン管理スキームの名残です。 -
変更後:
if(hasprefix(p, "go") && (!contains(p, "beta") || nrev == 0)) {
この新しい条件式は、以下の論理積(
&&
)と論理和(||
)を組み合わせています。hasprefix(p, "go")
: タグが"go"
で始まることを確認します。これは必須条件です。(!contains(p, "beta") || nrev == 0)
: この部分がベータ版タグの扱いを制御します。!contains(p, "beta")
: タグが"beta"
という文字列を含まない場合(例:go1.3
)。この場合、そのタグは正式リリース版のタグと見なされ、採用されます。nrev == 0
: タグが"beta"
を含んでいても、現在のリビジョンがそのタグと完全に一致する場合(つまり、そのベータ版タグが付けられたコミットそのものである場合)。この場合も、そのベータ版タグが採用されます。
この変更により、go version
コマンドの出力は、ベータ版タグが付けられた正確なリビジョンでのみベータ版タグを表示し、それ以降のリビジョンではベータ版タグを含まない、より適切なバージョン文字列を生成するようになります。これにより、Goの正式リリース後の開発ブランチにおけるバージョン表示の正確性が向上しました。
関連リンク
- Go言語の公式ウェブサイト: https://go.dev/
- Go言語のリリース情報: https://go.dev/doc/devel/release
- Go Modulesのバージョン管理に関するドキュメント: https://go.dev/blog/using-go-modules (Go ModulesはGo 1.11で導入されたため、このコミットの時点では直接関連しませんが、Goのバージョン管理の概念を理解する上で参考になります)
参考にした情報源リンク
- GitHub: golang/go repository: https://github.com/golang/go
- Goの
cmd/dist
に関するウェブ検索結果 - Goのバージョン管理に関するウェブ検索結果
- Goのソースコード (
src/cmd/dist/build.c
) - Goのコードレビューシステム (Gerrit): https://go.googlesource.com/go/+/refs/heads/master/src/cmd/dist/build.c (このコミットのChange-ID:
98650046
に対応するGerritのリンクは、コミットメッセージに記載されています:https://golang.org/cl/98650046
)