Fixed Crate Versions vs. Moving Targets

One thing that becomes evident after moving private crates to a registry server is how big of an advantage it is for a specific crate version, once published, to remain available at the registry server in perpetuity.

A lot of the problems that arise from the use of path- and git-based dependencies can be categorized as specifying a dependency to a "moving target" rather than a fixed version.

In the case of path-based dependencies, there is no version, there is only what code is currently residing in a local directory at build time. This is inherently unstable, and can easily lead to problems such as confusion about which version of the code was present in the directory at build time.

Git-based dependencies suffer from the same problem -- instead of the moving target being a local directory, it's a git branch. Changes, including possibly breaking changes, can be pushed to a branch at any time. What exists in master branch today is unlikely to be the same as what exists in master branch next week.

In contrast, a registry server makes each specific crate version -- a fixed point in the code history which was verified to build immediately before publishing -- remains available in perpetuity, without needing to perform any work (i.e. checking out the correct branch, etc.) for that version to be available.

In practice, choosing between a set of fixed crate versions rather than the moving targets of path-based or git-based dependencies solves a surprising number of problems relating to dependency management of private crates.