<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SOW:Pigsty 出品的软件仓库管理器 on SOW</title><link>https://sow.pgsty.com/zh/</link><description>Recent content in SOW:Pigsty 出品的软件仓库管理器 on SOW</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://sow.pgsty.com/zh/index.xml" rel="self" type="application/rss+xml"/><item><title>SOW 0.2:文档站上线</title><link>https://sow.pgsty.com/zh/blog/release/sow-docs-launch/</link><pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/blog/release/sow-docs-launch/</guid><description>&lt;p&gt;&lt;strong&gt;发布日期:&lt;/strong&gt; 2026-08-04 · &lt;strong&gt;版本:&lt;/strong&gt; &lt;code&gt;sow 0.2.0-dev&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;SOW 是 &lt;a href="https://pigsty.cc"&gt;Pigsty&lt;/a&gt; 出品的自包含软件仓库管理器:一个静态 Go 二进制,
在 Linux 与 macOS 上创建并维护 APT(DEB)与 YUM(RPM)软件仓库,而且整件事都由它
自己完成 —— 从不调用 &lt;code&gt;createrepo_c&lt;/code&gt;、&lt;code&gt;dpkg-scanpackages&lt;/code&gt;、&lt;code&gt;reprepro&lt;/code&gt; 或
&lt;code&gt;modifyrepo_c&lt;/code&gt;。没有常驻服务,没有数据库,也没有需要一并安装的东西。名字取自那个动词:
把软件包播进仓库,仓库自己长起来。&lt;/p&gt;</description></item><item><title>下载与安装</title><link>https://sow.pgsty.com/zh/download/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/download/</guid><description>&lt;p&gt;SOW 是一个静态可执行文件。没有安装器,没有要装的软件包,没有要启用的服务,
在你第一次运行需要状态的命令之前,它甚至不会创建任何目录。安装它 = 把一个文件
放进 &lt;code&gt;PATH&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>sow create</title><link>https://sow.pgsty.com/zh/docs/reference/cli/create/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/create/</guid><description>&lt;p&gt;&lt;code&gt;sow create&lt;/code&gt; 把一个已经放着 &lt;code&gt;.rpm&lt;/code&gt; / &lt;code&gt;.deb&lt;/code&gt; 的目录变成平面仓库（flat repository）：在包旁边写出索引
文件。它就是 Plain 平面模式的全部——没有 &lt;code&gt;sow.yml&lt;/code&gt;、没有 SQLite、不做工作区发现。本页讲清扫描规则、
原子的 &lt;code&gt;--pigsty&lt;/code&gt; 兼容操作，以及 &lt;code&gt;--sign-with&lt;/code&gt; 的 RPM 包签名。&lt;/p&gt;</description></item><item><title>安装 SOW</title><link>https://sow.pgsty.com/zh/docs/start/install/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/start/install/</guid><description>&lt;p&gt;SOW 以单个静态可执行文件分发。所谓安装,就是把这一个文件放到 &lt;code&gt;PATH&lt;/code&gt; 上的某个位置。
没有软件包要装,没有服务要启用,在你执行第一条需要落盘的命令之前,它也不会创建任何
状态目录。&lt;/p&gt;</description></item><item><title>搭建 YUM 仓库</title><link>https://sow.pgsty.com/zh/docs/tutorial/yum-repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/tutorial/yum-repo/</guid><description>&lt;p&gt;这篇教程从零搭出一个生产形态的 RPM 仓库。做完你会得到:一个工作区(Workspace),里面有名为
&lt;code&gt;pigsty&lt;/code&gt; 的仓库(Repository)和一个 &lt;code&gt;el9&lt;/code&gt; Dist,由单一包池(pool)渲染出两个架构视图,
debuginfo 噪声被过滤掉,每个包只保留最新版本,以及一份 &lt;code&gt;dnf&lt;/code&gt; 能吃的 &lt;code&gt;.repo&lt;/code&gt; 文件。&lt;/p&gt;</description></item><item><title>能力总览</title><link>https://sow.pgsty.com/zh/docs/feature/overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/overview/</guid><description>&lt;p&gt;SOW 是一个自包含的软件仓库管理器:一个纯静态 Go 二进制(&lt;code&gt;CGO_ENABLED=0&lt;/code&gt;),在 Linux 与 macOS 上创建并维护 APT(DEB)与 YUM(RPM)软件仓库。它不调用 &lt;code&gt;createrepo_c&lt;/code&gt;、&lt;code&gt;dpkg-scanpackages&lt;/code&gt;、&lt;code&gt;reprepro&lt;/code&gt; 或 &lt;code&gt;modifyrepo_c&lt;/code&gt;,也不需要常驻进程。本页是覆盖面的地图,后续各页解释每一块是怎么实现的。&lt;/p&gt;</description></item><item><title>设计原则</title><link>https://sow.pgsty.com/zh/docs/design/principles/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/principles/</guid><description>&lt;p&gt;SOW 首先不是一个“元数据生成器”，而是一个所有权与状态迁移系统，只是它的输出恰好是
APT 与 RPM 仓库。下面这些原则让整套系统保持可推理。&lt;/p&gt;
&lt;h2 id="每个持久事实只有一个主人"&gt;每个持久事实只有一个主人&lt;/h2&gt;
&lt;p&gt;每类持久事实都只有一个作用域与权威：&lt;/p&gt;</description></item><item><title>Plain 平面仓库</title><link>https://sow.pgsty.com/zh/docs/feature/plain/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/plain/</guid><description>&lt;p&gt;&lt;code&gt;sow create&lt;/code&gt; 接手一个已经装着 &lt;code&gt;.rpm&lt;/code&gt; 和 &lt;code&gt;.deb&lt;/code&gt; 的目录,就地给它写一份索引。它的全部工作就是这个。本页讲清楚它读什么、写什么、承诺绝不碰什么,以及执行到一半被杀掉时怎么活下来。&lt;/p&gt;</description></item><item><title>sow init</title><link>https://sow.pgsty.com/zh/docs/reference/cli/init/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/init/</guid><description>&lt;p&gt;&lt;code&gt;sow init&lt;/code&gt; 创建根级 &lt;code&gt;sow.yml&lt;/code&gt; 与私有状态目录 &lt;code&gt;.sow/&lt;/code&gt;，这两样东西让一个目录成为工作区（Workspace）。
它同时也是手写配置的收敛命令：如果 &lt;code&gt;sow.yml&lt;/code&gt; 里已经声明了 Repository 与 Dist，&lt;code&gt;init&lt;/code&gt; 会把还不存在
的那些实体化出来，已完成的原样跳过。&lt;/p&gt;</description></item><item><title>搭建 APT 仓库</title><link>https://sow.pgsty.com/zh/docs/tutorial/apt-repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/tutorial/apt-repo/</guid><description>&lt;p&gt;这篇教程搭一个托管 APT 仓库:按源码包分组的 Debian 风格包池、每个架构一份索引、&lt;code&gt;by-hash&lt;/code&gt;
索引副本(让客户端不会撞上重建),以及现代 deb822 与传统单行两种客户端配置。&lt;/p&gt;</description></item><item><title>快速上手</title><link>https://sow.pgsty.com/zh/docs/start/quickstart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/start/quickstart/</guid><description>&lt;p&gt;这一页大约五分钟。你会把若干软件包放进一个目录,执行一条命令,用 HTTP 暴露出去,
然后用 &lt;code&gt;dnf&lt;/code&gt; 或 &lt;code&gt;apt&lt;/code&gt; 从中安装。不需要配置文件、不需要工作区、不需要数据库 ——
Plain 平面模式只是在软件包旁边写出索引,除此之外什么都不做。&lt;/p&gt;</description></item><item><title>sow.yml 配置参考</title><link>https://sow.pgsty.com/zh/docs/reference/config/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/config/</guid><description>&lt;p&gt;&lt;code&gt;sow.yml&lt;/code&gt; 是 Managed 托管工作区(Workspace)唯一的配置文件。它位于工作区根目录,
声明存在哪些仓库(Repository)与 Dist,并保存每次构建都要执行的成员策略与签名设置。
Plain 平面模式(&lt;code&gt;sow create&lt;/code&gt;)完全不读它。&lt;/p&gt;</description></item><item><title>系统模型</title><link>https://sow.pgsty.com/zh/docs/design/model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/model/</guid><description>&lt;p&gt;SOW 刻意把模型分层：配置表达意图，数据库记录有主状态，公共树是确定性投影。
任何一层都不能悄悄替代另一层。&lt;/p&gt;
&lt;h2 id="对象层级"&gt;对象层级&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── Repository
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Package Object
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Dist
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ └── Membership -&amp;gt; Package Object
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Desired 状态
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── Built Generation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── Retained Generation 引用
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── Publication Target
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── Repository + provider + prefix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="workspace"&gt;Workspace&lt;/h3&gt;
&lt;p&gt;Workspace 提供发现、配置与协调，拥有 &lt;code&gt;sow.yml&lt;/code&gt;、私有 &lt;code&gt;.sow/&lt;/code&gt; 目录和稳定锁路径；
它不是包体去重域。&lt;/p&gt;</description></item><item><title>Managed 工作区</title><link>https://sow.pgsty.com/zh/docs/feature/managed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/managed/</guid><description>&lt;p&gt;当同一个仓库要维护好几个月 —— 包成批到达、由策略决定谁留下、事后还得说清楚什么时候变了什么 —— 你需要的是 Managed 模式。本页讲三层模型、它产出的布局,以及命令怎么判断你说的是哪个仓库、哪个 Dist。&lt;/p&gt;</description></item><item><title>sow config</title><link>https://sow.pgsty.com/zh/docs/reference/cli/config/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/config/</guid><description>&lt;p&gt;&lt;code&gt;sow config&lt;/code&gt; 有两个只读子命令。&lt;code&gt;config check&lt;/code&gt; 是对 &lt;code&gt;sow.yml&lt;/code&gt; 的全量预检——每次手工改完配置以及在
CI 里都该跑一遍。&lt;code&gt;config show&lt;/code&gt; 打印 SOW 实际算出来的配置，用它确认默认值、继承的架构与规范化别名
是不是按你预期解析的。&lt;/p&gt;</description></item><item><title>包引用</title><link>https://sow.pgsty.com/zh/docs/reference/package-ref/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/package-ref/</guid><description>&lt;p&gt;&lt;code&gt;sow rm&lt;/code&gt;、&lt;code&gt;sow show&lt;/code&gt;、&lt;code&gt;sow where&lt;/code&gt; 都接受一个 &lt;code&gt;PACKAGE&lt;/code&gt; 参数。本页定义你能在那里写什么。
三条命令共用同一套文法,只有对&lt;strong&gt;歧义名称&lt;/strong&gt;的处理不同。&lt;/p&gt;
&lt;p&gt;这里的内容与 &lt;code&gt;sow add&lt;/code&gt; 无关 —— &lt;code&gt;add&lt;/code&gt; 接受的是文件系统路径,不是包引用。&lt;/p&gt;</description></item><item><title>仓库签名</title><link>https://sow.pgsty.com/zh/docs/tutorial/signing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/tutorial/signing/</guid><description>&lt;p&gt;没签名的仓库,链路上任何人都能改写。这篇教程把这个洞堵上:生成签名钥、配置 SOW 对发布内容签名、
手工验证签名,再打开客户端强制校验,让 &lt;code&gt;dnf&lt;/code&gt; 与 &lt;code&gt;apt&lt;/code&gt; 拒绝一切校验不过的东西。&lt;/p&gt;</description></item><item><title>单包体仓库</title><link>https://sow.pgsty.com/zh/docs/design/single-payload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/single-payload/</guid><description>&lt;p&gt;0.3 开发线调整了 RPM 物理布局，但保留 v0.2 确立的所有权模型。它的目标很精确：在一个
Repository 及其每个发布前缀内，每个 live Package Object 恰好只有一条包体路径。&lt;/p&gt;
&lt;div class="alert alert-warning" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;开发线设计&lt;/div&gt;
&lt;p&gt;本页描述已经落入 0.3 源码的布局；已发布 v0.2 的操作参考仍然使用 C2 view-local 硬链接。
迁移现有 v0.2 仓库前，请先读&lt;a href="https://sow.pgsty.com/zh/docs/design/evolution/"&gt;设计演进&lt;/a&gt;。&lt;/p&gt;</description></item><item><title>第一个工作区</title><link>https://sow.pgsty.com/zh/docs/start/workspace/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/start/workspace/</guid><description>&lt;p&gt;这一页大约十分钟,从零搭出一个 Managed 托管仓库:一个工作区、一个仓库、其中的一个 RPM Dist
与一个 DEB Dist,往两边添加软件包,最后看清楚磁盘上到底生成了什么。
与 &lt;a href="https://sow.pgsty.com/zh/docs/start/quickstart/"&gt;Plain 平面模式&lt;/a&gt;不同,工作区会&lt;strong&gt;记住&lt;/strong&gt;你的意图 ——
你按名字增删软件包,而不是靠搬文件,SOW 只重建真正变化的部分。&lt;/p&gt;</description></item><item><title>sow repo</title><link>https://sow.pgsty.com/zh/docs/reference/cli/repo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/repo/</guid><description>&lt;p&gt;一个仓库（Repository）独占一份 &lt;code&gt;pool/&lt;/code&gt;、一份 &lt;code&gt;dists/&lt;/code&gt;、一个 SQLite 数据库与一个私有状态目录。它是
锁、事务恢复、Generation 编号与 Changeset 的边界——跨仓库不去重，也不承诺跨仓库原子提交。
&lt;code&gt;sow repo&lt;/code&gt; 管理的就是这条边界。&lt;/p&gt;</description></item><item><title>包池与架构视图</title><link>https://sow.pgsty.com/zh/docs/feature/views/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/views/</guid><description>&lt;p&gt;列一遍 Managed 仓库,你会在三个不同路径上看到同一个包文件,而 &lt;code&gt;du&lt;/code&gt; 坚称它只占一份空间。这不是错觉,也不是符号链接。本页讲清楚这套投影模型 —— 它为什么存在、保证了什么,以及它对你的文件系统提出的那一条约束。&lt;/p&gt;</description></item><item><title>仓库布局</title><link>https://sow.pgsty.com/zh/docs/reference/layout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/layout/</guid><description>&lt;p&gt;SOW 的磁盘布局是&lt;strong&gt;固定&lt;/strong&gt;的。没有 &lt;code&gt;path:&lt;/code&gt; 配置项,没有模板,也没有办法把仓库挪到别处 ——
每一条路径都由工作区根目录、一个已校验的名称和固定的相对片段推导而来。
本页给出完整地图,让你清楚哪些该发布、哪些该复制、哪些必须留在本地。&lt;/p&gt;</description></item><item><title>对外服务</title><link>https://sow.pgsty.com/zh/docs/tutorial/serving/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/tutorial/serving/</guid><description>&lt;p&gt;SOW 产出的是一个静态目录。任何能提供静态文件的东西都能服务它——没有守护进程、没有应用服务器、
没有运行时组件。这篇教程讲清楚该把 web 服务器指向哪里、一份实测过的 Nginx 配置、一条命令的本地
预览,以及怎么把整棵树搬到够不着构建机的主机上。&lt;/p&gt;</description></item><item><title>发布与恢复</title><link>https://sow.pgsty.com/zh/docs/design/publication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/publication/</guid><description>&lt;p&gt;构建与发布是两个独立状态迁移。构建产生与 target 无关的 Generation；发布把该 Generation
应用到一个供应商前缀，并记录足以在不猜测的前提下恢复的证据。&lt;/p&gt;
&lt;h2 id="所有权拆分"&gt;所有权拆分&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Repository 作用域&lt;/th&gt;
					&lt;th&gt;Target prefix 作用域&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Package Object&lt;/td&gt;
					&lt;td&gt;Publication Attempt&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Desired 与 Built 状态&lt;/td&gt;
					&lt;td&gt;Applied Checkpoint&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Generation 与 Changeset&lt;/td&gt;
					&lt;td&gt;远端 inventory&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;retained 包体/元数据引用&lt;/td&gt;
					&lt;td&gt;grace 与删除证据&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;这项拆分避免把 filesystem 发布成功当成 R2 的证据，也避免一个 target 的半完成尝试污染另一个。&lt;/p&gt;</description></item><item><title>核心概念</title><link>https://sow.pgsty.com/zh/docs/start/concepts/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/start/concepts/</guid><description>&lt;p&gt;跑完&lt;a href="https://sow.pgsty.com/zh/docs/start/quickstart/"&gt;快速上手&lt;/a&gt;、搭完&lt;a href="https://sow.pgsty.com/zh/docs/start/workspace/"&gt;第一个工作区&lt;/a&gt;之后,
