Debian 的 Git 迁移计划

所有与 Debian 源代码交互的人员都应能完全通过 git 完成操作

简而言之:

Debian 正在实施 Git 迁移计划。目前进展顺利,但我们需要帮助,尤其是在推广和更新 Debian 文档方面。

元素周期表

Debian git 迁移项目目标

  1. 所有与 Debian 源代码交互的人员都应能完全通过 git 完成操作。

具体而言:

  1. 所有源代码的审查与编辑均应通过常规 git 操作实现。
  2. 源代码应以 git 数据形式传输交换,而非 tarball 压缩包。git 应成为所有场景的规范格式。
  3. 上游Git历史记录应可追溯地重新发布,作为Debian正式Git版本发布的一部分。
  4. 任何人都无需学习Debian源代码包——这种古怪的机制已被现代版本控制系统淘汰。

目标虽宏大,但我们已取得长足进展!

现有成果与当前状态

我们已取得长足进展,但仍有大量工作待完成——特别是Git过渡团队亟需您协助推广应用、开发者联络及开发文档全面修订。

目标1和4已取得重大突破。目标2部分实现:当前已实现双轨并行。目标3触手可及,但取决于tag2upload(及/或dgit push)的广泛采用。

下游项目和用户可通过Git格式获取任意Debian软件包的源代码。(dgit clone,2013年)。他们可以完全在 git 中处理这些源代码,包括构建二进制文件、合并新版本,甚至自动进行(例如 Raspbian,2016年),且全程无需处理源代码包(例如维基媒体,2025年)。

Debian维护者可完全在Git中维护自己的软件包。他们能从Git获取上游源代码,并在Git中完成打包工作(git-buildpackage,2006)。

每位Debian维护者都能够(也应当!)从Git可靠地以标准格式发布软件包(dgit push, 2013; tag2upload,2025)。这种方式不仅更符合原则,也比dput等dgit之前的工具更便捷,用户体验更佳。

事实上,Debian维护者如今常能仅通过Git分支(无需tar包)将变更发布至Debian。向Debian发布只需推送签名标签即可(tag2upload, 2025)。

Debian维护者可以在Git中维护上游源代码的变更堆栈(gbp pq 2009)。维护者甚至可将此类增量系列作为可直接构建的重置Git分支进行维护,并通过常规git rebase操作编辑变更(git-dpm,2010年; git-debrebase, 2018)

经授权的Debian开发者可对Debian中的任何软件包进行适度更新,即使该软件包由他人维护,也能通过标准便捷的方式在git中完成操作(dgit, 2013)。

Debian贡献者可在Git代码托管平台共享开发进展,通过合并请求、基于Git的代码审查等方式协作(Alioth, 2003; Salsa, 2018)。

核心工程原则

Debian Git迁移项目基于一项核心工程原则:

所有Debian源代码包均可实现与Git之间的无损转换。

为实现从Debian源代码包的迁移,我们需要在旧版dsc方案与新版Git方案之间建立转换通道

该网关必须具备双向性:使用dput等传统工具上传的源代码包需导入规范化的git表示形式;同时开发者准备的git分支也需转换为源代码包,以满足传统下游系统(如Debian存档库和apt source)的需求。

该双向网关由src:dgit实现,使我们能够逐步用基于git的组件替换Debian系统中基于dsc的部分。

dsc与git的对应关系

可靠的双向网关必须定义不变量:

对应于.dsc文件的规范git树,即dpkg-source -x命令生成的树结构

这种规范形式有时称为“dgit视图”。它可能与维护者的git分支不一致,因为许多维护者仍在使用“未应用补丁”的git分支。下文将对此展开说明。

(对于3.0 (quilt)版本的.dsc文件,规范Git树不包含quilt的.pc目录。)

已应用补丁与未应用补丁

规范Git格式采用“已应用补丁”模式,即:

*若Debian修改了上游源代码,通过常规Git克隆规范分支将获得可直接阅读和构建的修改后源代码树。 *

许多 Debian 维护者采用不同的 git 分支格式管理软件包:Debian 对上游源代码的修改实际存储在 debian/patches/ 子目录中的 patch 文件中。

相较于未应用补丁的格式,已应用补丁格式具有多项重要优势:

  • 对非Debian人员而言更熟悉且不易造成困惑。Debian内部人员严重低估了“未应用补丁”模式的特殊性。即便是资深软件开发者也可能因此陷入混乱,甚至意外构建出未包含安全补丁的二进制文件
  • 仅需常规git命令即可完成修改,例如git commit。许多使用patches-unapplied的Debian内部人员仍在使用quilt(1)——这个处理补丁文件的工具布满陷阱!
  • 开发时可同时修改上游代码和Debian打包文件,无需繁琐操作。不必在补丁队列分支和打包分支间反复切换(如gbp pq所要求),也无需“提交”补丁文件等。用户可随时编辑任意文件并通过git commit提交。

缺点在于,采用(诡异的)3.0 (quilt)源代码格式时,debian/patches/目录下的补丁文件必须保持同步更新。不过如今,借助git-debrebasegit-dpm(以及用于NMU的dgit)等工具,处理已应用补丁的git分支变得非常轻松。git-debrebase甚至能高效处理大型补丁堆栈

(对于通常无需补丁的小型软件包,直接使用上游Git分支执行git merge,配合更简化的dsc格式 则完全规避了该问题。)

优先保障Debian用户(及其他外部人员)权益

我们期望每个人都能共享并修改其使用的软件。这意味着应让用户以自身需求为准则,真正获取源代码。

