Menggunakan impor paket bercabang di Go

104

Misalkan Anda memiliki repositori di github.com/someone/repodan Anda mem-forknya github.com/you/repo. Anda ingin menggunakan garpu alih-alih repo utama, jadi Anda melakukan a

go get github.com/you/repo

Sekarang semua jalur impor di repo ini akan "rusak", artinya, jika ada beberapa paket di repositori yang mereferensikan satu sama lain melalui URL absolut, mereka akan mereferensikan sumbernya, bukan garpu.

Apakah ada cara yang lebih baik seperti mengkloningnya secara manual ke jalur yang benar?

git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo
Erik Aigner
sumber
1
Tidak ada jalur impor di garpu baru yang akan rusak yang belum pernah rusak sebelum bercabang.
zzzz
11
Maaf mengecewakan Anda, tapi itu tidak benar. Jika sub-paket direferensikan dalam impor melalui url absolutnya, impor ini akan rusak di percabangan (atau setidaknya mereferensikan paket yang salah).
Erik Aigner
2
Misalnya goamz . Ini memiliki referensi internal di semua tempat.
Erik Aigner
1
Lihat ec2paket - ada launchpad.net/goamz/awsimpor. Keduanya, awsdan ec2paket berada di repositori yang SAMA, jadi ketika bercabang, tidak akan mereferensikan paket yang benar (yang ada di percabangan).
Erik Aigner
1
Garpu akan mereferensikan paket yang sama dengan sumber garpu. Apa yang salah? Garpu akan mengkompilasi, membangun, melakukan hal yang sama seperti sebelumnya. Lalu apa definisi 'paket salah'? Perhatikan bahwa bahasa Go, seperti halnya sistem build-nya, tidak memiliki kesadaran akan repositori, hanya paket.
zzzz

Jawaban:

84

Untuk menangani permintaan tarik

  • percabangkan repositori github.com/someone/repokegithub.com/you/repo
  • unduh kode asli: go get github.com/someone/repo
  • berada disana: cd "$(go env GOPATH)/src"/github.com/someone/repo
  • aktifkan mengunggah ke garpu Anda: git remote add myfork https://github.com/you/repo.git
  • unggah perubahan Anda ke repo Anda: git push myfork

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

Untuk menggunakan paket dalam proyek Anda

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

Ivan Rave
sumber
dari folder mana yang harus saya lakukan git remote add? klon dari garpu? klon dari aslinya? dari dalam pergi?
putaran
1
@lapots menjalankan perintah di repo asli (yaitu $ GOPATH / src / github.com / somone / repo)
will7200
Bagaimana jika saya ingin menambahkan perubahan ke repo yang sudah lama bercabang?
NA
61

Jika Anda menggunakan modul go . Anda bisa menggunakan replacedirektif

The replacedirektif memungkinkan Anda untuk memasok path impor lain yang mungkin modul lain terletak di VCS (GitHub atau di tempat lain), atau pada sistem file lokal Anda dengan path file relatif atau absolut. Jalur impor baru dari replacedirektif digunakan tanpa perlu memperbarui jalur impor di kode sumber sebenarnya.

Jadi Anda bisa melakukannya di bawah ini di file go.mod Anda

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

di mana v3.2.1tag di repo Anda. Juga bisa dilakukan melalui CLI

go mod edit -replace="github.com/someone/[email protected]=github.com/you/[email protected]"
Yogesh
sumber
4
bekerja dengan baik. Saya pikir satu-satunya alasan ini tidak memiliki lebih banyak suara positif adalah karena orang-orang belum menggunakan modul go. Saya juga menggunakan trik ini untuk mengarahkan ke lokasi file ke direktori lain di workstation saya tempat saya memiliki pengeditan lokal yang sedang saya kerjakan. Saya hanya akan menghapus baris "ganti" saya setelah saya mendorong suntingan lokal saya di github.
lazieburd
^ 100% setuju. Pilih orang.
Andrew Arrow
2
oh, tapi "master" tidak berhasil untukku. Saya harus menulis v0.0.1 atau versi tertentu di sana.
Andrew Arrow
1
Anda juga dapat go mod edit -replace langsung pada baris perintah: go mod edit -replace="github.com/someone/[email protected]=github.com/you/[email protected]". Keduanya @v...opsional.
Joel Purra
Bukankah keren memiliki go.mod.localatau go.mod.devperan siapa yang benar-benar menggantikan jalur impor untuk pembangunan lokal? Maksud saya, Anda tidak akan pernah lupa untuk menghapus "ganti" yang jelek karena Anda tidak perlu melakukannya.
Manuel
21

