Utilisation de l'importation de packages fourchus dans Go

104

Supposons que vous ayez un référentiel sur github.com/someone/repoet que vous le fassiez github.com/you/repo. Vous voulez utiliser votre fork au lieu du repo principal, vous faites donc un

go get github.com/you/repo

Désormais, tous les chemins d'importation de ce référentiel seront "cassés", ce qui signifie que s'il y a plusieurs packages dans le référentiel qui se référencent via des URL absolues, ils référenceront la source, pas le fork.

Existe-t-il un meilleur moyen de le cloner manuellement dans le bon chemin?

git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo
Erik Aigner
la source
1
Aucun chemin d'importation dans la nouvelle fourche ne sera cassé qui ne l'était déjà avant la fourche.
zzzz
11
Désolé de vous décevoir, mais ce n'est pas vrai. Si un sous-package est référencé dans les importations via son URL absolue, cette importation sera interrompue dans le fork (ou au moins référencera le mauvais package).
Erik Aigner le
2
Par exemple goamz . Il a des références internes partout.
Erik Aigner le
1
Regardez le ec2paquet - il a une launchpad.net/goamz/awsimportation. Les packages awset les ec2packages résident dans le même référentiel, donc lorsqu'ils sont forkés, ils ne référenceront pas le package correct (celui du fork).
Erik Aigner le
1
Le fork fera référence au même package que la source du fork. Qu'est-ce qui est incorrect là-dedans? Le fork va compiler, il va construire, il fera la même chose qu'avant. Quelle est alors la définition de «package incorrect»? Notez que le langage Go, tout comme son système de construction, n'a aucune connaissance des référentiels, seulement des packages.
zzzz

Réponses:

84

Pour gérer les demandes d'extraction

  • bifurquer un référentiel github.com/someone/repoversgithub.com/you/repo
  • télécharger le code original: go get github.com/someone/repo
  • Soyez là: cd "$(go env GOPATH)/src"/github.com/someone/repo
  • activez le téléchargement sur votre fork: git remote add myfork https://github.com/you/repo.git
  • importez vos modifications dans votre dépôt: git push myfork

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

Pour utiliser un package dans votre projet

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

Ivan Rave
la source
à partir de quel dossier dois-je faire git remote add? cloner de la fourche? cloner de l'original? de l'intérieur aller?
lapots
1
@lapots exécutez la commande dans le dépôt d'origine (c'est-à-dire $ GOPATH / src / github.com / somone / repo)
will7200
Que faire si je veux ajouter des modifications à un dépôt qui a été forké il y a longtemps?
NA
61

Si vous utilisez des modules go . Vous pouvez utiliser la replacedirective

La replacedirective vous permet de fournir un autre chemin d'importation qui pourrait être un autre module situé dans VCS (GitHub ou ailleurs), ou sur votre système de fichiers local avec un chemin de fichier relatif ou absolu. Le nouveau chemin d'importation de la replacedirective est utilisé sans qu'il soit nécessaire de mettre à jour les chemins d'importation dans le code source réel.

Vous pouvez donc faire ci-dessous dans votre fichier 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.1est la balise sur votre repo. Peut également être fait via CLI

go mod edit -replace="github.com/someone/[email protected]=github.com/you/[email protected]"
Yogesh
la source
4
a très bien fonctionné. Je pense que la seule raison pour laquelle il n'y a pas plus de votes positifs est que les gens n'utilisent pas encore les modules go. J'ai également utilisé cette astuce pour pointer vers un emplacement de fichier vers un autre répertoire sur mon poste de travail où j'avais des modifications locales sur lesquelles je travaillais. Je supprimerais simplement ma ligne "replace" une fois que j'aurais poussé mes modifications locales dans github.
lazieburd
^ 100% d'accord. Votez les gens.
Andrew Arrow
2
oh, mais "maître" n'a pas fonctionné pour moi. J'ai dû écrire la v0.0.1 ou une version spécifique là-bas.
Andrew Arrow
1
Vous pouvez également go mod edit -replace directement sur la ligne de commande: go mod edit -replace="github.com/someone/[email protected]=github.com/you/[email protected]". Les deux @v...sont facultatifs.
Joel Purra
Ne serait-il pas cool d'avoir un go.mod.localou go.mod.devdont le rôle est de remplacer réellement la voie de l'importation pour le développement local? Je veux dire, vous n'oublierez jamais de supprimer le vilain "remplacer" parce que vous n'auriez pas à le faire.
Manuel
21