Debian的许多流程默认所有参与者都是内部人士。存在Debian内部人士群体本身无可厚非,人们也理应为自己努力融入的集体产生归属感。但缺乏多元视角可能导致软件背离我们的核心价值观。

我们的源代码实践——尤其是坚持规范化(且系统化)共享的决心——正是Debian价值所在的核心要素。如同Debian安装程序,我们希望源代码能被Debian外部人员所使用。

正因如此,我们选择优先采用更符合主流习惯的git分支格式,即便这种格式在Debian内部使用较少。

部分令人困扰的后果

要求转换过程必须具备双向性无损性上下文无关性可能带来不便。

例如,我们无法支持通过.gitattributes(https://manpages.debian.org/trixie/dgit/dgit.7.en.html#GITATTRIBUTES)在Git检入/检出时修改文件的行为。该配置会使Git树的含义产生依赖于上下文的任意变化,导致Git到源代码包的转换结果不稳定。更糟的是,某些源代码包可能根本无法在Git中表示。

另一个例子:维护者常为其包保留现有Git分支,这些分支由早于dgit的工具生成,其规范性与严谨性不及我们当前的工具。这可能导致Git与dsc之间出现差异,必须在基于Git的上传成功前解决这些差异。

部分维护者使用未应用补丁格式,部分使用已应用补丁格式,这意味着必须进行某种转换以实现标准Git表示法。若选择使用率较低的已应用补丁格式作为规范形式,则意味着大量软件包需要转换其Git表示形式。这也意味着用户及外部访问的{browse,git}.dgit.d.odgit clone分支,未必与Salsa上的维护者分支兼容。用户提交的变更需通过cherry-pick而非合并处理,或转换回维护者格式。好消息是dgit能自动化处理大部分流程,手动操作通常也只是简单的git命令。

以git形式分发源代码

我们的源代码管理应采用常规、现代的git模式。这意味着Debian存档已过时,需由一组git仓库取代。

正式发布至Debian的源代码替代仓库为*.dgit.debian.org。该地址包含自2013年以来所有基于Git上传的完整对象,涵盖每个发布版本的签名标签。

计划通过集中导入所有历史上传内容至Git,最终实现对所有已上传Debian软件包的Git视图覆盖。

传统存档变更时的相关Git数据追踪

当前许多关键源代码管理任务仍通过修改传统Debian存档实现,该系统完全基于dsc文件(及关联的tar包等)运作。因此存档内容仍是重要的数据源。但其架构限制使其无法直接存储Git数据。

为追踪存档库变更,我们于2013年在基于Git的上传包.dsc文件中新增了Dgit:字段。该字段声明了包转换自哪个Git提交,并标注了获取相应Git对象的位置。

因此,当获得基于Git上传的Debian源代码包时,新的Git工具可获取等效的Git对象。若用户需在Git环境中操作,则无需下载任何tar包:可通过Git协议直接从仓库获取Git数据。

签名版本(https://browse.dgit.debian.org/libsdl2-ttf.git/tag/?h=archive/debian/2.24.0%2bdfsg-3)及签名标签(https://browse.dgit.debian.org/libsdl2-ttf.git/tag/?h=debian/2.24.0%2bdfsg-3) 包含标准化元数据,可追溯至上传的Debian贡献者。

为何*.dgit.debian.org并非Salsa

我们需要的是 git 存储库——一个正式、可靠且永久的 git 源代码仓库,用于实际发布至 Debian 的代码。

Gitlab 等 Git 托管平台虽便捷,但其安全性不足, 过多 冗余 漏洞 层出不穷,因此无法成为我们所有源代码的主要且唯一的归档库。(Gitlab公司的“开放核心”商业模式及其持续迭代的开发策略,是关键的根本问题。)

我们的Git仓库虽缺乏合并请求等开发工具功能,但:

  • 它具备可靠性与安全性保障
  • 采用只追加模式:一旦代码被推送,便永久记录。
  • 其访问控制机制完全遵循Debian软件仓库规范。
  • 其引用命名空间标准化且与Debian发行版本对应。
  • 提交操作通过PGP签名而非SSH密钥授权,确保可追溯性。

dgit git仓库已超越Alioth的寿命周期,且极可能延续至Salsa之后。

我们需要同时拥有优质的代码托管平台和 *.dgit.debian.org 正式Git仓库。

路线图

进行中

当前我们正全力推进tag2upload功能。

我们正全力解决剩余问题,确保服务正式版发布前所有关键缺陷得到修复。

未来技术

全存档dsc导入器

当前Git仓库仅存储基于Git的包更新数据(tag2upload和dgit push),传统dput上传数据尚未迁移。这意味着基于git和传统上传方式的包必须通过客户端dgit clone进行处理。

我们将着手将传统上传包迁移至git仓库。

届时下游项目和用户只需执行git clone即可获取任意包的源代码,即使维护者使用dput等传统上传工具亦然。

支持向security.debian.org提交基于git的上传

安全补丁任务尤其需要更完善、更规范的Git应用。基于Git的安全补丁应用与回溯方案,远比处理实际补丁文件便捷得多。

当前虽可借助Git准备安全上传,但常需从dsc导入(缺乏完整Git历史)开始,或需摸清维护者在Salsa平台上非标准化的Git使用习惯。

且无法以git身份正确执行安全发布。

内部Debian消费者转向从git获取源代码

若构建服务器、lintian检查等质量保证工作无需处理源代码包,流程将更为简化。

鉴于git实为规范形式,我们希望这些系统直接使用它。

远期问题展望

数十年来,Debian始终围绕源代码包构建。替代方案需要漫长而复杂的过渡。可以肯定的是,在可预见的未来,源代码包仍将持续获得支持。

不可避免会出现未预见的问题。同时存在可预见的问题:例如某些软件包在git环境下可能运行异常。我们相信能够在问题出现时及时应对。

认知度与普及度——请鼎力相助!

我们和用户对现有技术深感满意,其便捷性与可靠性无可挑剔。

尤其值得称道的是dgit工具——纵使由我们自夸也毫不为过。作为技术人员,我们始终专注于打造优质软件,但在市场推广方面似乎有所欠缺。

关于源代码发布的恳切呼吁

git是首选的修改形式

我们的上游项目几乎都采用git。我们自身也几乎都采用git。但令人震惊的是,许多软件包在Debian中并未以正确、正式且官方的方式发布git历史记录。

所谓“正确”发布源代码为git格式,意味着任何人都能自动可靠地获取并构建与二进制文件完全对应的源代码。检验标准是:能否据此构建衍生版本?

将软件包存放于Salsa的Git仓库通常是明智之举,但仅此不足以满足要求。Salsa上的Git既未强制执行标准分支结构(也不应强制,因此无法自动可靠获取),代码树也非标准格式(因此无法自动构建),且未必与源代码包完全一致。因此仅凭Vcs-Git字段和Salsa的Git仓库,永远无法满足衍生版本的构建需求。

Debian 并未发布源代码!

如今已到该让 Debian 正确发布源代码成为主流实践的时刻。所有维护上游使用 git 的软件包(现今几乎涵盖所有软件包)的维护者,都应基于上游 git 仓库开展工作,并通过 tag2upload 或 dgit 正确发布代码。

这其实毫不困难!现代基于Git的工具集提供了远超以往的上传体验。

常见误解

**dgit push并非gbp pq或quilt的替代方案,tag2upload亦然。**这些上传工具是对现有Git工作流的补充,它们取代并优化了源代码包构建/签名及后续的dput操作。若您在 salsa 使用常规 git 布局且包状态良好,可立即采用 tag2upload 和/或 dgit push。

git-debrebase 则截然不同,它确实提供了管理 git 打包、执行上游 rebase 等操作的替代方案。

文档

Debian的所有文档都需要更新,特别是打包指南,应推荐采用git优先的工作流程。Debian不应将上游项目使用git生成的“发布压缩包”导入git仓库(外部人士发现这种做法时往往深感震惊)。我们应当使用上游git仓库,在git中进行开发,并以git格式规范发布(及公开)。

我们作为git迁移团队,是该技术的专家,可提供优质建议。但我们无力承担必要的教育推广和文档更新工作——尤其考虑到(如同任何变革计划)许多人会持怀疑甚至敌对态度。

因此我们非常需要写作和外联方面的协助。

团队成员

我们自称为Debian git过渡团队。

现成员包括:

  • Ian Jackson。dgit与git-debrebase作者及维护者。tag2upload联合创建者。dpkg-source原始作者,1996年Debian源代码包发明者。Debian技术委员会前成员。
  • 肖恩·惠顿。tag2upload系统联合创建者;git-debpush作者兼维护者。dgit联合维护者。Debian政策联合编辑。Debian技术委员会前主席。

我们承担以下与git迁移相关的职责:

联系方式:

我们主要在 Salsa 进行核心开发工作。

致谢

特别感谢 Joey Hess——他在2013年瓦马库斯设计会议上协助创立了dgit。此后我们获得诸多支持:近期包括推动tag2upload部署的政治支持,更历经多年用户提供的有益错误报告与鼓励话语,以及翻译与代码贡献。

众多人士为支持在Git中处理Debian源代码做出了广泛贡献。我们特别要提及Guido Günther(git-buildpackage开发者);当然还有Alexander Wirt、Joerg Jaspert、Thomas Goirand和Antonio Terceiro(Salsa管理员);以及更早期的Alioth管理员团队。

元素周期表抱枕

本文文字及图片出自 Debian’s git transition,由 WebHek 分享。

共有{112}精彩评论

  1. 作为社区转型的一部分,团队正确地将重点放在加强整个生态系统向Git迁移过程中的沟通与文档建设上。

    我认为Steam在传达哪些软件已适配其新游戏平台、哪些尚未适配方面具有重要价值。验证标记和软件包状态标识等工具对于传达进展、激励维护者升级非常有用。建议设计类似的验证机制,帮助社区轻松追踪进展并推动行动迟缓者。若技术门槛过高,社区将难以推动进程。

    https://www.steamdeck.com/en/verified

  2. 此处存在细微差别。针对既定目标*"所有与Debian源代码交互者(1)应能(2)完全通过git操作*的补充说明:

    (1) “应能”不等于“必须”,用户可自由选择合适工具

    (2) 当然,Debian绝大多数工作已基于git进行,通过Salsa[1](Debian自主托管的GitLab实例)实现。此处更关注git中存储的内容及其与源代码包的关系(即.deb包的构建来源)。例如当前多数Debian git仓库基于上游tar包发布的“pristine-tar”分支开展工作,而非直接使用上游分支。

    [1]: https://salsa.debian.org

    • > 例如,当前多数Debian git仓库基于“pristine-tar”分支开展工作,该分支由上游tarball发布构建而成

      我真心希望各类开源打包系统能尽可能摒弃源代码tarball的概念,尤其当这些tarball并非直接来自上游时。例如:

      – Fedora 采用“旁路缓存”机制,打包者将 tarball 上传至该缓存。理论上这些文件应如源 RPM 所示来自 git,但我认为没有任何机制能验证这一点。

      – Python 包会构建源代码 tarball。理论上,新最佳实践是通过 GitHub Actions 构建包,并通过复杂机制证明确实来自 GitHub Actions。

      – 我虽未制作过Debian包,但据我所知维护者基本可自由操作。

      我认为这完全荒谬。若Fedora、Debian、PyPI或crates.io等平台托管的包宣称对应某个上游Git提交或发布版本,则托管系统应基于该提交/发布版本加上必要的包配置与补丁进行构建并发布。若存储源代码副本,该副本应能通过加密方式追溯至对应提交——实现很简单:提交哈希值本就是包含完整源代码在内的数据集哈希值!

      • 对多数软件项目而言,发布版tar包并非简单地将特定提交点的代码用gzip压缩。因此该方案仅适用于部分软件包。

        • 简化版本可能是:仓库仅存放需编译语言的单文件代码,而tar包则包含编译后的二进制文件。

          仅生成确定性二进制文件已非易事,更遑论在无需从头重编译的情况下验证“此输出源自该源代码”。

        • 对于设计良好的项目,源代码tar包可从源代码树干净生成。标准构建流程是(源代码tar包)→构建产物,但存在替代流程(源代码树)→构建产物,其中源代码tar包作为中间环节。

          在Python中,源代码压缩包的概念相对明确。uv build命令能从源代码树愉快地构建出源代码压缩包和wheel包,而uv build –from <适当参数>则能直接从压缩包构建wheel包。

          令人遗憾的是,当前PyPI上传机制要求提交源代码压缩包和wheel包,而非上传经过验证的源代码树并由PyPI完成构建——至少在简单场景下本应如此。

          传统C语言项目中,源代码树常包含将代码编译为源代码压缩包的脚本(autogen.sh最为常见)。像 Debian 或 Fedora 这样的软件包仓库,从源代码树构建甚至使用正确固定版本的 autotools 等工具,根本不存在技术障碍。真正令人失望的是,目前最接近完善 C/C++ 隔离构建系统的方案竟是 Dockerfile,而 Dockerfile 几乎完全未能处理好细节问题。或许 Nix 能做得更好?C 和 C++ 确实需要类似 Cargo 的工具。

          • 想到PyPI可能在构建全局轮子的系统中执行我包里的代码,我体内的黑客基因就兴奋不已。

            • 这似乎和GitHub Actions执行用户上传的任意代码没什么两样。

              要做得相当不错其实并不难,而且可以实现多层安全防护。首先使用一次性虚拟机,像AWS这样实力雄厚的供应商会以相对合理的价格提供这类服务。在容器内以受限的无特权用户身份运行,然后使用gVisor之类的工具。

              此外…理论上大多数纯Python包无需执行任何代码即可构建。最终产物仅需按pyproject.toml配置将文件打包即可。遗憾的是规范要求安装构建后端并运行,但可锁定几个可信版本的构建后端,并限制其配置为纯文件复制模式。我认为 uv-build 可能属于此类。至少目前尚未发现证据表明,除非启用 .pyc 文件生成功能,否则现行 uv-build 版本无法执行任何非基础操作。

        • 若无法至少对特定仓库特定提交的文件子集进行gzip压缩,那么某些人对“源代码”的定义显然需要重新审视。

          • 要获取仓库的特定提交通常需要克隆整个仓库,这比直接下载tar包会产生更大的下载量。

            • 浅克隆技术是可行的。创建包含完整哈希链验证数据的tar包相当简单(事实上我几年前曾临时拼凑过类似方案,或许该重新整理了)。这种tar包解压效果与常规tar包无异,但内部隐藏着tar命令会忽略的完整Git对象。

              • 指的是当前提交头,还是任意提交?

                • 我不确定这有何区别。提交头的特殊性仅在于存在一个小文件(该文件本身不受版本控制),标记特定提交为当前提交头。

      • > 若Fedora、Debian、PyPI或crates.io等平台声称其托管的软件包对应某个上游Git提交或发布版本,则托管系统应基于该提交/发布版本本身,结合必要的软件包专属配置与补丁进行构建后发布。

        Debian正是通过tag2upload实现此功能。

    • 若“任意工具”意指“补丁拼接”,请务必避免。请告别石器时代,迈入现代分布式版本控制系统时代。

      • Git本质上是补丁拼接之上的“瓷器”,其实现复杂度远超人们想象

        • 这是对Git机制的误解。Git本质是基于默克尔哈希树的不可变/仅追加文件系统,采用内容寻址机制,提交作为对象通过哈希值绑定文件系统根节点。构成提交的差异并非其实际内容——它们是按需计算生成的。虽然多数情况下将Git视为补丁拼接的瓷器模型最为简便,但其本质远不止于此。尽管这种模型能解决大部分问题,但终究需要理解其更深层的机制。

          • 不过打包过程中不会触及这个层面。

            比起折腾Debian打包规范(过去)采用的补丁拼接方式,我更倾向于重构Git历史。上次不得不使用Debian打包机制时,我将其转换为Git格式进行操作,导出过程中未丢失任何数据。

  3. 整个补丁拼接机制简直糟糕透顶。直接将补丁作为提交记录即可。这不会“欺骗”我或任何人——尤其当你将它们存放在标记为“debian”的分支时。

    拜托了,请停止这种补丁拼接的荒谬做法——它极其繁琐,增加不必要的认知负担,抬高贡献门槛,加重维护难度,且毫无价值。补丁拼接是双输的方案。

    • > 整个补丁拼接机制糟透了。直接将补丁作为提交保存即可。

      我认为quilt工具现已基本废弃。其名称仅保留在格式命名中,实际已无关紧要。

      如今维护补丁的人都通过gbp-pq操作(即命名不佳的git-buildpackage软件中的“补丁队列”子命令)。gbp-pq switch会读取存储在debian/patches/目录下的补丁,在HEAD基础上创建临时分支并在此重放补丁。该分支上的任何变更(新增提交、删除注释、修改提交)都会通过gbp-pq export转换为有效的补丁集,从而替换debian/patches/目录。

      该机制引入两个额外命令(分别用于“进入”和“退出”补丁应用视图),但使Debian能够轻松维护一个可合并的Git仓库——该仓库在上游源代码基础上浮动着补丁集。这在纯Git环境下无法实现,即使在Debian之外也需要额外工具或特殊工作流。

      • > 仅用普通Git无法实现,即使在Debian之外也需要额外工具或特殊工作流

        Rebase。

        • 此外,重新基准操作可用的信息较少,因此相较于合并操作,它更难实现干净的更新。千万别这么做!!只需将新分支头与上游之间的差异视为“差异本身”,并说明差异产生的原因。

      • 兄弟们都这么说。你需要的是git rebase,尤其要配合--onto--interactive选项。你可能还想用类似bisect-rebase.sh[0]的工具,不过现在还有其他类似方案。

        [0] https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee650

        • 重新基准化意味着无法对“顶层补丁”进行连续版本控制,这可能并不理想。此外,历史重写可能导致协作困难。

          合并操作虽能规避这些问题,但在存在大量冲突时操作难度较大,因为无法逐个补丁解决冲突。

          或许基于“合并后重新基准”或“重新基准后覆盖合并”的工作流可行,但简单说“直接重新基准”并不妥当。

          • Gerrit引入了提交ID概念:本质上是将UUID与首次将提案提交合并到主干的审核关联起来。

            手动挑选(cherry-pick)会保留该Commit-Id,rebase同样如此——因为它们本质上只是提交信息的文本内容。

            因此若需要,你可以通过这种方式追踪补丁历史。不过你其实不需要。

            (附注:谷歌某团队当时既不理解Git原理也不清楚真实需求,在rebase的无谓争论上浪费了软件工程师数十年的时间; 我至少帮他们稍作改进,并阻止其他团队效仿)

            • 但该提交ID尾注并无实际功能。若我克隆了仓库,而上游(此处指debian维护者)执行了rebase操作,我不明白这有何助益。

              > 你不会需要它。

              为什么不行?追踪Debian包应用过的补丁历史难道没有意义吗?

      • 这正是git-rebase的功能,它内置于标准git中。

    • 本文讨论的是从 quilt 维护的补丁堆栈迁移到 git 的过程。

    • 值得一提的是,quilt 方法出现的时间至少比 git 早十年。我认为它与 git 的兼容性已存在一段时间,但迁移基础补丁堆栈到 git 似乎始终不是最紧迫的事项。

      1. 没人应该被迫学习Debian源代码包——这种机制既古怪又已被现代版本控制系统淘汰。
    • 对于完全陌生的用户,什么是补丁拼接?

      • https://wiki.debian.org/UsingQuilt 简而言之:保留原始源代码不变,在构建包时应用debian/patches目录下的所有补丁,完成构建后再撤销这些补丁。这算是“明确标记变更”的极端版本——操作起来却相当繁琐,因为需要反复应用、修改、测试,最后再把变更打包成diff格式(quilt工具采用压栈/弹栈机制,所以这做法倒也不算太离谱)。

        • 哈,听起来确实疯狂。要是真有专门追踪代码变更的版本控制系统就好了…

          • Quilt早于Git诞生。当时源代码以tar包形式分发,Debian团队仅维护一个存放补丁的目录用于应用到tar包上。

          • 用纯Git实现类似Quilt的工作流相当困难

            我试过

            • Quilt本身难维护,但类Quilt工作流?很简单:只需创建一个包含所有补丁提交的分支。通过git rebase --onto $new_upstream_commit_tag_or_branch命令,就能将这些补丁重新应用到上游的新版本上。

  4. 确实如此。这对项目的长期生存力至关重要。衷心希望这项工作能成功,感谢所有推动者!

    • 你或许这么想,但2025年底的今天它仍处于开发中。

      我认为这并非坏事,但他们似乎一直靠补丁和tar包勉强维持着。

      • 我暂时找不到那张图表了,但最近看到一张显示新加入Debian开发者数量随时间变化的曲线图,近几年呈现断崖式下跌。我原本正朝着Debian开发者的方向前进(参加过几次Debian大会,有几个软件包进入存档库,还成为Debian维护者),但最终因精疲力竭而放弃——很大程度上是因为Debian的工具链让所有事情都变得异常痛苦。Michael Stapelberg关于离开Debian的帖子道出了真相:https://michael.stapelberg.ch/posts/2019-03-10-debian-windin

        Debian或许仍在“勉强维持”,但若不进行Git迁移这类变革,终将难以为继。

  5. Debian打包系统令我始终难以接受的是源代码与包文件共存的设计。我更倾向于Ports类系统——由打包文件指定源代码获取路径。当源代码与包捆绑时,操作体验明显笨拙。更新包也更麻烦,打包者必须替换嵌入的源代码,而非仅在构建配方中修改下载的源代码包。

    • Debian要求所有包必须能完全离线构建。

      > 基于许可和安全考量,Debian 保证所有二进制包均可从现有源代码包构建。例如,若构建系统从外部站点下载依赖项,该项目所有者可能发布采用不同许可的新版本依赖项。攻击者甚至可能在请求来自 Debian 构建服务器时提供恶意版本的依赖项。[1]

      [1] https://wiki.debian.org/UpstreamGuide#:~:text=make%20V=1-,Su

      • Gentoo和Nix同样如此,但它们的打包机制与源代码分离。源代码虽需获取,但在配置、编译和安装阶段会将构建过程隔离于网络之外。因此技术上完全可行。

        • Nix 绝对不允许大多数软件离线构建(至少不符合Debian定义的离线构建)。

          在Nix中,任何获取器都会下载源代码。其机制确保获取内容的sha值完全一致,若Nix存储库中已存在相同sha值的文件则无需重复下载。

          然而,仅凭Debian源代码树的镜像,你就能完全脱离互联网构建所有软件。但仅凭nixpkgs的镜像则绝对无法实现这一点。

          • > 使用Nix时,任何获取器都会下载源代码。

            明白了,我理解Debian理念与Portage/Nix等理念的差异。对于Portage和Nix而言,仅需构建过程离线即可,但源代码会在包构建初始阶段获取。我不仅认为这种方式足够,更倾向于它——因为在我看来这能简化包的操作(毕竟你只需处理打包代码,而非上游代码)。

          • 通过端口系统维护源代码库仍有可行方案。只需分析构建使用的源代码,创建镜像站点,并将下载请求重定向至该镜像。这并非异想天开。打包工作仍将独立进行。

            • 若我理解无误,这正是Nix的做法:正如XorNot在同一父帖回复中所述,“镜像”即cache.nixos.org。

        • 我认为Nix(尤其是nixpkgs)在这方面表现极差。它并非发行版:只是随机链接的集合,如今多数内容仅存在于cache.nixos.org。tarball服务器常缺失内容,某些内容根本无法呈现(递归哈希类型),链接已彻底失效(博通驱动压缩包指向的域名现已沦为在线赌博广告)。

          Nix并非真正函数式:它只是将命令式部分全部转移到更难解析的阶段,冠以“评估”之名,却完全忽视了函数式的卫生原则。

          不!你的打包依赖树绝不该包含缓存服务器上的不透明二进制文件,或指向他人Bugzilla实例上陈年补丁的链接(这类链接同样常失效)。

          从未有什么比处理这类替代方案更能让我领悟主流发行版的决策价值。

          • 这点对Nix的诟病相当致命,而众人却对其赞誉有加。是否有文章对此有更深入的阐述?

      • 这并非你所理解的含义。其规定是每个二进制包仅能依赖其声明的源代码包,并未要求源代码包必须在断开上游连接的情况下构建。

        原帖所指的是,Debian的工具链会将上游代码与Debian构建代码一同存储。为应对这种复杂性,存在辅助工具:用于下载新上游版本的uscan,以及将上游变更整合到Debian版本控制中的uupdate。但这意味着Debian实际上会镜像上游代码两次:一次在其源代码管理系统中(如今主要为salsa.debian.org),一次在其软件仓库中(以Debian源代码存档形式存在)。

      • 要实现离线构建并规避你提到的所有风险,只需确保包构建环节包含源代码存档的校验和,并同步该源代码即可。

      • 这为用户提供了多么美妙的保障。多数情况下,我更信任Debian维护者而非上游开发者(尤其考虑到供应链攻击风险)。

        令人遗憾的是,如今太多Linux项目正从apt转向直接分发上游代码的snap/flatpak等系统。

    • > Debian打包系统令我始终难以接受的是源代码与包文件混存的设计。

      许多软件包已停止分发完整源代码,仅在Git中保留debian目录。

      典型案例包括:

      – gcc-*
      – openjdk-*
      – llvm-toolchain-*
      以及更多。

    • 在集中化源代码存储出现前(Debian打包系统诞生于Sourceforge之前,更不用说GitHub了),这种做法很有道理。

      不过当上游源代码意外中断时(这种情况偶尔仍会发生),保留本地源代码依然很有价值。

    • > 我发现当源代码与包管理工具捆绑时,反而显得笨重。

      另一方面,当需要升级编译或运行时依赖版本时,这种模式能极大简化操作。应用程序与包管理工具共享单一权威源,

      Docker和Helm图表亦是如此。许多项目偏执地将它们分散在不同仓库,导致变更提案变得极其麻烦。

  6. “代码库≠仓库”是优秀的设计模式。若二者分离,甚至可为单个仓库配置多个代码库。

    或许您需要托管硬件设计或美术资源这类适合某类锻造平台的内容,同时托管需要另一类平台支持的代码?或者更简单地,用一个锻造平台进行持续集成,另一个用于代码审查。

  7. 若我理解有误请指正:据我所知,核心系统和库(或任何相关组件)迁移至新架构的进程已全面展开。但存在大量由其他方维护的扩展库,这个库生态系统采用了各种各样的方法,每种方法都有其缺点。当前的主要目标是让所有维护者加入进来,转向基于git的新工作流程——过渡团队(及其他团队)一直在努力使这个流程合理且易于实施。

    以上对现状的概括是否准确?(后续还有补充说明,但想先确认基本假设是否正确)。

  8. Ubuntu等衍生发行版与Debian相比,其软件包构建方式有何差异?

  9. 若由此能让尚未Debian化的软件作者,有机会从自身仓库构建出合格的Debian软件包,且一旦该包符合Debian收录标准,就能轻松启动发布流程——那简直是天赐良机。

    目前若未熟悉Debian包构建流程,连本地构建都堪称煎熬。

    • 问题在于“当软件包符合Debian收录标准时”,其核心要求_主要_在于“软件包元数据是否填写正确”,以及所有构建依赖项都必须已存在于Debian系统中。

      若你想要建立“简单自定义仓库”,可能需要另辟蹊径,明确执行官方Debian仓库不允许的操作。

      例如:当仅支持单一Debian版本时,动态链接很简单;或当Debian构建/打包基础设施自动处理时也很容易。但若运行自定义仓库,你必须为每个目标Debian版本准备独立包,并理解~deb13u1这类机制以确保升级路径正确,或者使用静态二进制文件(我自己的自定义仓库就是这么做的)。

    • 他们可以参考pkgsrc[1]的工作机制。

      [1] https://www.pkgsrc.org/

      • pkgsrc 非常出色,我在 smartos 上使用它(仅作为终端用户),操作极其直观

  10. Debian 在适应现代世界方面有些迟缓。

    我挺欣赏Debian很早就把开源软件(FOSS)奉为核心价值;事实上,这是我用过的第一个迫使我学习命令行的发行版。当时xorg-server——或者说X11服务器——无法正常工作,我只能依靠命令行和一本精简的Debian手册。我通过敲入命令行逐步掌握了操作技巧。此前使用的SUSE发行版虽配有厚重的手册和花哨的图形界面,却完全派不上用场——那已是2005年前后的事了。

    如今2025年,我已很久没用Debian或其衍生发行版。要么参考LFS/BLFS从源代码松散地编译系统;要么最近常用的Manjaro——它堪称现代Slackware变种中最接近的版本 (尽管它用了systemd;Slackware曾是我长期使用的系统,但遗憾的是过去十年间它变得越来越慢,即使是alienbob这类现代变体也未能例外——Manjaro的进步速度快上百倍,同时还能保持稳定运行,包括我需要从源代码编译时;不知为何,许多老派发行版都未能适应现代需求。systemd或许是障碍之一,但问题远比这更根本。例如如今软件包数量激增,编译耗时大幅延长——LLVM等组件需耗费更多时间,而这些又是mesa等项目的基础;此外还有cmake、meson/ninja等工具链。现代系统需要处理的软件生态已膨胀至此)。

    • > Debian适应现代化的步伐确实迟缓。

      确实如此。我猜这源于他们那种“必须掌控全世界”的怪异理念——所有开源Linux软件都必须收录进Debian。

      若真要升级整个世界,那可得花上不少时间…

  11. > 标准的Git格式是“patches applied”。

    有多少Debian软件包对上游进行了补丁应用?

    • 绝大多数,因为Debian是唯一严格执行手册页和文件系统标准的发行版。而多数源代码包对此并不在意,或者说有其他想法

    • 很多。因为许多上游项目未配置适配发行版的构建系统(无法从系统获取依赖项并安装到标准位置)。所有发行版都必须打补丁才能让它们正常工作。

      • 打补丁的积极程度存在显著差异。Arch Linux 坚持严格最小化补丁,并尽可能完全避免使用补丁。这是好事,否则就会出现像Xscreensaver那样的荒唐局面——原始开发者会激烈抵制发行版软件包,因为这些软件包篡改了他们的作品,并/或强迫毫无防备的用户使用陈旧且存在漏洞的版本。

        • > 出现像Xscreensaver那样的荒唐局面,原始开发者激烈抵制发行版软件包

          我此前不知此事。能否提供相关链接?

        • 咦?我参与Debian开发,从不强行打补丁。你也完全可以参与。

          • 那恭喜你。看来你不能代表那些制造灾难的Debian维护者发言:

            https://research.swtch.com/openssl

            Debian(以及基于它的数十个发行版)似乎存在严重问题——他们完全不尊重操作系统所基于的软件开发者,最终伤害最大的是用户。我不明白他们为何不能保持尊重,但恐怕他们正在为Debian掘墓,因为人们正大批放弃陈旧且故障频出的Debian衍生发行版。

          • 本质是“尽量少打补丁”与“用最小补丁强制执行规则”的对立

    • 我猜在积极开发的应用/工具/库中应该不少。脱离sid(不稳定分支)的Debian软件包通常会落后于上游版本,但仍受支持。因此若上游项目未维护与测试/稳定/旧稳定分支版本匹配的旧版,安全修复通常会被回溯移植。

  12. >修改只需使用常规git命令即可完成,例如git commit。许多处理未应用补丁的Debian内部人员仍在使用quilt(1)——这可是个操作补丁文件时陷阱遍布的工具!

    咦。我今年才在学习Debian打包时接触quilt。现在已开始在自己的分支项目中使用它,或许将来能回馈社区。

    我猜Debian构建文档里推荐quilt等工具的旧内容,正是链接页面所提文档更新项目需要处理的部分。

  13. 我一直以为Debian早已采用Git,所以有点困惑。Debian项目当前(或过去)是如何进行源代码管理的?

    • 简短回答:并非如此。

      详细解释:许多人已使用Git进行Debian版本控制,文章阐述了未来将如何实现更深度的集成。但进入存档(用于构建)的核心本质上仍是带版本号的源代码包。虽有变更日志,但你大可随意在其中造假。

  14. 记得我之前任职的初创公司从svn迁移到git时的情景。他们完成迁移后,竟把提议迁移的人当替罪羊甩掉;那人辞职后,公司也随之垮了。笑死!

    • 我曾加入一家小型初创公司(约15名员工),入职后首要任务就是将SVN仓库迁移至Git。过程不算太复杂,导入历史数据后,我不得不编写大量工具来处理源代码不再集中于单一巨型层级的问题(由于采用微服务架构和自包含库,拆分是合理的)。

      离开那家公司后,我加入了一家规模更大的企业(约14000名员工),部分原因正是我曾有过SVN转Git的迁移经验。这次迁移难度截然不同:需要修改海量工作流,导入十年SVN历史(部分历史源自CVS),清理误添加的虚拟机镜像和ISO文件,重写Jenkins实例中的大量代码等等。

      更棘手的是还要部署、配置并管理一个地理分布式的内部Gitlab实例,其中包含数十至数百GB级别的多仓库系统。

      这段历程充满挑战且耗时数年,但同时充满乐趣。值得庆幸的是,提出迁移建议的分别是首家公司的CEO和第二家公司的CTO,整个过程未出差错,无人因此受责,两家公司至今在源代码管理方面都运转良好。

    • 掌握Git本质上是检验学习工具能力的职场技能

      • Git实则是“更差即更好”的经典案例。除纯粹速度外,Hg在各方面都优于它。当然,Git仍远胜于SVN。

        • Git的崛起并非源于与Mercurial的竞争(尽管这占了小部分),而是更多地来自对SVN、CVS以及从未接触过版本控制用户的替代。这类似于Chrome取代Firefox成为主流浏览器的过程——其用户转化主要来自IE和Safari,而非原本使用Firefox的高级用户群体。

          • 这点至关重要:2005年“所有代码必须纳入版本控制”仍是争议性理念,尤其对那些生产软件却非“科技公司”的企业而言。Git的扩张很大程度上源于团队首次将软件投入版本控制系统。

  15. 太棒了!调试时再也不用和发行版源代码工具较劲了。

  16. 希望Debian也能升级到现代化的缺陷跟踪系统,现在的系统实在太陈旧了。

    • 它确实不够美观,但你认为它缺少必要功能吗?

      真心提问。我已很久没接触过它了。

      • 跟踪一个错误的简单任务需要你:

        1. 向该错误的专用邮箱发送空邮件。

        2. 等待15-30分钟,让Debian的灰名单邮件服务器接收邮件并发送确认函。

        3. 回复确认函。

        上次我尝试跟踪问题时,始终没收到确认函。

        其他几乎所有问题跟踪系统里,关注问题只需点击按钮即可。

        与大多数Debian开发工具类似,这个漏洞追踪器虽然能完成任务(大多数时候),但其操作复杂度远超必要水平。

        • 说得有道理。不过我没亲自查看过,为了方便读者理解——如果用户已有追踪器账号,是否必须执行该操作?比如在 GitHub 上追踪问题很简单,但创建账户时也得经历类似的繁琐流程。

          • Debian 错误追踪器根本不支持创建账户。每次追踪错误都得重复这些繁琐步骤。

          • 我真心希望两者兼得。既要有交互式网页前端,也要保留经典的邮件驱动式漏洞追踪器,两者共享同一数据源。我认为两者各有优势。不过考虑到网页端已发展得如此庞大且快速迭代,这项工作恐怕相当艰巨。

          • 没错,但全球几乎所有开发者都已跨越过这个门槛。他们无需为每个项目重复操作。

            况且这个门槛可以简单到“点击此处用<你已有的其他账户>登录”。

        • 我用reportbug简化了初始报告流程,但整体交互体验仍远不够便捷。

          https://tracker.debian.org/pkg/reportbug

      • 作为Debian用户且偶尔与BTS交互的人,我的看法是:

        据我所知,使用BTS必然会遭遇垃圾邮件轰炸,因为唯一交互方式是邮件,且每次交互都会未经编辑直接发布到网页。因此若想接收更新或监控问题,就必然会收到垃圾邮件。

        再次强调,由于仅支持邮件的设计,用户必须记忆命令或参考文本文件才能对错误采取行动。这对资深用户尚可接受,但对多数人而言是糟糕的用户体验。我只能推测维护者可能拥有类似bugreport命令的工具,能提供某种程度的界面辅助——只是我尚未知晓。作为用户,我完全不知道如何关闭自己提交的错误报告,甚至无法确认哪些错误是我创建的。因此维护包的开发者不得不承担全部工作,负责整理错误追踪系统(众所周知开发者最爱做这种事……)。

        根据我的使用体验,搜索/错误查看功能也相当糟糕。错误报告的组织方式极其反直觉,除非你事先了解其运作机制。部分问题源于所有发行版共有的“究竟哪个包负责这个错误?”的根本困境,但Debian BTS的体验尤为糟糕。它混杂显示状态和优先级,还使用令人费解的符号如“(不被HN允许的皱眉表情)”、“=”和“i”,必须查看工具提示才能搞清楚这些鬼东西的含义。

        • > 据我所知,使用BTS系统必然会遭遇垃圾邮件轰炸,因为唯一的交互方式是邮件,而每次与BTS的互动都会未经编辑直接发布到网络上。因此,若想接收更新或监控漏洞,就必然会收到垃圾邮件。

          Bugs Tracker System的邮件是否来自固定来源?若是如此,虽非理想方案,但可注册专用别名邮箱,将非系统邮件全部拦截。

        • 该命令在devscripts中为bts。我于2001年编写此功能。

        • 垃圾邮件问题可能是反对采用邮件中心化设计的有力论据之一,这种设计常见于缺陷追踪系统、代码托管平台等场景。现代软件开发中,专业参与者不得不默许所有兜售桥梁的垃圾邮件发送者向其发送未经请求的垃圾邮件,这种现状实在荒谬。

          如今多数代码托管平台提供虚拟邮箱作为用户身份认证,正是出于这个原因。

      • 每次需要操作时都令人恼火地笨拙,相比GitLab等现代缺陷追踪器更是如此。

        另外,本地修改reportbug以支持XDG基础目录规范简直是苦差事(维护者多年来拒绝采纳相关修复)。

    • 公平地说,它完全契合我的需求,且没有常见的JavaScript臃肿问题。

      因此要向其作者致敬

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号