Salah satu cara untuk mengatasinya adalah yang disarankan oleh Ivan Rave dan http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html - cara bercabang.

Cara lainnya adalah mengatasi perilaku golang . Saat Anda go get, golang meletakkan direktori Anda dengan nama yang sama seperti di URI repositori, dan di sinilah masalahnya dimulai.

Jika, sebaliknya, Anda menerbitkan sendiri git clone, Anda bisa mengkloning repositori Anda ke sistem file Anda pada jalur yang dinamai sesuai repositori asli.

Dengan asumsi repositori asli ada github.com/awsome-org/tooldan Anda meminjamkannya github.com/awesome-you/tool, Anda dapat:

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 sangat senang untuk melanjutkan repositori ini dan tidak peduli beberapa direktori atas memiliki nama awesome-orgsementara git remote adalah awesome-you. Semua impor untuk awesome-orgdisimpan kembali melalui direktori yang baru saja Anda buat, yang merupakan set kerja lokal Anda.

Lebih lanjut, silakan lihat posting blog saya: Memotong repositori Golang di GitHub dan mengelola jalur impor

edit : jalur direktori tetap

Shlomi Noach
sumber
3
Saya setuju ini adalah solusi "terbaik" untuk ini. Tapi alangkah baiknya melihat bagaimana orang mengelola alur kerja ini saat menjalankan aplikasi Go di container Docker. Saya sedang mempelajari golang dan ingin menambahkan fitur kecil ke perpustakaan yang saya gunakan ketika saya mengalami sakit kepala ini dengan mengujinya sebelum membuat Permintaan Tarik.
Joakim
6

Jika garpu Anda hanya sementara (yaitu Anda bermaksud untuk menggabungkannya) maka lakukan saja pengembangan Anda di situ, misalnya di $GOPATH/src/launchpad.net/goamz.

Anda kemudian menggunakan fitur sistem kontrol versi (misalnya git remote) untuk menjadikan repositori upstream sebagai repositori Anda, bukan yang asli.

Ini mempersulit orang lain untuk menggunakan repositori Anda, go gettetapi lebih mudah untuk diintegrasikan ke upstream.

Sebenarnya saya memiliki gudang untuk goamz di lp:~nick-craig-wood/goamz/goamzmana saya mengembangkannya dengan cara yang persis seperti itu. Mungkin penulis akan menggabungkannya suatu hari nanti!

Nick Craig-Wood
sumber
1
Supaya saya mengerti implikasi dari melakukan ini, jika saya pergi ke rute ini, ketika seseorang melakukan a go getdari repo saya, semua pernyataan impor saya dan semacamnya akan tetap mencerminkan github.com/original_authordan dengan demikian akan rusak ... benar?
parker.sikand
@ parker.sikand ya itu benar. Teknik ini paling baik untuk hal-hal yang ingin Anda gabungkan ke hulu, bukan untuk digunakan. Jika Anda berniat untuk membagi paket secara permanen, gunakan teknik jawaban lain.
Nick Craig-Wood
4

Inilah cara yang berhasil untuk semua orang:

Gunakan github untuk bercabang ke "my / repo" (hanya sebagai contoh):

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

Ulangi setiap kali Anda membuat kode lebih baik:

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

Mengapa? Ini memungkinkan Anda memiliki repo yang go getberfungsi dengan apa pun . Ini juga memungkinkan Anda memelihara & meningkatkan cabang yang bagus untuk permintaan tarik. Itu tidak membengkak dengan "vendor", itu mempertahankan sejarah, dan membangun alat dapat memahaminya.

pengguna1212212
sumber
Sedikit koreksi: jalankan github.com/golang/tools/cmd/gomvpkg/main.go dan perintah ini memindahkan .git, jadi simpan di tempat lain & pulihkan setelahnya.
pengguna1212212
juga dimungkinkan untuk menggunakan plugin mvn-golang yang membuat beberapa otomatisasi dalam pemrosesan dependensi seperti pada contoh github.com/raydac/mvn-golang/tree/master/mvn-golang-examples/…
Igor Maznitsa
3

