Both Dart and Go support decentralized package distribution. One is able to directly adopt an existing git repository as dependency, easing the effort of distributing packages.

Sometimes we might expect more fine-grained control on what to pull from a git repository. For example, to lock a package’s version, we would specify a particular tag, commit or branch name to pull from. Or if it’s a mono-repo, we would choose a sub-directory from the repository root. This post summarizes how to achieve these purposes in both languages.

## Dart

dart pub add has several options related to adding a git repository as dependency. To start with, one should specify the repository’s URL with the --git-url argument

This command adds a dependency named repo by pulling from https://github.com/user/repo.git. The --git-path argument can be provided to specify from which sub-directory of the repository dart should read from

Dart can also read from a specific git commit or branch (but not tags!), for which one should supply the --git-ref argument

## Go

Go modules are born to be based on git repositories. We regularly use go get to add a dependency

, which pulls a remote repository, and parses its content as a Go module. A tag @vX.Y.Z can be suffixed to specify a particular git tag like

, which instead pulls from a tag named vX.Y.Z. There’s a detailed description on version tag’s semantics at Go Modules Reference - Versions. Straightforwardly, we can append its path after the repository’s name if a sub-directory is to be used

Things become a little trickier when both sub-directory and tag are wanted. Literally, we might type a command as below

It, however, will fail with a complaint go: github.com/user/repo/subdir@vX.Y.Z: invalid version: unknown revision subdir/vX.Y.Z. What’s happening is, when a sub-directory is involved, Go modules will seek for a tag name with a pattern like subdir/vX.Y.Z, instead of aforementioned vX.Y.Z. This enables multiple sub-repos in a large mono-repo to individually tag their own version. We are hence required to rename the tag as subdir/vX.Y.Z, which should work as intended.