Goでのフォークされたパッケージのインポートの使用


104

にリポジトリがあり、github.com/someone/repoそれをforkしたとしgithub.com/you/repoます。メインリポジトリの代わりにフォークを使用したいので、

go get github.com/you/repo

これで、このリポジトリのすべてのインポートパスは「壊れた」状態になります。つまり、リポジトリに絶対URLを介して相互に参照する複数のパッケージがある場合、それらはフォークではなくソースを参照します。

手動で正しいパスに複製するより良い方法はありますか?

git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo

1
いいえ新しいフォークにインポートパスは、フォークの前に、すでに壊れていないされた壊れません。
zzzz

11
あなたを失望させて申し訳ありませんが、それは本当ではありません。サブパッケージが絶対URLを介してインポートで参照されている場合、このインポートはフォークで壊れます(または少なくとも間違ったパッケージを参照します)。
Erik Aigner 2013年

2
たとえばgoamz。あちこちに内部参照があります。
Erik Aigner 2013年

1
ec2パッケージを見てください- launchpad.net/goamz/awsインポートされています。awsec2パッケージの両方がSAMEリポジトリに存在するため、フォークすると、正しいパッケージ(フォーク内のパッケージ)を参照しません。
Erik Aigner

1
フォークは、フォークのソースと同じパッケージを参照します。その何が間違っていますか?フォークはコンパイルされ、ビルドされ、以前と同じことを行います。では、「誤ったパッケージ」の定義は何ですか?Go言語は、そのビルドシステムと同様に、パッケージのみがリポジトリを認識しないことに注意してください。
zzzz

回答:


84

プルリクエストを処理するには

  • リポジトリgithub.com/someone/repoをフォークしてgithub.com/you/repo
  • 元のコードをダウンロード: go get github.com/someone/repo
  • そこにいる: cd "$(go env GOPATH)/src"/github.com/someone/repo
  • フォークへのアップロードを有効にします。 git remote add myfork https://github.com/you/repo.git
  • 変更をリポジトリにアップロードします。 git push myfork

http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html

プロジェクトでパッケージを使用するには

https://github.com/golang/go/wiki/PackageManagementTools


どのフォルダから行うべきですgit remote addか?フォークからクローン?オリジナルからクローン?内から?
ラポ

1
@lapotsは元のリポジトリ(つまり、$ GOPATH / src / github.com / somone / repo)でコマンドを実行します
will7200

ずっと前にフォークされたリポジトリに変更を追加したい場合はどうなりますか?
NA

61

goモジュールを使用している場合。replaceディレクティブを使用できます

replaceディレクティブは、あなたが他のVCS(他のGitHubまたは)に位置モジュール、または相対または絶対ファイルパスを使用してローカルファイルシステム上にあるかもしれない別のインポートパスを供給することができます。replaceディレクティブからの新しいインポートパスは、実際のソースコードのインポートパスを更新する必要なく使用されます。

だからあなたはあなたのgo.modファイルで以下を行うことができます

module github.com/yogeshlonkar/openapi-to-postman

go 1.12

require (
    github.com/someone/repo v1.20.0
)

replace github.com/someone/repo => github.com/you/repo v3.2.1

v3.2.1あなたのリポジトリのタグはどこですか?CLIからも実行できます

go mod edit -replace="github.com/someone/repo@v0.0.0=github.com/you/repo@v1.1.1"

4
うまくいきました。私がこれに賛成票がないのは、人々がまだgoモジュールを使用していないためです。また、このトリックを使用して、自分が作業していたローカル編集があったワークステーション上の別のディレクトリへのファイルの場所をポイントしました。githubでローカル編集をプッシュしたら、「replace」行を削除するだけです。
lazieburd

^ 100%同意する。投票してください。
Andrew Arrow

2
ああ、でも「マスター」はうまくいかなかった。そこでv0.0.1または特定のバージョンを作成する必要がありました。
Andrew Arrow、

1
go mod edit -replace コマンドラインで直接行うこともできますgo mod edit -replace="github.com/someone/repo@v0.0.0=github.com/you/repo@v1.1.1"。どちら@v...もオプションです。
Joel Purra

持っているクールではないでしょうgo.mod.localか、go.mod.devその役割は、実際に地域開発のためのインポートパスを交換するのですか?つまり、あなたがする必要がないので、醜い「交換」を削除することを決して忘れないでしょう。
マヌエル