Jawabannya adalah jika Anda membagi repo dengan beberapa paket, Anda perlu mengganti nama semua jalur impor yang relevan. Ini sebagian besar merupakan hal yang baik karena Anda telah melakukan fork semua paket itu dan jalur impor harus mencerminkan ini.

Jeremy Wall
sumber
3
Saya menghabiskan lebih banyak waktu daripada yang saya akui untuk mendiagnosis hal ini dalam kontribusi pertama saya untuk proyek Go. "Semua tes lulus, termasuk yang saya tulis untuk menguji fungsionalitas baru secara menyeluruh. Ada apa ?!" Apakah Anda mengetahui adanya perkakas yang tersedia untuk memudahkan titik sandungan bagi pemula ini?
Sage Mitchell
3
Setelah saya pikir itu keluar itu mudah untuk memecahkan menggunakan find, xargsdan sed, tetapi akan membantu untuk memiliki alur kerja bebas rasa sakit yang secara konsisten bekerja untuk semua orang.
Sage Mitchell
@JakeMitchell gomvpkgdapat melakukan penggantian nama dengan lebih mudah / lebih baik. go get golang.org/x/tools/cmd/gomvpkglalu gomvpkg -help.
Dave C
3
Jawaban ini menurut saya tidak praktis. Mengeluarkan file proyek dari proyek bercabang, itu gila? Apa yang Anda lakukan saat membuat permintaan tarik? Jawaban dari Ivan Rave sepertinya merupakan solusi yang jauh lebih baik bagi saya.
Ivan P
8
Apakah ini masih cara kerja Go-lang? Ini benar-benar gila, sehingga tidak lucu ... Ramah hulu, atau ramah hilir, tapi tidak keduanya. Ini adalah cacat desain yang sangat besar menurut pendapat saya yang tidak begitu rendah hati, mungkin dilakukan oleh orang-orang yang tidak terlalu banyak berkolaborasi lintas proyek. #FAIL #GOLANG
Niclas Hedhman
1

Untuk mengotomatiskan proses ini, saya menulis skrip kecil. Anda dapat menemukan detail selengkapnya di blog saya untuk menambahkan perintah seperti "gofork" ke bash Anda.

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
heralight
sumber
Haruskah golangdiubah menjadi goforkbaris 4?
Dan Tenenbaum
terlihat baik! memperbaiki!
heralight
1

Gunakan vending dan submodul bersama-sama

  1. Fork lib di github (go-mssqldb dalam kasus ini)
  2. Tambahkan submodul yang mengkloning fork Anda ke dalam folder vendor tetapi memiliki jalur repo upstream
  3. Perbarui importpernyataan Anda di kode sumber agar mengarah ke folder vendor, (tidak termasuk vendor/awalan). Misalnya vendor/bob/lib=>import "bob/lib"

Misalnya

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

mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb

git submodule add "[email protected]:$mygithubuser/$librepo" "vendor/$upstreamgithubuser/$librepo"

Mengapa

Ini memecahkan semua masalah yang saya dengar dan temui saat mencoba mencari tahu sendiri.

  • Ref paket internal di lib sekarang berfungsi karena jalur tidak berubah dari upstream
  • Pembayaran baru dari proyek Anda berfungsi karena sistem submodule mendapatkannya dari garpu Anda di komit yang tepat tetapi di jalur folder upstream
  • Anda tidak perlu tahu cara meretas jalur secara manual atau mengacaukan peralatan jalan.

Info lebih lanjut

Tim Abell
sumber
0

di Gopkg.tomlfile Anda tambahkan blok ini di bawah

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

Jadi itu akan menggunakan bercabang project2sebagai penggantigithub.com/globalsign/mgo

msonowal.dll
sumber
The Gopkg.tomlfile hanya digunakan oleh depyang pertanyaan ini tidak menyebutkan sama sekali. Proyek Go baru harus menggunakan modul Go sebagai gantinya (dan proyek berbasis dep IMO yang ada juga harus bermigrasi).
Dave C
Saya tidak tahu tentang fitur dep ini, dan jawaban Anda pasti membantu saya :)
Veger
0

Anda dapat menggunakan perintah go get -funtuk memberi Anda repo bercabang

kevin
sumber