只需要少数几个概念就能解释 SOW 的其余全部行为。本页讲清楚这些:两种模式与如何选型、
Managed 模型的四个层级,以及&amp;quot;你要什么&amp;quot;与&amp;quot;当前发布了什么&amp;quot;之间的分离。&lt;/p&gt;</description></item><item><title>sow dist</title><link>https://sow.pgsty.com/zh/docs/reference/cli/dist/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/dist/</guid><description>&lt;p&gt;Dist 是一个仓库内、单一格式（&lt;code&gt;rpm&lt;/code&gt; 或 &lt;code&gt;deb&lt;/code&gt;）的具名包集合。客户端指向的就是它。一个仓库可以同时拥有
RPM Dist 与 DEB Dist，两者共用一份 &lt;code&gt;pool/&lt;/code&gt;，但渲染进完全独立的 &lt;code&gt;dists/&lt;/code&gt; 子树。&lt;/p&gt;</description></item><item><title>成员策略</title><link>https://sow.pgsty.com/zh/docs/feature/policy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/policy/</guid><description>&lt;p&gt;策略回答的是这个问题:&amp;ldquo;我把整个构建目录倒进了这个 Dist,但我不想要 debuginfo 包,而且每个包只留最新版本。&amp;ldquo;两条规则完成这件事,它们按固定顺序执行,并且作用于&lt;strong&gt;完整候选集&lt;/strong&gt;,而不是你这次恰好 add 的那几个包。&lt;/p&gt;</description></item><item><title>从 createrepo_c / reprepro 迁移</title><link>https://sow.pgsty.com/zh/docs/tutorial/migration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/tutorial/migration/</guid><description>&lt;p&gt;你已经有一个仓库了。这篇教程换掉构建它的工具,而不弄坏消费它的客户端——包括没人会提醒你的那些
残留文件,以及应该在动手前而不是动手后知道的布局差异。&lt;/p&gt;</description></item><item><title>兼容性边界</title><link>https://sow.pgsty.com/zh/docs/design/compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/compatibility/</guid><description>&lt;p&gt;“兼容”太宽泛，不足以成为工程结论。一个包可能安装成功，但镜像工具拒绝同一份元数据；
一棵树可能在 POSIX 磁盘上去重，上传后却变成多个完整对象。因此 SOW 把兼容性拆成独立门禁。&lt;/p&gt;</description></item><item><title>退出码</title><link>https://sow.pgsty.com/zh/docs/reference/exit-codes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/exit-codes/</guid><description>&lt;p&gt;每条 &lt;code&gt;sow&lt;/code&gt; 命令都以七个退出码之一结束。它们是稳定的、对所有命令一致,
并且就是设计来给脚本做分支判断的 —— 区分&amp;quot;这件事失败了&amp;quot;和&amp;quot;这件事被正确地拒绝了&amp;quot;,
正是设置多个非零码的全部意义。&lt;/p&gt;</description></item><item><title>JSON 输出</title><link>https://sow.pgsty.com/zh/docs/reference/json/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/json/</guid><description>&lt;p&gt;所有产出数据的命令都接受 &lt;code&gt;--json&lt;/code&gt;。输出是 stdout 上的&lt;strong&gt;一行&lt;/strong&gt;版本化信封 ——
不管是哪条命令产生的,都能直接管道给 &lt;code&gt;jq&lt;/code&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow status --json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;schema&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sow.cli/v1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;ok&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;repository&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pigsty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;operation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;result&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;repository&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pigsty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;clean&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;ready_to_copy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;desired_revision&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;built_generation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;dirty_dists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[],&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;dirty_reasons&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[],&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;pending&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;count&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;bytes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;recent_operation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8632724976452398569&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;add&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;state&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;done&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-08-04T04:07:17.665377Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026-08-04T04:07:18.293848Z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;repository_locked&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="nt"&gt;&amp;#34;errors&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:[]}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(此处为便于阅读做了折行,实际输出是一行。)&lt;/p&gt;</description></item><item><title>sow add</title><link>https://sow.pgsty.com/zh/docs/reference/cli/add/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/add/</guid><description>&lt;p&gt;&lt;code&gt;sow add&lt;/code&gt; 是主要的写入路径。它解析你指定的包，从包头推导格式与架构，执行 Dist 的成员策略，并且——
除非你加 &lt;code&gt;--skip&lt;/code&gt;——在返回前重建全部受影响的索引。命令退出码为 &lt;code&gt;0&lt;/code&gt; 时，客户端已经能看到新包了。&lt;/p&gt;</description></item><item><title>签名模型</title><link>https://sow.pgsty.com/zh/docs/feature/signing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/signing/</guid><description>&lt;p&gt;客户端会对一个仓库提两个不同的问题,SOW 用两套彼此独立的机制分别回答。把它们混为一谈,是&amp;quot;我明明签了名,&lt;code&gt;dnf&lt;/code&gt; 还是报错&amp;quot;这类问题最常见的来源 —— 所以本页先把两者拆开。&lt;/p&gt;</description></item><item><title>设计演进</title><link>https://sow.pgsty.com/zh/docs/design/evolution/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/design/evolution/</guid><description>&lt;p&gt;SOW 的旧文档来自三套实质不同的系统。缺少版本边界时，互相矛盾的结论看起来像同时成立。
本页保留有价值的决策，同时明确它们各自的作用域。&lt;/p&gt;
&lt;h2 id="时间线"&gt;时间线&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;版本线&lt;/th&gt;
					&lt;th&gt;主要问题&lt;/th&gt;
					&lt;th&gt;物理模型&lt;/th&gt;
					&lt;th&gt;处置&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;V1 实验（2026-07）&lt;/td&gt;
					&lt;td&gt;纳管 Pigsty 既有 APT/YUM 树与远端发布流程&lt;/td&gt;
					&lt;td&gt;Git/CAS、route-aware 投影、edge/provider 契约&lt;/td&gt;
					&lt;td&gt;归档为研究与实现证据&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;v0.2.0&lt;/td&gt;
					&lt;td&gt;交付紧凑的本地 Plain + Managed 仓库管理器&lt;/td&gt;
					&lt;td&gt;根 Pool + C2 view-local RPM 硬链接&lt;/td&gt;
					&lt;td&gt;已发布；操作文档继续在线&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;0.3 开发线&lt;/td&gt;
					&lt;td&gt;每个 Repository/target prefix 只发布一份正典包体&lt;/td&gt;
					&lt;td&gt;根 Pool + 纯元数据 view + target-scoped 发布&lt;/td&gt;
					&lt;td&gt;源码已实现；发布证据待完成&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="v1-留下了什么"&gt;V1 留下了什么&lt;/h2&gt;
