How to rename or relocate a public Go module
Import paths should remain stable. But what if you need to rename or relocate a public repository that others rely on?
For instance, you have this module:
github.com/myorg/mymodule
and you want to move this module to:
gitlab.com/otherorg/mymodule
The solution: Don't move it. Copy it. (Via fork or otherwise).
The point is that all clients cannot upgrade to the new path at the same time. There will always be clients that continue using the old module for a while.
So copy the module over to the new path but don't touch the original module. Or rather, update the README with a deprecation note, and consider marking the module as deprecated. ( The “Deprecation” subsection in the Go mod reference shows how to do this.)
Tip: Use canonical import paths
Did I say don't move the module? Well, there is an option for that, too:
Canonical import paths, a.k.a. vanity import paths.
However, this option requires planning in advance. A canonical import path can be different from the repository URL. The go get
command (and related commands) retrieve the final repository location by sending a specifically crafted HTTP GET to the server that the canonical path points to.
The full process is described
here, but as a quick example, let's take a look at my what
module, a package for adding ad-hoc logging code.
The canonical import path is
appliedgo.net/what. The go
command queries that URL for a pointer to the true repo. The page appliedgo.net/what contains a Meta tag that points to
github.com/appliedgocode/what (plus information about the brand of the version control system), where the go
command then can download the module.
(If you are curious, open appliedgo.net/what, open the browser tools, and search the HTML head for go-import
. You will find this Meta tag: <meta name="go-import" content="appliedgo.net/what git https://github.com/appliedgocode/what">
.)
With this canonical import path in place, if I ever want to move the module to another repository, I would simply update the Meta tag at appliedgo.net/what.
Easy-peasy. And appliedgo.net/what
is so much more elegant and easier to memorize than github.com/appliedgocode/what
.