假设我的项目中 require 了一个第三方 github.com/old/dep 模块,依赖的版本是 v1.2.3 。
现在我对该依赖 fork 出来做了修改,放到 github.com/new/dep 上,然后我想依赖于新的模块。
不知道推荐的方法是什么?
方法 1:仍然 require github.com/old/dep v1.2.3 ,用 replace 将其替换到新的地址?那版本号怎么处理呢?毕竟我有了新的提交,打 tag 肯定不能是 v1.2.3 了,重新 tag 为 v1.2.4 ,这该如何写 replace 呢?以后不会混乱么?
方法 2:干脆和 github.com/old/dep 模块分离,直接在项目中 require github.com/new/dep 。但是这个项目中有很多源代码是直接 import 的 github.com/old/dep/xxx 。使用 gohack ?
1
kuanat 2023-12-13 19:02:40 +08:00 1
用你方法一的思路,replace 是支持版本号映射的,比如
require github.com/old/dep v1.2.3 => github.com/new/dep v1.2.4 另外也可以 github.com/new/dep@dev 指定分支。 你说的方法二有个问题:就像你说的,如果它包含子模块,这些子模块还是会引用 /old/dep ,那 fork 出来需要修改的地方就非常多。 具体怎么做取决于 /new/dep 这个 fork 的定位。仅仅打个补丁,需要定期合并上游 /old/dep 那就用方法一。如果是要大刀阔斧另起炉灶,那就方法二吧。 关于版本号,我的建议是保持一致。就是你在 v1.2.3 上的改版,就用 v1.2.3 发布,特别是你仅仅要做个小改动的时候。不过这个事情不重要,你清楚对应的版本就可以了,而且几乎做不到一一对应。 另外这里要注意 go sum 机制,改版 /new/dep 发布之后 github.com/new/dep v1.2.3 校验信息会被 google 缓存。这个时候如果对 /new/dep 做了多次修改,就只能升版本或者换分支了。 |
2
javalaw2010 2023-12-13 19:07:17 +08:00
如果你的 fork 打算 merge 到上游,用 replace ,如果你的改动比较私人,不希望或者不太可能合并到上游,就用/new/dep
|
3
vultr 2023-12-15 08:40:16 +08:00
如果可以的话,最好是合并回上游。
|
5
kuanat 2023-12-17 18:15:21 +08:00 1
@zhwguest #4
可能之前没表达清楚,这里应该不存在冲突的。 比如说你一开始用的 /old/dep 依赖,那么在 go.mod 里面就会有 require github.com/old/dep v1.2.3 只要你不升级依赖,那么整个项目一直会用 /old/dep v1.2.3 然后你 fork 了 /new/dep 出来,并且给 /new/dep 打了版本 v1.2.3 这个时候增加一句 replace github.com/old/dep v1.2.3 => github.com/new/dep v1.2.3 就可以了。 假如 /old/dep 更新过后,你发现没有必要用 /new/dep 了,那就把上面的删掉,然后更新依赖到比如说 /new/dep v1.2.4 ,不管是 go get -u 还是手动修改 go.mod ,最终 go.mod 都会是 require github.com/old/dep v1.2.4 假如你还是要用 /new/dep ,不管你是继续在 /new/dep 上修改,还是合并了 /old/dep 的上游更新,然后打了 v1.2.4 的版本,只需要修改 replace 这一句变成 replace github.com/old/dep v1.2.3 => github.com/new/dep v1.2.4 但是 require 那一句还保持 require github.com/old/dep v1.2.3 也就是说,只要你不主动升级 /old/dep 的版本,那就只需要修改 replace 的目标版本。至于 /new/dep 怎么打版本 tag 是随意的。 之前说保持版本号一致只是应对两种场景,一种是 /new/dep 作为临时开发测试分支,有可能被 /old/dep 合并,当 /old/dep 更新之后又会回到 /old/dep 上面去。另一种是 /new/dep 是因为某些原因不可能被 /old/dep 合并,但是修改可以通过 patch 的方式自动化,上游 /old/dep 发布一个版本,下游 /new/dep 就发布一个对应的修改版。 默认情况下,github 的 fork 功能,是不带 tag 的,所以你可以在 fork 里面重新任意标记版本。假如你不想处理 tag 相关的事情,也可以完全不理会。这种情况下,replace 后面改成 /new/dep 就行了,go.sum 会用 v0.0.0-timestamp-commit_hash 的方式来唯一确定。 |
7
zhwguest OP @kuanat 关于 tag 的问题还想请教一下,比如上游 git 的版本是 1.2.3 ,我现在将其 tag 为 1.2.4 ,那下次上游 tag 升级为 1.2.4 的时候,我的 tag 不是和它冲突了么?所以是不是本身不建议 tag ?
|
8
zhwguest OP |
9
kuanat 362 天前 1
@zhwguest #8
git tag 是与 repo 相关的,/old/dep 和 /new/dep 是相互独立的,我不确定你说的冲突,只要同一个 repo 里面 tag 唯一就可以。 一般不建议 => 左边带版本,除非你的项目永远不升级依赖。如果左边带版本 v1.2.3 ,就代表只有这个特定版本会被替换,但是上游更新 v1.2.4 然后你 go get -u 升级了依赖,那 v1.2.3 的替换就失效了。不带版本就是所有版本都会替换。 右边只有替换成本地 repo 的时候才可以不带版本。 |
10
liaoyuan6666 362 天前
@zhwguest 要指定 hast 或版本的
|
11
liaoyuan6666 362 天前
hash 打错了
|