&lt;p&gt;V1 大范围探索了既有仓库纳管、远端发布、供应商 fencing、边缘鉴权、迁移、恢复与大仓库证据。
它具体的 Git/CAS/route 模型大多已被替换，但几条原则保留下来：&lt;/p&gt;</description></item><item><title>sow rm</title><link>https://sow.pgsty.com/zh/docs/reference/cli/rm/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/rm/</guid><description>&lt;p&gt;&lt;code&gt;sow rm&lt;/code&gt; 把包从你选定的 Dist 的期望成员集中拿掉，并默认立即重建受影响的索引。它绝不从 &lt;code&gt;pool/&lt;/code&gt; 删除
字节——成员关系与内容是两个概念，而且系统没有垃圾回收。&lt;/p&gt;
&lt;h2 id="语法"&gt;语法&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sow rm PACKAGE... [-c|--check] [--skip] [-j|--jobs N] [-C|--workdir DIR] [-r|--repo NAME] [-d|--dist NAME]... [-T|--timeout DUR | -N|--no-wait] [--json]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="参数"&gt;参数&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;参数&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
					&lt;th&gt;默认&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-c, --check&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只预览：计算并打印方案，不写任何东西&lt;/td&gt;
					&lt;td&gt;关闭&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--skip&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只更新期望状态，不构建&lt;/td&gt;
					&lt;td&gt;关闭&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-j, --jobs N&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;并发 worker 数&lt;/td&gt;
					&lt;td&gt;逻辑 CPU 数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-C, --workdir DIR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;工作区发现的起始目录&lt;/td&gt;
					&lt;td&gt;当前目录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-r, --repo NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;选择一个仓库&lt;/td&gt;
					&lt;td&gt;按选择规则&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-d, --dist NAME&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;选择一个 Dist；可重复&lt;/td&gt;
					&lt;td&gt;按选择规则&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-T, --timeout DUR&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;等待锁的最长时间；&lt;code&gt;0&lt;/code&gt; 无限等待&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;-N, --no-wait&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;锁被占用时立即失败&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;--json&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;输出版本化 JSON envelope&lt;/td&gt;
					&lt;td&gt;false&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;--check&lt;/code&gt; 与 &lt;code&gt;--skip&lt;/code&gt; 互斥：&lt;/p&gt;</description></item><item><title>兼容性</title><link>https://sow.pgsty.com/zh/docs/reference/compatibility/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/compatibility/</guid><description>&lt;p&gt;SOW 输出的是标准 rpm-md 与 Debian archive 元数据,所以问题不在于客户端&amp;quot;能不能&amp;quot;读,
