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
어떤 새로운 포크 수입 경로는 포크 (fork) 전에 이미 깨진하지 된 깨진되지 않습니다.
zzzz

11
실망 시켜서 미안하지만 사실이 아닙니다. 하위 패키지가 절대 URL을 통해 가져 오기에서 참조되는 경우이 가져 오기는 포크에서 중단됩니다 (또는 적어도 잘못된 패키지 참조).
Erik Aigner 2013 년

2
예 : goamz . 모든 곳에서 내부 참조가 있습니다.
Erik Aigner 2013 년

1
ec2패키지를 보세요 - launchpad.net/goamz/aws가져 오기가 있습니다. 패키지 awsec2패키지 는 모두 SAME 저장소에 있으므로 분기 될 때 올바른 패키지 (포크에있는 패키지)를 참조하지 않습니다.
Erik Aigner 2013 년

1
포크는 포크의 소스와 동일한 패키지를 참조합니다. 그게 뭐가 틀렸나 요? 포크는 컴파일되고 빌드되며 이전과 동일한 작업을 수행합니다. 그렇다면 '잘못된 패키지'의 정의는 무엇입니까? 빌드 시스템 인 Go 언어 는 리포지토리를 인식 하지 않고 패키지 만 인식합니다.
zzzz

답변:


84

pull 요청을 처리하려면

  • 저장소 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? 포크에서 복제 하시겠습니까? 원본에서 복제 하시겠습니까? 이동에서?
lapots

1
@lapots는 원래 저장소 (예 : $ GOPATH / src / github.com / somone / repo)에서 명령을 실행합니다.
will7200

오래 전에 분기 된 저장소에 변경 사항을 추가하려면 어떻게해야합니까?
NA

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 % 동의합니다. 사람들에게 투표하십시오.
Andrew Arrow

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...선택 사항입니다.
Joel Purra 19

로컬 개발을위한 가져 오기 경로를 실제로 대체하는 것이 go.mod.local또는 go.mod.dev누구의 역할 을 갖는 것이 멋지지 않습니까? 내 말은, 당신은 그럴 필요가 없기 때문에 추악한 "교체"를 제거하는 것을 결코 잊지 않을 것입니다.
Manuel

21

이를 해결하는 한 가지 방법은 Ivan Rave와 http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html ( 포킹 방법 )이 제안한 것입니다.

또 다른 방법은 golang 동작 을 해결하는 입니다. 당신이 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-orggit remote가 awesome-you. 에 대한 모든 가져 오기 awesome-org는 방금 만든 디렉터리 인 로컬 작업 집합을 통해 다시 요청됩니다.

자세한 내용은 내 블로그 게시물 : GitHub에서 Golang 리포지토리 포크 및 가져 오기 경로 관리 를 참조하세요.

편집 : 고정 디렉토리 경로


3
이것이 "최상의"해결책이라는 데 동의합니다. 하지만 Docker 컨테이너에서 Go 앱을 실행할 때 사람들이이 워크 플로를 어떻게 관리하는지 보는 것은 정말 좋을 것입니다. 저는 golang을 배우고 있으며 Pull Request를 만들기 전에 테스트하면서 골치 아픈 문제가 발생했을 때 사용중인 라이브러리에 작은 기능을 추가하고 싶었습니다.
조아킴

6