Une façon de résoudre ce problème est celle suggérée par Ivan Rave et http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html - la manière de bifurquer.

Une autre solution consiste à contourner le comportement du golang . Lorsque vous go get, golang dispose vos répertoires sous le même nom que dans l'URI du référentiel, et c'est là que le problème commence.

Si, à la place, vous émettez le vôtre git clone, vous pouvez cloner votre référentiel sur votre système de fichiers sur un chemin nommé d'après le référentiel d'origine.

En supposant que le référentiel d'origine se trouve github.com/awsome-org/toolet que vous le chargez github.com/awesome-you/tool, vous pouvez:

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 est parfaitement heureux de continuer avec ce dépôt et ne se soucie pas vraiment que certains répertoires supérieurs portent le nom awesome-orgalors que git remote l'est awesome-you. Toutes les importations pour awesome-orgsont résolues via le répertoire que vous venez de créer, qui est votre ensemble de travail local.

Plus longuement, veuillez consulter mon article de blog: Forking Golang repositories sur GitHub et gérer le chemin d'importation

edit : chemin de répertoire fixe

Shlomi Noach
la source
3
Je suis d'accord que c'est la «meilleure» solution pour cela. Mais ce serait vraiment bien de voir comment les gens gèrent ce flux de travail lorsqu'ils exécutent l'application Go dans un conteneur Docker. J'apprends le golang et je voulais ajouter une petite fonctionnalité à une bibliothèque que j'utilise lorsque j'ai rencontré ce mal de tête en le testant avant de créer une demande d'extraction.
Joakim
6

Si votre fork n'est que temporaire (c'est-à-dire que vous avez l'intention de le fusionner), faites simplement votre développement in situ, par exemple dans $GOPATH/src/launchpad.net/goamz.

Vous utilisez ensuite les fonctionnalités du système de contrôle de version (par exemple git remote) pour faire du référentiel amont votre référentiel plutôt que celui d'origine.

Il est plus difficile pour d'autres personnes d'utiliser votre référentiel avec go getmais beaucoup plus facile pour son intégration en amont.

En fait, j'ai un référentiel pour goamz pour lp:~nick-craig-wood/goamz/goamzlequel je développe exactement de cette manière. Peut-être que l'auteur le fusionnera un jour!

Nick Craig-Wood
la source
1
Juste pour que je comprenne les implications de faire cela, si je suis allé dans cette voie, quand quelqu'un fait un go getde mon dépôt, toutes mes déclarations d'importation et autres refléteront toujours github.com/original_authoret seront donc cassées ... correct?
parker.sikand
@ parker.sik et oui c'est correct. Cette technique est la meilleure pour les choses que vous avez l'intention de fusionner en amont, pas pour vous en servir. Si vous avez l'intention de bifurquer le paquet de façon permanente, utilisez la technique de l'autre réponse.
Nick Craig-Wood
4

Voici un moyen qui fonctionne pour tout le monde:

Utilisez github pour accéder à "my / repo" (juste un exemple):

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

Répétez chaque fois que vous améliorez le code:

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

Pourquoi? Cela vous permet d'avoir votre repo avec lequel tout go getfonctionne. Il vous permet également de maintenir et d'améliorer une branche qui convient à une pull request. Il ne gonfle pas git avec "vendeur", il préserve l'historique, et les outils de construction peuvent en donner un sens.

user1212212
la source
Légère correction: lancez github.com/golang/tools/cmd/gomvpkg/main.go et cette commande déplace .git, alors enregistrez-la ailleurs et restaurez-la par la suite.
user1212212
aussi il est possible d'utiliser simplement le plugin mvn-golang qui rend une certaine automatisation dans le traitement des dépendances comme dans l'exemple github.com/raydac/mvn-golang/tree/master/mvn-golang-examples/…
Igor Maznitsa
3

