Использование импорта forked package в Go
Предположим, что у вас есть репозиторий в github.com/someone/repo
, и вы его разворачиваете до github.com/you/repo
. Вы хотите использовать свою вилку вместо основного репо, поэтому вы делаете
go get github.com/you/repo
Теперь все пути импорта в этом репо будут "сломаны", то есть если в репозитории есть несколько пакетов, которые ссылаются друг на друга через абсолютные URL-адреса, они будут ссылаться на источник, а не на fork.
Есть ли лучший способ, как клонирование вручную на правильный путь?
git clone [email protected]:you/repo.git $GOPATH/src/github.com/someone/repo
Ответы
Ответ 1
Для обработки запросов на выгрузку
- разветкить репозиторий
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
Ответ 2
Один из способов его решения - это то, что предложил Иван Рав и http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html - способ разветвления.
Другой способ - обходное поведение голанга. Когда вы go get
, golang выдает ваши каталоги под тем же именем, что и в 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 [email protected]:awesome-you/tool.git # OR: git clone https://github.com/awesome-you/tool.git
cd tool/
go get ./...
golang с удовольствием продолжит работу с этим репозиторием и на самом деле не заботится о том, что верхний каталог имеет имя awesome-org
, а удаленный git - awesome-you
. Весь импорт для awesome-org
переносится через каталог, который вы только что создали, который является вашим локальным рабочим набором.
Более подробно см. мой пост в блоге: Формирование репозиториев Golang на GitHub и управление пути импорта
изменить: путь к фиксированной директории
Ответ 3
Если ваша вилка только временная (т.е. предполагается, что она будет объединена), просто выполните свою разработку на месте, например, в $GOPATH/src/launchpad.net/goamz
.
Затем вы используете функции системы управления версиями (например, git remote
), чтобы сделать восходящий репозиторий вашим репозиторием, а не оригинальным.
Это затрудняет для других людей использование вашего репозитория с помощью go get
, но гораздо проще для его интеграции вверх по течению.
На самом деле у меня есть репозиторий для goamz в lp:~nick-craig-wood/goamz/goamz
, который я разрабатываю именно таким образом. Возможно, автор однажды объединит его!
Ответ 4
Если вы используете иди модули. Вы можете использовать директиву replace
directive
Директива replace
позволяет вам указать другой путь импорта, который может быть другим модулем, расположенным в VCS (GitHub или в другом месте), или на вашем локальная файловая система с относительным или абсолютным путем к файлу. Новый импорт путь из директивы replace
используется без необходимости обновления импортировать пути в исходный код.
Так что вы можете сделать ниже
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 master
Ответ 5
Вот способ, который работает для всех:
Используйте 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
работает. Это также позволяет вам поддерживать и улучшать ветку, которая хороша для запроса извлечения. Он не переполняет мерзавца "вендором", он сохраняет историю, и инструменты сборки могут это понять.
Ответ 6
Ответ на этот вопрос заключается в том, что если вы разблокируете репо с несколькими пакетами, вам нужно будет переименовать все соответствующие пути импорта. Это в значительной степени хорошо, поскольку вы разветвляли все эти пакеты, и пути импорта должны отражать это.
Ответ 7
Используйте вендоринг и субмодули вместе
- Разместите библиотеку на github (в данном случае go-mssqldb)
- Добавьте подмодуль, который клонирует ваш форк, в папку вашего поставщика, но имеет путь к репозиторию восходящего направления.
- Обновите операторы
import
в исходном коде, чтобы они указывали на папку поставщика (не включая vendor/
префикс). Например, vendor/bob/lib
=> import "bob/lib"
Например
cd ~/go/src/github.com/myproj
mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb
git submodule add "[email protected]:$mygithubuser/$librepo" "vendor/$upstreamgithubuser/$librepo"
Зачем
Это решает все проблемы, о которых я слышал, и сталкиваюсь, пытаясь понять это самостоятельно.
- Внутренние ссылки на пакеты в lib теперь работают, потому что путь не меняется от апстрима
- Новая проверка вашего проекта работает, потому что подмодульная система получает его от вашего форка при правильном коммите, но в пути к восходящей папке
- Вам не нужно знать, чтобы вручную взламывать пути или связываться с инструментом go.
Больше информации
Ответ 8
Чтобы автоматизировать этот процесс, я написал небольшой script. Более подробную информацию о blog можно найти, чтобы добавить команду, например "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
Ответ 9
в вашем файле Gopkg.toml
добавьте эти блоки ниже
[[constraint]]
name = "github.com/globalsign/mgo"
branch = "master"
source = "github.com/myfork/project2"
Так что он будет использовать раздвоенный project2
вместо github.com/globalsign/mgo