포크가 일시적인 경우 (예 : 병합하려는 경우) 현장에서 개발을 수행하십시오 (예 : $GOPATH/src/launchpad.net/goamz.

그런 다음 버전 제어 시스템의 기능 (예 :) git remote을 사용하여 업스트림 저장소를 원래 저장소가 아닌 저장소로 만듭니다.

다른 사람들이 저장소를 사용하기 어렵게 go get하지만 업스트림에 통합하기가 훨씬 쉽습니다.

사실 저는 lp:~nick-craig-wood/goamz/goamz정확히 그런 방식으로 개발하는 goamz 저장소를 가지고 있습니다 . 아마도 저자는 언젠가 그것을 병합 할 것입니다!


1
그래서 나는 이것을하는 것의 의미를 이해합니다.이 경로를 갔다면 누군가가 go get내 저장소에서 a 를 수행하면 내 모든 수입 명세서 등이 여전히 반영 github.com/original_author되어 깨질 것입니다 ... 맞습니까?
parker.sikand 2014 년

@ parker.sik 그리고 네 맞습니다. 이 기술은 사용하기위한 것이 아니라 업스트림으로 병합하려는 항목에 가장 적합합니다. 패키지를 영구적으로 포크하려면 다른 답변의 기술을 사용하십시오.
Nick Craig-Wood

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작동하는 저장소를 가질 수 있습니다 . 또한 풀 리퀘스트에 좋은 브랜치를 유지하고 향상시킬 수 있습니다. "공급 업체"로 부 풀리지 않고 기록을 보존하며 빌드 도구가이를 이해할 수 있습니다.


약간의 수정 : github.com/golang/tools/cmd/gomvpkg/main.go를 실행하면이 명령이 .git을 이동하므로 다른 곳에 저장하고 나중에 복원하십시오.
user1212212


3

이에 대한 대답은 여러 패키지가있는 저장소를 포크하는 경우 모든 관련 가져 오기 경로의 이름을 바꿔야한다는 것입니다. 이러한 패키지를 모두 포크하고 가져 오기 경로에이를 반영해야하므로 이는 대체로 좋은 것입니다.


3
Go 프로젝트에 대한 첫 번째 기여에서 이것을 진단하는 것보다 더 많은 시간을 소비했습니다. "새로운 기능을 철저히 테스트하기 위해 작성한 테스트를 포함하여 모든 테스트를 통과했습니다. 무엇이 잘못 되었나요?!" 초보자를위한 이러한 걸림돌을 완화 할 수있는 도구가 있는지 알고 있습니까?
Sage Mitchell

3
나는 그것을 알아 낸 후이를 사용하여 해결하기 쉬웠다 find, xargs그리고 sed있지만, 지속적으로이 모두를 위해 작동하는 고통이없는 워크 플로우를 가지고 도움이 될 것이다.
Sage Mitchell

@JakeMitchell gomvpkg은 이름 변경을 더 쉽고 / 더 잘 할 수 있습니다. go get golang.org/x/tools/cmd/gomvpkg그런 다음 gomvpkg -help.
Dave C

3
이 대답은 완전히 비현실적이라고 생각합니다. 분기 된 프로젝트에서 프로젝트 파일을 sed-ing하는 건 미친 짓이야? 풀 리퀘스트를 생성 할 때 무엇을합니까? Ivan Rave의 대답은 나에게 훨씬 더 나은 해결책처럼 보입니다.
이반 P

8
이것이 여전히 Go-lang이 작동하는 방식입니까? 이건 너무 미쳐서 재미 있지 않아요 ... 업스트림 친화적이든 다운 스트림이든 상관 없지만 둘다는 아닙니다. 그것은 너무 많은 교차 프로젝트를 공동 작업하지 않는 사람들이 만든 그렇게 겸손하지 않은 내 의견으로는 거대한 디자인 결함입니다. #FAIL #GOLANG
니클라스 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

4 행 golang으로 변경 해야합니까 gofork?
Dan Tenenbaum

잘 보였습니다! 고치다!
heralight

1

공급 업체 및 하위 모듈을 함께 사용

  1. github에서 lib 포크 (이 경우 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의 내부 패키지 참조가 이제 작동합니다.
  • 프로젝트의 새로운 체크 아웃은 서브 모듈 시스템이 올바른 커밋의 포크에서 가져 오지만 업스트림 폴더 경로에 있기 때문에 작동합니다.
  • 경로를 수동으로 해킹하거나 이동 도구를 엉망으로 만드는 것을 알 필요가 없습니다.

더 많은 정보


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 모듈을 사용해야합니다 (그리고 IMO 기존 dep 기반 프로젝트도 마이그레이션해야 함).
Dave C

:) 나는이 DEP 기능에 대해 알고하지 않았다, 당신의 대답은 반드시 저를 도와
Veger

0

명령 go get -f을 사용 하여 분기 된 저장소를 얻을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.