La réponse à cela est que si vous créez un dépôt avec plusieurs packages, vous devrez renommer tous les chemins d'importation appropriés. C'est en grande partie une bonne chose car vous avez forké tous ces packages et les chemins d'importation devraient refléter cela.

Jeremy Wall
la source
3
J'ai brûlé plus de temps que je ne veux l'admettre en diagnostiquant cela lors de ma première contribution à un projet Go. "Tous les tests réussissent, y compris ceux que j'ai écrits pour tester de manière exhaustive les nouvelles fonctionnalités. Qu'est-ce qui ne va pas ?!" Connaissez-vous des outils disponibles pour faciliter ce point d'achoppement pour les débutants?
Sage Mitchell
3
Une fois que j'ai tout compris il était facile de résoudre en utilisant find, xargset sed, mais il serait utile d'avoir un flux de travail sans douleur qui fonctionne de manière cohérente pour tout le monde.
Sage Mitchell
@JakeMitchell gomvpkgpeut faire les changements de noms plus facilement / mieux. go get golang.org/x/tools/cmd/gomvpkgalors gomvpkg -help.
Dave C
3
Cette réponse me paraît totalement irréalisable. Séduire les fichiers de projet d'un projet fourchu, c'est fou? Que faites-vous lorsque vous créez une pull request? La réponse d'Ivan Rave me semble être une bien meilleure solution.
Ivan P
8
Est-ce toujours ainsi que Go-lang fonctionne? C'est tellement insensé que ce n'est pas drôle ... Soit être convivial en amont, soit convivial en aval, mais pas les deux. C'est un énorme défaut de conception à mon avis pas si humble, probablement fait par des personnes qui ne collaborent pas trop entre projets. #FAIL #GOLANG
Niclas Hedhman
1

Pour automatiser ce processus, j'ai écrit un petit script. Vous pouvez trouver plus de détails sur mon blog pour ajouter une commande comme "gofork" à votre 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
heralight
la source
Devrait golangêtre changé goforken ligne 4?
Dan Tenenbaum
bien vu! réparer!
heralight
1

Utiliser ensemble la vente et les sous-modules

  1. Fork la lib sur github (go-mssqldb dans ce cas)
  2. Ajoutez un sous - module qui clone votre fork dans votre dossier fournisseur mais qui a le chemin du repo en amont
  3. Mettez à jour vos importdéclarations dans votre code source pour qu'elles pointent vers le dossier du fournisseur (sans le vendor/préfixe). Par exemple vendor/bob/lib=>import "bob/lib"

Par exemple

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

mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb

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

Pourquoi

Cela résout tous les problèmes dont j'ai entendu parler et que j'ai rencontré en essayant de comprendre cela moi-même.

  • Les références de package internes dans la bibliothèque fonctionnent maintenant car le chemin est inchangé depuis l'amont
  • Une nouvelle extraction de votre projet fonctionne car le système de sous-modules l'obtient de votre fork au bon commit mais dans le chemin du dossier en amont
  • Vous n'avez pas besoin de savoir comment pirater manuellement les chemins ou jouer avec l'outillage go.

Plus d'informations

Tim Abell
la source
0

dans votre Gopkg.tomlfichier, ajoutez ces blocs ci-dessous

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

Donc, il utilisera le fourchu project2à la place degithub.com/globalsign/mgo

msonowal
la source
Le Gopkg.tomlfichier n'est utilisé que pour deplequel cette question ne mentionne pas du tout. Les nouveaux projets Go devraient utiliser des modules Go à la place (et les projets basés sur les dépôts existants de l'OMI devraient également migrer).
Dave C
Je ne connaissais pas cette fonctionnalité de dép, et votre réponse m'a sûrement aidé :)
Veger
0

Vous pouvez utiliser la commande go get -fpour obtenir un dépôt fourchu

Kevin
la source