如何正确fork一个Golang模块

如何正确fork一个Golang模块 我创建了一个Go模块(cobra)的分支,编写了一些新代码和测试。然后在我的客户端应用程序中,我尝试使用我的新分支,但由于我的方法过于简单,出现了各种错误和问题。我意识到分叉一个Go项目比我想象的要复杂一些(我只使用Go几周,所以还在学习阶段)。

因此,我需要知道如何做两件事:

  1. 首先,在分叉中必须做什么,以确保客户端能够正确使用它。
  2. 在客户端项目中需要进行哪些更改,以切换到我的cobra分叉版本。

在网上搜索并没有给我完整的答案,涵盖上述两点。

我已经能够在我的分叉中运行包含我更改的测试,但我还没有推送这些更改。我意识到我已经犯了一个错误,因为我没有更改本地模块路径。也就是说,我的go.mod文件中的路径仍然指向原始路径(github.com/spf13/cobra),而不是我的分叉github.com/snivilised/cobra,但这并不影响在本地运行测试。我也没有更改分叉源代码中的任何导入路径。

尝试临时更改路径似乎不起作用。我想我需要执行某种“go mod edit -replace”操作,但我认为这只是一个临时措施,不应该被提交,所以我完全困惑了,需要了解这方面知识的人告诉我正确的工作流程是什么。

谢谢。


更多关于如何正确fork一个Golang模块的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

如果我的理解正确,你或许可以保持代码中的导入语句不变,并在你分支的 go.mod 文件中添加 replace 指令,但不要在 PR 中提交修改后的 go.mod 文件。

更多关于如何正确fork一个Golang模块的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的,明白了,谢谢 @mje。那么这仅仅意味着在提交 PR 之前,我必须记得在 fork 仓库中还原 mod replace。这听起来很合理,谢谢,我会尝试一下并反馈结果。

我还没有更改本地模块路径。也就是说,我的 go.mod 文件中的路径仍然指向原始地址(github.com/spf13/cobra),而不是我的复刻版本……我也没有更改复刻源代码中的任何导入路径。

除了为你所做的任何 API 更改修改客户端代码外,这些正是你需要为 #2 做的事情。为了临时测试,你可以在你的 go.mod 中添加一个 replace 指令来指向你的复刻版本。

你好,@mje,感谢你的回复。我找到了一些文章作为参考,因为这件事并不像你想象的那么简单。我遇到的第一个问题是关于复刻本身。由于我想提交一个拉取请求,我不能简单地在复刻仓库中更改导入路径,因为这些路径对于拉取请求来说将是错误的。我需要在这里做一些事情,既要对拉取请求友好,同时又要从复刻路径而不是原始路径导入。具体该怎么做,目前还是个谜。

我确实理解你关于客户端部分的建议,即将导入路径替换为复刻仓库的路径。这部分很直观,我猜这里我会使用 replace 指令来修改复刻模块的路径。但是,我到底该对复刻仓库本身做什么呢!

在 Go 中正确 fork 一个模块需要修改模块路径并正确处理依赖关系。以下是具体步骤:

1. 在分叉仓库中必须做的更改

修改 go.mod 文件

将模块路径改为你的分叉地址:

# 在分叉仓库目录中执行
go mod edit -module github.com/snivilised/cobra

更新所有内部导入(如果需要)

如果你的分叉代码中有导入原始 cobra 包的地方,需要更新为新的模块路径:

// 将原来的
import "github.com/spf13/cobra"

// 改为
import "github.com/snivilised/cobra"

推送更改到远程仓库

git add .
git commit -m "Update module path to forked version"
git push origin main

2. 在客户端项目中切换到分叉版本

方法一:使用 replace 指令(推荐用于开发)

在客户端项目的 go.mod 中添加 replace 指令:

module your-client-app

go 1.21

require (
    github.com/spf13/cobra v1.7.0
)

replace github.com/spf13/cobra => github.com/snivilised/cobra v0.0.0

然后更新依赖:

go mod tidy

方法二:直接导入分叉版本

修改客户端代码中的导入:

import "github.com/snivilised/cobra"

更新 go.mod:

go get github.com/snivilised/cobra@latest
go mod tidy

完整示例

分叉仓库的 go.mod:

module github.com/snivilised/cobra

go 1.21

require (
    github.com/inconshreveable/mousetrap v1.1.0
    github.com/spf13/pflag v1.0.5
    golang.org/x/text v0.13.0
)

客户端项目的 go.mod:

module myapp

go 1.21

require github.com/snivilised/cobra v0.0.0

replace github.com/snivilised/cobra => ../path/to/local/fork  // 本地开发时使用
// 或者
replace github.com/spf13/cobra => github.com/snivilised/cobra v0.0.0-20240101000000-abcdef123456

工作流程建议

  1. 开发阶段:使用 replace 指令指向本地分叉目录
  2. 测试阶段:推送分叉到远程,使用远程 replace
  3. 生产使用:直接导入分叉版本,移除 replace 指令
# 开发时本地替换
go mod edit -replace github.com/spf13/cobra=../my-cobra-fork

# 切换到远程分叉
go mod edit -replace github.com/spf13/cobra=github.com/snivilised/cobra@v1.7.0-forked

这样确保你的分叉可以正确被客户端项目使用,同时保持清晰的版本管理。

回到顶部