But if you have an internal version that's used in lots of modules, it's probably better to use an import path under your own organization, to avoid confusion.
Does this account for the scenario where you have a dependency of a dependency? For example, if I'm patching a bug in something that several of my upstream dependencies import, do I have to fork/replace everything in that chain to get it to do the right thing?
Debian packages can Replace each other too, and that's certainly an option for managing this scenario, but I feel it's often more disruptive— it's a much more invasive change to have to go in and mutate the package name all over the place, and then it's harder to unwind it later when upstream merges and releases my change and I don't need my fork any more. Maybe this is better in go land?
Not an expert (I just read the docs), but if you only have one binary that you ship, or all your binaries are in the same module, then it looks like a single "replace" directive will do the right thing.
If your binaries are spread across multiple modules, each one would need its own replace directives, so you'd have a bit of duplication. (But maybe this independence is good, since you can upgrade them one at a time?)
If you're publishing a library and don't control the binaries (this is something your customers build) then it looks like "replace" isn't going to work (it's under their control, so they have to do it). If you need to control the exact versions used by your library, you'll want to look into vendoring.
No, you don't need to fork/replace everything in the chain. A `replace` in the top-level `go.mod` applies in all places where that package is used.
Doing a fork/replace on everything in the chain will have no affect; `replace` is only obeyed for the top-level `go.mod`, `replace` in dependencies is ignored.
Debian packages can Replace each other too, and that's certainly an option for managing this scenario, but I feel it's often more disruptive— it's a much more invasive change to have to go in and mutate the package name all over the place, and then it's harder to unwind it later when upstream merges and releases my change and I don't need my fork any more. Maybe this is better in go land?