Використання імпорту роздвоєного пакета в 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.