而在于哪些客户端&lt;strong&gt;确实被验证过&lt;/strong&gt;。本页给出实测矩阵、二进制支持的平台,
以及少数几条忽略了就会出问题的约束。&lt;/p&gt;</description></item><item><title>事务与恢复</title><link>https://sow.pgsty.com/zh/docs/feature/transactions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/transactions/</guid><description>&lt;p&gt;仓库工具翻车通常是两种难堪的姿势之一:留下一份指向已不存在的包的索引,或者把自己的数据库搞坏、只能从头重建。SOW 的设计目标是让这两件事都不可能发生,本页讲清楚支撑这一点的机制。&lt;/p&gt;</description></item><item><title>sow ls / show / where</title><link>https://sow.pgsty.com/zh/docs/reference/cli/query/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/query/</guid><description>&lt;p&gt;三条命令回答三个不同的问题。&lt;code&gt;ls&lt;/code&gt; 列出一个 Dist 应该包含什么，&lt;code&gt;show&lt;/code&gt; 详细查看某一个包对象，&lt;code&gt;where&lt;/code&gt;
找出哪些 Dist（跨仓库）在提供某个包。三者都是只读的，不取写锁，共用同一套 &lt;code&gt;--json&lt;/code&gt; envelope。&lt;/p&gt;</description></item><item><title>可观测与审计</title><link>https://sow.pgsty.com/zh/docs/feature/audit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/feature/audit/</guid><description>&lt;p&gt;四条只读命令回答四个不同的问题,而且每一条都拒绝替另外三条干活。这种分离是刻意的:一个偶尔会把整仓哈希一遍的&amp;quot;便宜状态检查&amp;quot;没法放进循环,一个会偷偷修东西的&amp;quot;完整校验&amp;quot;没法当证据用。&lt;/p&gt;</description></item><item><title>sow build / status / check / changes</title><link>https://sow.pgsty.com/zh/docs/reference/cli/build/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/build/</guid><description>&lt;p&gt;一个概念一条命令。&lt;code&gt;status&lt;/code&gt; 是便宜的读，&lt;code&gt;check&lt;/code&gt; 是完整校验，&lt;code&gt;build&lt;/code&gt; 是唯一会改变公开树的命令，
&lt;code&gt;changes&lt;/code&gt; 给出两代之间的物理文件差分。四条放在一页，因为你几乎总是一起用它们。&lt;/p&gt;</description></item><item><title>sow log</title><link>https://sow.pgsty.com/zh/docs/reference/cli/log/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/docs/reference/cli/log/</guid><description>&lt;p&gt;仓库内的每条写命令，都会&lt;em&gt;先&lt;/em&gt;在该仓库的 SQLite 中提交一条应用级 Operation，然后才产生任何外部文件
副作用。这条记录让崩溃恢复成为可能——而当 Operation 进入终态之后，同一条记录就是你的审计轨迹。
&lt;code&gt;sow log&lt;/code&gt; 读的就是它。&lt;/p&gt;</description></item><item><title>页面不存在</title><link>https://sow.pgsty.com/zh/404/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://sow.pgsty.com/zh/404/</guid><description>&lt;p&gt;你访问的页面可能已被移动、删除,或从未存在。&lt;/p&gt;
&lt;p&gt;请回到&lt;a href="https://sow.pgsty.com/zh/docs/"&gt;文档首页&lt;/a&gt;,或使用 &lt;kbd&gt;⌘K&lt;/kbd&gt; / &lt;kbd&gt;Ctrl K&lt;/kbd&gt; 站内搜索。&lt;/p&gt;</description></item></channel></rss>