21

それを解決する1つの方法は、Ivan Raveおよびhttp://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html-フォークの方法によって提案された方法です。

もう1つは、golangの動作を回避することです。ときgo getgolangはリポジトリURIと同じ名前でディレクトリをレイアウトします。これが問題の始まりです。

代わりに、独自のを発行するgit clone場合は、元のリポジトリにちなんで名付けられたパス上のファイルシステムにリポジトリを複製できます。

元のリポジトリがあり、github.com/awsome-org/toolそれをにフォークするとgithub.com/awesome-you/tool、次のことができます。

cd $GOPATH
mkdir -p {src,bin,pkg}
mkdir -p src/github.com/awesome-org/
cd src/github.com/awesome-org/
git clone git@github.com:awesome-you/tool.git # OR: git clone https://github.com/awesome-you/tool.git
cd tool/
go get ./...

golangはこのレポジトリを続行しても問題なくawesome-org、git remoteが存在する間、実際には上位ディレクトリの名前が気になりませんawesome-you。のすべてのインポートはawesome-org、作成したディレクトリ(ローカルワーキングセット)を介して再解決されます。

詳しくは、私のブログ投稿を参照してください:GitHubでのGolangリポジトリのフォークとインポートパスの管理

編集:固定ディレクトリパス


3
これが「最善の」ソリューションであることに同意します。しかし、DockerコンテナーでGoアプリを実行するときに、このワークフローを管理する方法を知っておくと非常に便利です。私はgolangを学んでいて、プルリクエストを作成する前にテストしてこの頭痛の種に遭遇したときに使用しているライブラリに小さな機能を追加したいと考えていました。
ジョアキム2016

6

フォークが一時的なものである場合(つまり、マージするつもりである場合)、開発をその場で、たとえばで行うだけです$GOPATH/src/launchpad.net/goamz

次に、バージョン管理システムの機能(などgit remote)を使用して、元のリポジトリではなく上流のリポジトリをリポジトリにします。

他の人があなたのリポジトリを使うのを難しくしますgo getが、それを上流に統合するのはずっと簡単です。

実際、私はgoamzのリポジトリを持っています。そのリポジトリをlp:~nick-craig-wood/goamz/goamzまさにその方法で開発しています。多分作者はいつかそれをマージするでしょう!


1
これを行うことの意味を理解しているので、私がこのルートを使用した場合、誰かがgo get私のリポジトリからaを実行すると、すべてのインポート文などが引き続き反映されgithub.com/original_author、したがって壊れます...正しいですか?
parker.sikand 2014年

@ parker.sikandはい、それは正しいです。この手法は、go getを使用するのではなく、上流でマージする予定のものに最適です。パッケージを永続的にフォークする場合は、他の回答の手法を使用してください。
Nick Craig-Wood

4

これが誰にとってもうまくいく方法です:

githubを使用して「my / repo」にフォークします(単なる例):

go get github.com/my/repo
cd ~/go/src/github.com/my/repo
git branch enhancement
rm -rf .
go get github.com/golang/tools/cmd/gomvpkg/…
gomvpkg <<oldrepo>> ~/go/src/github.com/my/repo
git commit

コードを改善するたびに繰り返します。

git commit
git checkout enhancement
git cherry-pick <<commit_id>>
git checkout master

どうして?これにより、どのリポジトリでもgo get動作するリポジトリを作成できます。また、プルリクエストに適したブランチを維持および拡張できます。gitを「ベンダー」で膨らませることはなく、履歴を保持し、ビルドツールはそれを理解できます。


わずかな修正:github.com/golang/tools/cmd/gomvpkg/main.goを実行すると、このコマンドで.gitが移動するため、別の場所に保存して後で復元します。
user1212212 2017


3

これに対する答えは、複数のパッケージを含むリポジトリをフォークする場合、関連するすべてのインポートパスの名前を変更する必要があるということです。これらのパッケージをすべてフォークし、インポートパスがこれを反映しているため、これは主に良いことです。


3
Goプロジェクトへの最初の貢献で、これを診断することを認めるほどの時間を費やしました。「新しい機能を徹底的にテストするために私が書いたものを含め、すべてのテストに合格しました。何が問題なのですか?」初心者のこのつまずきを和らげるために利用できるツールを知っていますか?
セージミッチェル

