Improving semver for git dependencies

I'm wondering whether versioning of git dependencies in Cargo could be improved. Currently:

dep = { git = "url", version = "0.17" }

will only look at the latest commit, and fail if the version doesn't match. OTOH if you select a commit with rev, then it'll be locked forever, and cargo update won't update it. This makes versioning and updates of git deps a second-class citizen compared to registries.

Would it make sense to make Cargo smarter about this? For example, scan commits in a given branch to find a matching version.

The repository owner can tag revisions by major version number, and then move the tag when publishing a backwards-compatible release:

dep = { git = "url", version = "0.17", tag = "dep-0.17" }

This is the solution. Altho we do wonder, is there any way to require signed commits?

That still looks like a workaround to me. A standard usage of git is to tag releases, and never ever change the tag.

1 Like

I find it surprising that version is allowed with a git dep. I've always considered that git dependencies are versioned via tag/branch/rev instead of version; tag and rev are ~equivalent to an =x.y.z version, branch would commonly be a ^x.y.z version where each major version has a branch, and rev is also used by the lockfile to record the exact version chosen. My expectation for a scheme like @2e71828 mentions would be that you use branch = "0.17.x" and the repository owner updates that to the latest 0.17.* tag as they are published.

This is how it works with a lockfile, the branch is scanned for the rev recorded in the lockfile.


The reason is that git clients never re-fetch tags, so changing them is strongly discouraged.

See git-tag: On re-tagging.

1 Like

I'm asking about the improvement, because at my workplace we're evaluating whether we should abandon using git dependencies and switch to using an internal registry instead. Cargo's inferior support for versioning and updating git deps has been the main reason for switching.

We currently don't maintain version branches, only tag releases. I see a branch like 0.17.x could work for updates, but it's still inferior to ease of cargo publish, and incompatible cargo outdated. If Cargo scanned branches or tags for available versions, git deps could have feature-parity with registries in this area.