[インデックス 11357] ファイルの概要
このコミットは、Go言語のcmd/go
ツールにおけるgo get
コマンドがGitHubリポジトリを正しく取得できない問題を修正するものです。具体的には、github.com
プレフィックスを持つパスに対して、明示的にバージョン管理システム(VCS)としてGitを指定することで、go get
がGitHubリポジトリを適切にクローンできるようにします。
コミット
commit 59ae15106a2ae0a409f710a16a8180ae81f81a3d
Author: Russ Cox <rsc@golang.org>
Date: Tue Jan 24 14:15:37 2012 -0500
cmd/go: fix get github
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5569054
---
src/cmd/go/vcs.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index b2abd988a4..074d63bd40 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -286,6 +286,7 @@ var vcsPaths = []*vcsPath{
{
prefix: "github.com/",
re: `^(?P<root>github\\.com/[A-Za-z0-9_.\\-]+/[A-Za-z0-9_.\\-]+)(/[A-Za-z0-9_.\\-]+)*$`,
+ vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/59ae15106a2ae0a409f710a16a8180ae81f81a3d
元コミット内容
cmd/go: fix get github
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5569054
変更の背景
このコミットは、2012年当時のGo言語のgo get
コマンドがGitHubリポジトリを正しく処理できないという問題に対処するために行われました。go get
コマンドは、指定されたインポートパスに基づいて、対応するバージョン管理システム(VCS)からソースコードを取得し、ビルドする機能を提供します。
当時のgo get
は、特定のホスティングサービス(例: GitHub, Bitbucketなど)に対して、そのURLパターンからVCSの種類を自動的に推測しようと試みていました。しかし、GitHubの場合、そのURL構造だけではVCSがGitであると常に確実に判断できるわけではなかった可能性があります。特に、Go 1のリリース(2012年3月)前後の時期は、go get
の機能がまだ成熟途上にあり、ユーザー側でのGitのインストールや設定、プライベートリポジトリへの認証方法など、様々な要因で問題が発生しやすい状況でした。
このコミットは、src/cmd/go/vcs.go
ファイル内のvcsPaths
という設定において、github.com/
で始まるパスに対して明示的にvcs: "git"
という情報を追加することで、go get
がGitHubリポジトリを扱う際にVCSの自動検出に失敗する可能性を排除し、確実にGitとして処理するように修正することを目的としています。これにより、GitHubからのパッケージ取得の信頼性が向上しました。
前提知識の解説
go get
コマンド
go get
はGo言語のツールチェーンの一部であり、リモートリポジトリからGoパッケージとその依存関係をダウンロードし、ローカルのGOPATH
(またはGo Modulesが有効な場合はモジュールキャッシュ)に配置するコマンドです。また、ダウンロードしたパッケージをビルドしてインストールする機能も持ちます。
GOPATH
とGo Modules
GOPATH
: Go 1.11以前のGoプロジェクトのワークスペースを定義する環境変数でした。すべてのGoソースコード、コンパイル済みバイナリ、パッケージはGOPATH
内の特定のディレクトリ構造に配置されました。go get
は、このGOPATH
内にリモートリポジトリをクローンしていました。- Go Modules: Go 1.11で導入され、Go 1.16でデフォルトとなった新しい依存関係管理システムです。プロジェクトの依存関係を
go.mod
ファイルで宣言し、GOPATH
に依存しない形でパッケージを管理します。go get
の動作もGo Modulesの導入により大きく変化しましたが、このコミットが作成された2012年当時はまだGOPATH
が主流でした。
vcs.go
ファイルとVCS検出
src/cmd/go/vcs.go
(またはその前身となるファイル)は、go get
コマンドが様々なバージョン管理システム(Git, Mercurial, Subversionなど)を識別し、それらのリポジトリを操作するためのロジックを含んでいます。このファイルには、特定のインポートパスのプレフィックスや正規表現に基づいて、どのVCSを使用すべきか、リポジトリのURLは何か、といった情報を定義するvcsPath
構造体のリストが含まれています。
go get
は、ユーザーが指定したインポートパスをこれらのvcsPath
エントリと照合し、最初に見つかった一致するエントリの情報(VCSの種類、リポジトリURLなど)を使用して、リモートリポジトリのクローン操作を実行します。
github.com
の特殊性
GitHubは、Goコミュニティにとって非常に重要なコードホスティングプラットフォームです。多くのGoパッケージがgithub.com/user/repo
のような形式で公開されています。go get
がGitHubリポジトリを正しく扱えることは、Goエコシステム全体の健全性にとって不可欠でした。
技術的詳細
このコミットの技術的詳細の中心は、src/cmd/go/vcs.go
ファイル内のvcsPaths
スライス(Goの配列のようなもの)の定義にあります。
vcsPaths
は、go get
がインポートパスを解析し、対応するバージョン管理システムとリポジトリURLを決定するために使用するルールセットです。各ルールはvcsPath
構造体で表現され、以下のフィールドを持ちます(関連する部分のみ抜粋):
prefix
: インポートパスがこの文字列で始まる場合にマッチします。re
: インポートパス全体に適用される正規表現です。この正規表現は、リポジトリのルートパスなどをキャプチャするために使用されます。vcs
: 使用すべきバージョン管理システムの種類(例: "git", "hg", "svn")。repo
: リポジトリのクローンURLのテンプレート。re
でキャプチャされたグループ(例:{root}
)を埋め込むことができます。
変更前のgithub.com/
に対応するエントリは以下のようでした。
{
prefix: "github.com/",
re: `^(?P<root>github\\.com/[A-Za-z0-9_.\\-]+/[A-Za-z0-9_.\\-]+)(/[A-Za-z0-9_.\\-]+)*$`,
repo: "https://{root}",
check: noVCSSuffix,
},
この定義では、github.com/
で始まるパスに対して正規表現re
とリポジトリURLテンプレートrepo
が指定されていますが、vcs
フィールドが明示的に設定されていませんでした。vcs
フィールドが設定されていない場合、go get
はVCSの種類を自動的に検出するか、他のフォールバックメカニズムに頼ることになります。
このコミットでは、このエントリにvcs: "git",
という行が追加されました。
{
prefix: "github.com/",
re: `^(?P<root>github\\.com/[A-Za-z0-9_.\\-]+/[A-Za-z0-9_.\\-]+)(/[A-Za-z0-9_.\\-]+)*$`,
vcs: "git", // ← この行が追加された
repo: "https://{root}",
check: noVCSSuffix,
},
この変更により、go get
はgithub.com/
で始まるインポートパスを処理する際に、VCSの種類を自動検出するのではなく、常にGitとして扱うことが保証されるようになりました。これにより、GitHubリポジトリのクローン時にVCSの誤認識が発生する可能性が排除され、go get
の信頼性が向上しました。
これは、Goツールチェーンが特定のホスティングサービスに対して、そのサービスが主に利用しているVCSを明示的に指定することで、より堅牢な動作を実現する初期の例の一つと言えます。
コアとなるコードの変更箇所
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -286,6 +286,7 @@ var vcsPaths = []*vcsPath{
{
prefix: "github.com/",
re: `^(?P<root>github\\.com/[A-Za-z0-9_.\\-]+/[A-Za-z0-9_.\\-]+)(/[A-Za-z0-9_.\\-]+)*$`,
+ vcs: "git",
repo: "https://{root}",
check: noVCSSuffix,
},
コアとなるコードの解説
変更はsrc/cmd/go/vcs.go
ファイル内のvcsPaths
というグローバル変数([]*vcsPath
型のスライス)の定義の一部です。このスライスは、go get
コマンドがインポートパスを解析する際に使用する、バージョン管理システム(VCS)のリポジトリパターンを定義しています。
具体的には、github.com/
プレフィックスにマッチするvcsPath
エントリに、以下の1行が追加されました。
vcs: "git",
この行は、github.com/
で始まるGoのインポートパス(例: github.com/user/repo
)が指定された場合、go get
コマンドがそのリポジトリをGitバージョン管理システムとして扱うべきであることを明示的に指示しています。
変更前は、このvcs
フィールドが設定されていなかったため、go get
はGitHubリポジトリのVCSタイプを自動的に推測しようとしていました。しかし、この推測プロセスが常に成功するとは限らず、特に初期のGoツールチェーンでは、GitHubからのパッケージ取得に失敗するケースがあったと考えられます。
vcs: "git"
を明示的に追加することで、go get
はGitHubリポジトリに対してVCSの自動検出を行う必要がなくなり、直接Gitコマンド(例: git clone
)を使用してリポジトリをクローンするようになります。これにより、GitHubからのパッケージ取得の信頼性と安定性が向上しました。
関連リンク
- Go Change-Id 5569054: このコミットに対応するGoのコードレビューシステム(Gerrit)上の変更リストです。Goプロジェクトでは、GitHubのコミットと並行して、Gerrit上で詳細なレビュープロセスが行われます。
参考にした情報源リンク
- Go 1 Release Notes (March 2012): https://go.dev/doc/go1
- Stack Overflow:
go get
command not working (related to Git setup): https://stackoverflow.com/questions/tagged/go-get (General search forgo get
issues) golang.org/x/tools/go/vcs
package documentation (deprecated but provides context onvcs.go
's role): https://pkg.go.dev/golang.org/x/tools/go/vcsgo list -json
(modern approach for import path resolution): https://go.dev/ref/mod#go-list- Community-maintained VCS libraries for Go (e.g.,
github.com/Masterminds/vcs
): https://pkg.go.dev/github.com/Masterminds/vcs