3
私はそれを考え出したら、それは使用して解決するのは簡単だったfindxargssed、それは一貫して、みんなのために働くことを痛みのないワークフローを持つことが役立つだろう。
セージミッチェル

@JakeMitchell gomvpkgは名前の変更をより簡単に/より良く行うことができます。go get golang.org/x/tools/cmd/gomvpkgその後gomvpkg -help
Dave C

3
この答えは完全に非現実的であると私に思わせます。フォークされたプロジェクトからプロジェクトファイルをSed-ingしている、それはおかしい?プルリクエストを作成するときはどうしますか?Ivan Raveの答えは、私にとってはるかに優れた解決策のようです。
Ivan P

8
これはまだGo-langの仕組みですか?これは非常に非常識なので、面白くありません...上流に対応するか、下流に対応するかのいずれかですが、両方ではありません。私のそれほど控えめな意見では、それはおそらく設計上の大きな欠陥であり、おそらくクロスプロジェクトにあまり協力していない人々によってなされたものでしょう。#FAIL #GOLANG
Niclas Hedhman 2016

1

このプロセスを自動化するために、小さなスクリプトを書きました。私のブログで「gofork」のようなコマンドをbashに追加するための詳細を見つけることができます。

function gofork() {
  if [ $# -ne 2 ] || [ -z "$1" ] || [ -z "$2" ]; then
    echo 'Usage: gofork yourFork originalModule'
    echo 'Example: gofork github.com/YourName/go-contrib github.com/heirko/go-contrib'
    return
  fi
   echo "Go get fork $1 and replace $2 in GOPATH: $GOPATH"
   go get $1
   go get $2
   currentDir=$PWD
   cd $GOPATH/src/$1
   remote1=$(git config --get remote.origin.url)
   cd $GOPATH/src/$2
   remote2=$(git config --get remote.origin.url)
   cd $currentDir
   rm -rf $GOPATH/src/$2
   mv $GOPATH/src/$1 $GOPATH/src/$2
   cd $GOPATH/src/$2
   git remote add their $remote2
   echo Now in $GOPATH/src/$2 origin remote is $remote1
   echo And in $GOPATH/src/$2 their remote is $remote2
   cd $currentDir
}

export -f gofork

4行目golangでに変更する必要がありgoforkますか?
Dan Tenenbaum

よく見た!直せ!
heralight 2017

1

ベンダーとサブモジュールを一緒に使用する

  1. githubのlibをフォークします(この場合はgo-mssqldb)。
  2. フォークをベンダーフォルダーに複製するサブモジュールを追加しますが、アップストリームレポのパスがあります
  3. importソースコードのステートメントを更新して、ベンダーフォルダーを指すようにします(vendor/プレフィックスは含みません)。例vendor/bob/lib=>import "bob/lib"

例えば

cd ~/go/src/github.com/myproj

mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb

git submodule add "git@github.com:$mygithubuser/$librepo" "vendor/$upstreamgithubuser/$librepo"

なぜ

これは私がこれまでに聞いた問題をすべて解決、自分でこれを理解しようとしているときに遭遇します。

  • パスが上流から変更されていないため、libの内部パッケージ参照が機能するようになりました
  • サブモジュールシステムが適切なコミットで上流のフォルダーパスにあるフォークからプロジェクトを取得するため、プロジェクトの新しいチェックアウトが機能します
  • goツールを使って手動でパスをハックしたり、混乱させたりする必要はありません。

より詳しい情報


0

あなたのGopkg.tomlファイルにこれらのブロックを下に追加してください

[[constraint]]
  name = "github.com/globalsign/mgo"
  branch = "master"
  source = "github.com/myfork/project2"

ので、フォークのproject2代わりに使用しますgithub.com/globalsign/mgo


Gopkg.tomlファイルはのみで使用されてdepいるこの質問は一切言及していません。新しいGoプロジェクトでは、代わりにGoモジュールを使用する必要があります(IMOの既存のdepベースのプロジェクトも移行する必要があります)。
デイブC

私はこのdep機能を知りませんでした、そしてあなたの答えは確かに私を助けてくれました:)
Veger

0

コマンドgo get -fを使用してフォークされたレポを取得できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.