はじめに

この記事は、GoのリポジトリをGitHubでフォークして開発しようとした際に「import文のパスがずれてエラーが出る」「ローカルで動かない」という問題に直面した方を対象としています。

読むことで、fork先のリポジトリで正しくimportパスを解決する方法、特にgo.modreplaceディレクティブを使ったローカル開発のベストプラクティスがわかります。clone直後で動かない原因と、それを解決するための具体的な手順を解説します。

前提知識

  • Goの基本的な文法とプロジェクトのビルド方法
  • GitHubでリポジトリをフォーク・クローンする操作
  • go.modが依存関係を管理していることの理解

forkしてみたらimportが解決できない!

Go製のOSSにプルリクエストを送ろうと、GitHub上でフォークしてcloneしました。ところがgo rungo buildを実行すると、以下のようなエラーが出てしまいます。

main.go:5:2: github.com/original/repo/pkg/logger: no required module provides package github.com/original/repo/pkg/logger

要するに、「import文が元リポジトリのパスを指したままで、フォーク先のコードを参照できていない」という事象です。GoのmoduleシステムはimportパスとGitHubの物理パスを一致させる前提にあるため、フォーク先ではパスがずれてしまいます。

go.modのreplaceでローカルパスを騙す

この問題を解決する最も確実で簡潔な方法が、go.modreplaceディレクティブを追加することです。以下、手順を紹介します。

ステップ1:フォーク&clone

  1. GitHubで対象リポジトリをフォーク
  2. フォーク先のURLを自分の環境にclone
Bash
git clone https://github.com/YOUR_NAME/repo.git cd repo

ステップ2:go.modにreplaceを追加

プロジェクトルートのgo.modを開き、最終行に以下を追加します。

Go
module github.com/original/repo go 1.22 require ( github.com/some/dependency v1.2.3 ) replace github.com/original/repo => ./
  • 左辺:元リポジトリのimportパス
  • 右辺:./で現在のディレクトリ(フォーク先)を指す

これでgo run/go buildが通るようになります。

ステップ3:replaceを外してCIを通す(オプション)

プルリク作成時にCIが動く場合、go.modreplaceが残っているとCI側でも同じパス解決が必要です。CIを通したい場合は、プッシュ前に以下のどちらかを選びます。

  1. 一時的にreplace行をコメントアウト
  2. CI上でも同様のreplace処理を施す(sedや環境変数で)
Bash
# 例:コメントアウトしてプッシュ sed -i 's/^replace/# replace/' go.mod git add go.mod git commit -m "fix: remove replace for CI" git push origin feature-branch

ハマった点:replaceの書き方を間違えると無視される

最初replaceを以下のように書いてしまい、効いているのかどうか分からず困りました。

Go
// 間違い例 replace ( github.com/original/repo v0.0.0 => ./ )

replaceは「モジュールパス => ローカルパス」のみでバージョンを書くと無視されます。正しくは:

Go
// 正しい例 replace github.com/original/repo => ./

解決策:go listでreplaceが効いているか確認

以下コマンドで、replaceが効いているか即座に検証できます。

Bash
go list -m all | grep repo # => github.com/original/repo => ./ (replace)

=>の右が./になっていれば成功です。

まとめ

本記事では、GitHubでフォークしたGoリポジトリでimportパスが解決できない問題を、go.modreplaceディレクティブで解決する方法を解説しました。

  • フォーク直後はimportパスが元リポジトリを指しているためビルドできない
  • replace github.com/original/repo => ./を追加すればローカルで解決
  • CIを通す場合は、replaceを外すかCI側でも同様の処理が必要

この手法を使えば、OSSに貢献する際の最初のハードルが一つ下がります。次回はgo.workを使った複数モジュールの管理方法について掘り下げていきます。

参考資料