Skip to content

sow prune

Keep the latest RPM versions in a flat repository.

sow prune keeps the highest RPM Epoch/Version/Release for each package name and architecture, rebuilds the flat index, then removes older versions. EVR comparison follows RPM rules, including caret (^) snapshot versions such as 2.0^20250611 < 2.0.1. This command requires SOW 0.7.0 or later.

Synopsis

sow prune DIR [--dry-run] [--protect NAME]... [-j N] [--metadata-timestamp SECONDS] [-T DUR | -N] [--json]

DIR is required. SOW scans only top-level regular binary RPM files. It does not scan subdirectories, discover a Workspace, or read sow.yml.

Preview and prune

Run this command on a local publication source. Clients using cached old indexes may still need older RPMs; account for that in the publication workflow.

sow prune /srv/candidate --dry-run
sow prune /srv/candidate --protect age_18 --protect age_18-llvmjit

--dry-run validates packages and reports candidates without changing files. Use the same protection options for the preview and the actual run.

--protect NAME keeps every version of that exact package name across architectures. It is repeatable and does not accept patterns. Every supplied name must match a package; a typo returns exit code 2 before changes. SOW rejects equal EVRs in the same name and architecture group, including protected groups.

Options

Option Behavior
--dry-run Preview validated removal candidates without writes
--protect NAME Keep all versions of an exact package name; repeatable
-j, --jobs N Package inspection workers; defaults to CPU count
--metadata-timestamp SECONDS Index publication time in Unix seconds; defaults to 0, as for create
-T, --timeout DUR Limit the wait for the directory lock
-N, --no-wait Fail immediately if the directory lock is busy
--json Return the standard JSON envelope

--timeout and --no-wait are mutually exclusive. Prune does not sign packages or repository metadata and does not accept --pigsty or --passfile.

Integrity and recovery

The replacement RPM for each removed version must pass its embedded digest and signature header checks, including RSA, DSA, ECDSA, and EdDSA packets in header signature tag 267 (RPMSIGTAG_DSA). SOW binds those checks and the indexed bytes to a stable file identity, including change time. It checks the replacement before each deletion and again before completion. A detected change stops further deletion, including an in-place rewrite with restored size and modification time.

SOW publishes the filtered index before deleting packages. If an error occurs after index publication or after some deletions, the result reports what changed and returns partial-result exit code 3; interruption returns 130. SOW does not restore already removed packages. Resolve the reported problem, then rerun the same command.

SOW withdraws an existing repo_complete marker during changes (tracking it via .sow-prune-repo-complete) and refreshes it only after completion. That pending state survives interruption. Prune creates no marker when none existed and does not apply create --pigsty package exclusion rules.

JSON result fields include dir, dry_run, kept, candidates (each old path and its latest replacement), removed, index_updated, marker, and noop.

Supported repositories

Prune rejects managed workspaces, DEB packages or indexes, package symlinks, source RPMs, RPM v6 packages, and repositories with repodata/repomd.xml.asc. It also rejects an existing repomd.xml that registers independent metadata SOW does not generate, such as groups, updateinfo, modules, or an unknown type. Prune allows alternate package-index encodings such as SQLite and zchunk.

Exit codes

Code Meaning
0 Prune succeeded, or --dry-run / noop completed
1 Filesystem, package parsing, digest verification, or metadata rendering error
2 Invalid flags, missing directory, or unmatched --protect package name
3 Partial completion: failure after publishing the filtered index or removing at least one RPM
4 Directory lock is held by another process
6 Unsupported repository state (Managed workspace, DEB files, signed repomd.xml, foreign metadata, equal EVRs, or RPM v6)
130 Interrupted by SIGINT or SIGTERM

See also

Table reader