Package References
sow rm, sow show, and sow where all take a PACKAGE argument. This page defines
what you may write there. The same grammar applies to all three commands; only the
handling of an ambiguous name differs.
Nothing here applies to sow add, which takes filesystem paths, not references.
The five forms
| Form | Example | Matches |
|---|---|---|
| Content digest | sha256:d06d7f23b9cf...b98b1229 | Exactly one package object |
| RPM coordinate | rpm:pev2-0:1.23.0-1.noarch | Exactly one RPM |
| DEB coordinate | deb:libpq5=18.3-1.pgdg12+1:amd64 | Exactly one DEB |
| Filename | pev2-1.23.0-1.noarch.rpm | The package stored under that filename |
| Bare name | pev2 | Every version and architecture of that name |
The first three are exact: they name one object and either hit it or fail. The last two are conveniences that may match more than one object.
You never have to construct these by hand. sow ls prints the digest and the coordinate
of every package, in a form you can paste straight back into another command:
sow ls -d el9
repository=pigsty dists=el9 dirty=false
SHA256 COORDINATE DISTS BUILT_DISTS POOL_PATH
sha256:ceb1b8660f8bc1fe59fb7a28e750e19a1ccd010a254a50e82328adb5818a5943 rpm:blackbox_exporter-0:0.28.0-1.aarch64 el9 el9 pool/b/blackbox_exporter/blackbox_exporter-0.28.0-1.aarch64.rpm
sha256:5759c643a789631346e3ed315a696a0118f81f7cc3c65e5a4385a876983d3a18 rpm:blackbox_exporter-0:0.28.0-1.x86_64 el9 el9 pool/b/blackbox_exporter/blackbox_exporter-0.28.0-1.x86_64.rpm
sha256:d06d7f23b9cfc6aedaab7b60c8e890cda020efe84f1f246243414862b98b1229 rpm:pev2-0:1.23.0-1.noarch el9 el9 pool/p/pev2/pev2-1.23.0-1.noarch.rpm
Content digest
sha256:<64 lowercase hex digits>
The SHA-256 of the complete stored package bytes. This is the strongest reference SOW has: it is the object’s identity, so it can never be ambiguous.
sow where sha256:d06d7f23b9cfc6aedaab7b60c8e890cda020efe84f1f246243414862b98b1229
{"reference":"sha256:d06d7f23...b98b1229","locations":[{"repository":"pigsty","dists":["el9"],"built_dists":["el9"],"sha256":"d06d7f23...b98b1229","coordinate":"rpm:pev2-0:1.23.0-1.noarch"}]}
The digest must be complete and lowercase. There is no prefix matching and no case-folding — a short or uppercase digest is a usage rejection, not a failed lookup:
operation rejected: managed: operation rejected: sha256 reference requires 64 lowercase hexadecimal digits
Note that this digest covers the bytes as stored. If a repository re-signs RPM
payloads, the digest of the object differs from the digest of the file you handed to
sow add.
RPM coordinate
rpm:<name>-<epoch>:<version>-<release>.<arch>
The full NEVRA, prefixed with rpm:. Every component is required, including the epoch —
0 when the package has none.
sow where 'rpm:pev2-0:1.23.0-1.noarch'
Quote it in a shell: NEVRA contains a colon, and history expansion or path completion can otherwise mangle it.
Both the prefix and the epoch are load-bearing. Dropping either turns the string into a bare-name lookup that finds nothing:
sow where 'rpm:pev2-1.23.0-1.noarch'
operation rejected: managed: operation rejected: package reference "rpm:pev2-1.23.0-1.noarch" was not found in the selected Workspace scope
The architecture component is the one from the RPM header: x86_64, aarch64, or
noarch. It is not the canonical family — a noarch package is written noarch here,
even though SOW classifies it internally as neutral.
DEB coordinate
deb:<package>=<version>:<architecture>
The Debian identity triple, prefixed with deb:. The version is the complete Debian
version including epoch and revision; the architecture is the ecosystem name (amd64,
arm64, all), not the canonical family.
sow where 'deb:libpq5=18.3-1.pgdg12+1:amd64'
All three parts are required. deb:libpq5=18.3-1.pgdg12+1 without an architecture does
not match anything.
Filename
The complete filename of the package as stored, including the extension:
sow where 'pev2-1.23.0-1.noarch.rpm'
sow where 'libpq5_18.3-1.pgdg12+1_amd64.deb'
This is the easiest form to type when you are looking at a directory listing. It is not an identity, though: filename is not what SOW uses to tell packages apart, and two distinct objects could in principle carry the same name. Prefer a coordinate or a digest in scripts.
Bare name
Just the binary package name:
sow where pev2
What this means depends on the command:
sow rmtreats it as every version and native architecture of that name in the selected distributions. This is intentional — removing a package usually means removing all of it. Preview first with-c:sow rm libpq5 -d trixie -c{"repository":"pigsty","desired_revision":10,"built_generation":10,"dirty":false,"check":true, "removed":[{"dist":"trixie","sha256":"310611d0...","coordinate":"deb:libpq5=18.2-1.pgdg12+1:amd64","name":"libpq5"}, {"dist":"trixie","sha256":"4b526223...","coordinate":"deb:libpq5=18.3-1.pgdg12+1:amd64","name":"libpq5"}, {"dist":"trixie","sha256":"cadeb929...","coordinate":"deb:libpq5=18.3-1.pgdg12+1:arm64","name":"libpq5"}], ...}sow showandsow whererequire it to identify exactly one object. They describe a single package, so a name matching several is refused with the candidate list:operation rejected: managed: operation rejected: package reference "libpq5" is ambiguous: deb:libpq5=18.2-1.pgdg12+1:amd64 sha256:310611d0fea1ce82644f48d90d485c60738b21e52ab5a60e1de43875bdfef601, deb:libpq5=18.3-1.pgdg12+1:amd64 sha256:4b5262231787caf1f367f5c8705a8a03d3176c31a15e6096946d50514db128be, deb:libpq5=18.3-1.pgdg12+1:arm64 sha256:cadeb9294901ac5ae6228bd3471c444cc288d9894af0dd0730909596d9dfcefbEvery candidate is printed with both its coordinate and its digest, so the fix is to copy one of them back onto the command line.
What does not work
A NEVRA without the rpm: prefix looks like a coordinate but is parsed as a bare name,
and bare names do not contain epochs or architectures:
sow rm 'pev2-0:1.23.0-1.noarch' -d el9 -c
operation rejected: managed: operation rejected: package reference not found: package reference "pev2-0:1.23.0-1.noarch" matches no Desired Membership
There is also no glob, no regex, no version range, and no --all flag. If you want to
select a set of packages by pattern, that is membership policy
in sow.yml, not a command-line selector. The command line only ever names packages that
already exist.
Scope
A reference is resolved within a scope, and the scope is set by the usual selection flags, not by the reference:
| Command | Default scope | Narrow with |
|---|---|---|
sow rm | The selected distributions of the selected repository | -r, -d (required when several exist) |
sow show | The selected repository | -r, -d |
sow where | Every repository in the workspace | -r, -d |
sow where is the one that searches broadly — use it when you know a package exists
somewhere but not where. sow show describes one object in one repository in full detail.
The two commands also word their misses differently, which tells you which one you ran:
# rm — the reference resolved, but nothing in the selected dists matches it
operation rejected: ... package reference "nosuchpkg" matches no Desired Membership
# show / where — nothing in the searched scope matches at all
operation rejected: ... package reference "nosuchpkg" was not found in the selected Workspace scope
Coordinates and identity
The coordinate forms above are the logical identity of a package, and SOW enforces that
one coordinate maps to at most one content object inside a repository. Adding a different
file under a coordinate that already exists is a hard conflict — SOW will not silently
pick a winner, and there is no --replace.
Two packages that differ only in signature therefore still collide, because the coordinate
is the same. If you re-sign a package for real, bump its release; if you are re-adding the
identical input, SOW recognizes it and reports reused.
See also
sow rm— removal, preview, and batch semanticssow ls/show/where— the query commands- Exit Codes —
6covers both “no match” and “ambiguous”