Використання імпорту роздвоєного пакета в Go


104

Припустимо, у вас є сховище github.com/someone/repoі ви відправте його 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, цей імпорт буде порушений у вилці (або, принаймні, посилання на неправильний пакет).
Ерік Айгнер

2
Наприклад, гомз . Він має внутрішні посилання всюди.
Ерік Айгнер

1
Подивіться на ec2пакет - він має launchpad.net/goamz/awsімпорт. І пакети , awsі ec2пакети перебувають у сховищі SAME, тому при розщепленні не посилаються на правильний пакет (той, що знаходиться у вилці).
Ерік Айгнер

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

Що робити, якщо я хочу додати зміни до репо, що давно був роздвоєним?
НС

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.
lazieburd

^ 100% згоден. Голосуйте людей.
Ендрю Ерроу

2
о, але "майстер" не працював для мене. Мені довелося написати там v0.0.1 або якусь конкретну версію.
Ендрю Ерроу

1
Ви можете також go mod edit -replace безпосередньо в командному рядку: go mod edit -replace="github.com/someone/repo@v0.0.0=github.com/you/repo@v1.1.1". Обидва @v...необов’язкові.
Джоел Пурра

Чи не було б круто мати go.mod.localабо go.mod.devчия роль полягає в тому, щоб насправді замінити шлях імпорту для місцевого розвитку? Я маю на увазі, ви ніколи не забудете зняти потворну «заміну», тому що вам не доведеться.
Мануель

21

Один із способів вирішити це - запропонований Іваном Рейвом та 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 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 awesome-you. Весь імпорт для awesome-orgрезольвується через створений вами каталог, який є вашим локальним робочим набором.

Докладніше, дивіться мій пост у блозі: Розміщення сховищ Golang у GitHub та керування шляхом імпорту

редагувати : фіксований шлях до каталогу


3
Я згоден, це найкраще рішення для цього. Але було б дуже приємно подивитися, як люди керують цим робочим процесом під час запуску програми Go у контейнері Docker. Я вивчаю голанг і хотів додати крихітну особливість до бібліотеки, яку я використовую, коли я зіткнувся з цим головним болем, перевіряючи його перед створенням запиту на витяг.
Йоаким

6

Якщо ваша вилка є лише тимчасовою (тобто ви маєте намір її злиття), тоді просто зробіть свою розробку in situ, наприклад, в $GOPATH/src/launchpad.net/goamz.

Потім ви використовуєте функції системи управління версіями (наприклад git remote), щоб зробити репозиторій верхнього потоку своїм сховищем, а не оригінальним.

Іншим людям стає складніше використовувати ваше сховище, go getале набагато простіше його інтегрувати вгору за потоком.

Насправді у мене є сховище для goamz, в lp:~nick-craig-wood/goamz/goamzякому я розробляю саме таким чином. Можливо, автор одного разу з’єднає його!


1
Просто я розумію наслідки цього, якщо я пішов цим маршрутом, коли хтось зробить go getз мого репо, всі мої заяви про імпорт та інші будуть все-таки відображатись github.com/original_authorі таким чином порушуватися ... правильно?
parker.sikand

@ parker.sikand так, це правильно. Ця методика найкраща для речей, які ви збираєтеся об'єднати вгору за течією, а не для використання. Якщо ви збираєтесь роздрібнити пакет постійно, тоді використовуйте іншу техніку відповіді.
Нік Крейг-Вуд

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, тому збережіть це в іншому місці та відновіть його згодом.
користувач1212212

також можливо просто використовувати плагін mvn-golang, який робить деяку автоматизацію в обробці залежностей, як у прикладі github.com/raydac/mvn-golang/tree/master/mvn-golang-examples/…
Ігор Мазниця

3

Відповідь на це полягає в тому, що якщо ви роздвоюєте репо з кількома пакетами, вам потрібно буде перейменувати всі відповідні шляхи імпорту. Це багато в чому хороша річ, оскільки ви роздрібнили всі ці пакунки, і шляхи імпорту повинні відобразити це.


3
Я горів більше часу, ніж мені хочеться визнати, що діагностували це в своєму першому внеску в проект Go. "Усі тести проходять, включаючи ті, які я написав, щоб вичерпно перевірити нову функціональність. Що не так ?!" Чи знаєте ви про будь-який доступний інструмент для полегшення цієї точки спотикання для початківців?
Сейдж Мітчелл

3
Одного разу я зрозумів, що це легко вирішити за допомогою find, xargsі sed, але це допоможе безпроблемним робочим процесом, який постійно працює для всіх.
Сейдж Мітчелл

@JakeMitchell gomvpkgможе зробити перейменування легшими / кращими. go get golang.org/x/tools/cmd/gomvpkgто gomvpkg -help.
Дейв С

3
Ця відповідь вражає мене як повноту непрактичною. Вилучення файлів проекту з роздвоєного проекту, це божевільно? Що ви робите, коли створюєте запит на тягу? Відповідь Івана Рейва виглядає як набагато краще для мене рішення.
Іван П

8
Це все ще працює Go-lang? Це просто настільки божевільно, що це не смішно ... Або бути вгору за течією, або вниз за течією, але не те й інше. Це величезна вада дизайну в моїй не настільки скромній думці, ймовірно, це зроблено людьми, які не надто сильно співпрацюють між проектами. #FAIL #GOLANG
Niclas Hedhman

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

Чи golangслід змінити goforkрядок 4?
Дан Тененбаум

добре видно! виправити!
heralight

1

Використовуйте вендингові та субмодулі разом

  1. Виділіть lib на github (у цьому випадку 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 (а також існуючі проекти, засновані на ІМО, також повинні мігрувати).
Дейв C

Я не знав про цю функцію
Вегер,

0

Ви можете скористатися командою, go get -fщоб отримати роздвоєне репо

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.