Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12418] ファイルの概要

このコミットは、Go言語のビルドシステムの一部である cmd/dist ツールにおいて、Goのバージョン情報を取得する際に使用されるMercurial (Hg) コマンドの引数を修正するものです。具体的には、go version コマンドが報告するバージョン情報が、現在のビルド対象のリビジョンに正確に対応するよう、Mercurialのタグ検索方法を改善しています。

コミット

commit 36708a40e0511d7654f30615e9ca4452a4d90cc4
Author: Alex Brainman <alex.brainman@gmail.com>
Date:   Tue Mar 6 17:21:39 2012 +1100

    cmd/dist: use correct hg tag for go version
    
    When looking for suitable tag always start
    from current version, not the tip.
    
    R=minux.ma, rsc
    CC=golang-dev
    https://golang.org/cl/5731059

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/36708a40e0511d7654f30615e9ca4452a4d90cc4

元コミット内容

cmd/dist: use correct hg tag for go version

「Goのバージョンに正しいhgタグを使用する」

When looking for suitable tag always start from current version, not the tip.

「適切なタグを探す際には、常に現在のバージョンから開始し、tip(最新のリビジョン)からではない。」

変更の背景

Go言語のビルドプロセスでは、go version コマンドで表示されるバージョン情報を決定するために、ソースコードリポジトリ(当時はMercurial)のタグ情報が利用されていました。しかし、従来のMercurialコマンドの呼び出し方では、現在のビルド対象となっているリビジョンに直接関連するタグではなく、ブランチの最新リビジョン("tip")からタグを検索していました。

このアプローチには問題がありました。例えば、開発者が特定の過去のリビジョンをチェックアウトしてビルドした場合や、ブランチのtipにまだタグが付けられていない場合、go version が報告する情報が、実際にビルドされたコードベースのバージョンと一致しない可能性がありました。これは、デバッグやバージョン管理において混乱を招く原因となります。

このコミットは、この問題を解決し、go version が常にビルド対象の正確なバージョンを反映するようにするために行われました。

前提知識の解説

Goのビルドシステム (cmd/dist)

cmd/dist は、Go言語のソースコードからGoツールチェイン(コンパイラ、リンカ、標準ライブラリなど)をビルドするための内部ツールです。Goのソースツリーのルートにある make.bash (Unix系) や make.bat (Windows) スクリプトによって呼び出され、Goのビルドプロセス全体を管理します。このツールは、Goのバージョン情報をビルドされたバイナリに埋め込む役割も担っています。

Mercurial (Hg)

Mercurialは、Gitと同様の分散型バージョン管理システムです。Goプロジェクトは、初期にはMercurialを主要なバージョン管理システムとして使用していました(後にGitに移行しました)。Mercurialでは、リビジョンに意味のある名前(タグ)を付けることができ、特定のリリースバージョンなどを識別するために利用されます。

hg log コマンド

hg log はMercurialのリポジトリ履歴を表示するためのコマンドです。このコマンドには様々なオプションがあり、表示するリビジョンや情報の形式を制御できます。

  • -b <branch>: 特定のブランチのリビジョンのみを表示します。
  • --template <template>: 出力フォーマットをカスタマイズするためのオプションです。{tags} のようなキーワードを使用することで、リビジョンに付与されたタグ情報を取得できます。
  • -r <revision_range>: ログを表示するリビジョンの範囲を指定します。
    • . (ドット): 現在の作業ディレクトリに対応するリビジョンを指します。
    • 0: リポジトリの最初のリビジョン(ルートリビジョン)を指します。
    • .:0: 現在のリビジョンからリビジョン0まで(つまり、現在のリビジョンから履歴を遡ってリポジトリの最初まで)のすべてのリビジョンを意味します。

Goのバージョン情報

go version コマンドを実行すると、現在インストールされているGoのバージョン情報が表示されます。この情報は、Goのバイナリがビルドされる際に埋め込まれるもので、通常はGoのリリースバージョン(例: go1.0.3)や、開発版の場合はコミットハッシュなどが含まれます。この情報が正確であることは、開発者が使用しているGoの環境を正確に把握し、問題報告や互換性の確認を行う上で非常に重要です。

技術的詳細

このコミットの技術的な核心は、src/cmd/dist/build.c ファイル内の findgoversion 関数における hg log コマンドの呼び出し方法の変更です。

変更前は、hg log コマンドは -b <branch>--template "{tags} + " オプションを使用していました。これは、指定されたブランチのすべてのリビジョンを対象に、それぞれのタグ情報を取得しようとするものです。しかし、この方法では、Mercurialがタグを検索する際に、必ずしも現在の作業リビジョンに最も関連性の高いタグを優先するとは限りませんでした。特に、ブランチの「tip」にタグがない場合や、現在のリビジョンがtipから離れている場合に、意図しないタグが選択される可能性がありました。

変更後、hg log コマンドに新たに -r ".:0" オプションが追加されました。このオプションは、Mercurialに対して「現在のリビジョン (.) からリポジトリの最初のリビジョン (0) まで」の範囲でログを検索するように指示します。これにより、findgoversion 関数は、現在のビルド対象となっているリビジョンからその祖先を遡り、そのパス上で見つかる最も適切なタグを確実に取得できるようになります。

この変更により、go version コマンドは、ビルドされたGoツールチェインが実際にどのソースリビジョンから派生したのかを、より正確に反映するようになります。これは、特に開発版のGoを使用しているユーザーにとって、自身の環境のバージョンを正確に把握するために不可欠な改善です。

コアとなるコードの変更箇所

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -209,7 +209,7 @@ findgoversion(void)
 	// What are the tags along the current branch?
 	tag = "";
 	rev = ".";
-\trun(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "--template", "{tags} + ", nil);\n+\trun(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "-r", ".:0", "--template", "{tags} + ", nil);\n \tsplitfields(&tags, bstr(&b));
 \tnrev = 0;
 \tfor(i=0; i<tags.len; i++) {

コアとなるコードの解説

変更は src/cmd/dist/build.c ファイル内の findgoversion 関数にあります。この関数は、Goのバージョン情報を決定するためにMercurialコマンドを実行しています。

元のコード:

run(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "--template", "{tags} + ", nil);

この行は、hg log コマンドを実行し、指定されたブランチ (bstr(&branch)) のログからタグ情報を取得しようとしていました。しかし、リビジョンの範囲が指定されていないため、Mercurialはブランチ全体のログを検索し、その中でタグを見つけようとします。この挙動が、現在のビルドリビジョンに正確に対応するタグを見つけられない原因となっていました。

変更後のコード:

run(&b, goroot, CheckExit, "hg", "log", "-b", bstr(&branch), "-r", ".:0", "--template", "{tags} + ", nil);

この変更では、hg log コマンドの引数に新たに -r ".:0" が追加されています。

  • -r: リビジョン範囲を指定するオプションです。
  • ".:0": これはMercurialのリビジョン指定構文で、「現在のリビジョン (.) からリポジトリのルートリビジョン (0) まで」の範囲を意味します。

この追加により、hg log は現在のビルドが行われているリビジョンから、その履歴を遡ってタグを検索するようになります。これにより、findgoversion 関数は、現在のコードベースに最も関連性の高いタグを正確に特定し、go version コマンドが正しいバージョン情報を報告できるようになります。

関連リンク

参考にした情報源リンク