如果您发现某个 port 相对原作者所发布的版本已经过时, 则首先需要确认的是您的 port 是最新的。 您可以在 FreeBSD FTP 镜像的 ports/ports-current 目录中找到它们。 但是, 如果您正在使用较多的 port, 则可能使用 CVSup 来保持 Ports Collection 最新更为简单, 这在 使用手册 中进行了介绍。 此外, 这样做也有助于保持 port 依赖关系的正确性。
下一步是检查是否已经有在等待的更新。 要完成这项工作, 可以采用下列两种方法之一。 有一个用于搜索 FreeBSD 问题报告 (PR) 数据库 (也被称作 GNATS)。 在下拉框中选择 ports, 然后输入 port 的名字。
但是, 有些时候人们会忘记将避免混淆的 port 的名字放到 Synopsis 字段中。 这种时候, 您可以试试看 FreeBSD Ports 监视系统 (也被叫做 portsmon)。 这个系统会尝试按照 port 的名字来进行分类。 要搜索和某个特定 port 有关的 PR, 可以使用 port概览。
如果没有候审的 PR, 下一步是给 port 的维护者写信, 这可以通过执行 make maintainer 看到。 这个人可能正在进行升级工作, 或者由于某种理由暂时没有升级 (例如, 新版本有稳定性问题); 一般您不希望重复他们的工作。 注意没有维护者的 port 的维护者会显示为 ports@FreeBSD.org, 这是一般性 port 问题的邮件列表, 因此发邮件给它一般没什么意义。
如果维护者要求您去完成升级, 或者没有维护者, 您就有机会通过自行完成升级来帮助 FreeBSD 了! 请使用基本系统提供的 diff(1) 命令来完成相关的工作。
如果只修改一个文件, 可以直接使用 diff 来生成补丁, 将需要修改的文件复制成 something.orig, 并将改动放进 something, 接着生成补丁:
如果不是这样的话, 则您应使用 cvs diff 的方法 (第 10.1 节), 或将目录整个复制到另一个目录, 并使用 diff(1) 比较两个目录时在目录中递归产生的输出结果 (例如, 如果您修改后的 port 目录的名字是 superedit 而原始文件的目录是 superedit.bak, 则应保存 diff -ruN superedit.bak superedit 的结果)。 一致式 (unified) 或 上下文式 (context) diff 都是可以的, 但一般来说 port committer 会更喜欢一致式 diff。 请注意这里使用的选项 -N, 它的目的是强制 diff 正确地处理出现新文件, 或老文件被删除的情形。 在把 diff 发给我们之前, 请再次检查输出, 以便确认每一个修改都是有意义的。 (特别注意, 在对比目录之前要用 make clean 清理一下)。
为了简化常用的补丁文件操作, 您可以使用 /usr/ports/Tools/scripts/patchtool.py。 使用之前, 请首先阅读 /usr/ports/Tools/scripts/README.patchtool。
如果 port 目前还无人维护, 而且您自己经常使用它, 请考虑自荐为它的维护者。 FreeBSD 有超过 4000 个没有维护者的 port, 而这正是最需要志愿人员的领域。 (要了解关于维护者的任务描述, 请参见 开发手册中的相关部分。)
将 diff 发送给我们的最佳方式是通过 send-pr(1) (category 一栏写 ports)。 如果您正维护那个 port, 请务必在 synopsis 的开头写上 [maintainer update], 并将您的 PR 的 “Class” 设置为 maintainer-update。 反之, 您的 PR 的 “Class” 就应该是 change-request。 请在信中逐个提及每一个删除或增加的文件, 因为这些都必须明确地在使用 cvs(1) 进行 commit 时明确地指定。 如果 diff 超过了 20K, 请考虑压缩并对其进行 uuencode; 否则, 简单地将其原样加入 PR 即可。
在您 send-pr(1) 之前, 请再次阅读 Problem Reports 一文中的 如何撰写问题报告 小节; 它给出了丰富的关于如何撰写更好的问题报告的介绍。
重要: 如果您的更新是由于安全考虑, 或修复已经 commit 的 port 中的严重问题, 请通知 Ports 管理团队
<portmgr@FreeBSD.org>
来申请立即重建和分发您的 port 的 package。 否则, 不愿怀疑的使用 pkg_add(1) 的用户, 可能会在未来数周之内继续通过使用 pkg_add -r 安装旧版本。
现在您已经了解了所需的所有操作, 您可能会像要阅读在 第 14 章 中关于如何保持最新的描述。
如果可能的话, 请提交cvs(1) diff; 这种情形要比直接比较 “新、旧” 目录要容易处理。 此外, 这种方法也让您更容易看出到底改了什么, 并在其他人更新了 Ports Collection 时容易合并这些改动, 在提交之前, 这可以减少维护补丁所需的工作。
% cd ~/my_wrkdir % cvs -d R_CVSROOT co pdnsd % cd ~/my_wrkdir/pdnsd
在工作目录中, 您可以像往常一样进行任何更改。 如果您添加或删除了文件, 则需要告诉 cvs 来追踪这些改动:
% cvs add new_file % cvs remove deleted_file
请反复检查 第 3.4 节 列出的事项并使用 第 3.5 节 进行检查。
% cvs status % cvs update
表 10-1. cvs update 文件名前字母前缀的含义
U | 文件更新无误。 |
P | 文件更新无误 (通常只有在使用远程代码库时才会看到)。 |
M | 文件有本地修改, 并合并成功而未产生任何冲突。 |
C | 文件有本地修改, 进行了合并并产生了冲突。 |
如果您在执行 cvs update 时某些文件出现了 C, 则说明有其他人在 CVS 中做了修改, 而 cvs(1) 无法将这些改动与您本地的改动进行合并。 不过, 无论如何, 最好都检查一下合并的结果, 因为 cvs 并不知道 port 应该是什么样子, 因此它所做的合并无论是否产生了冲突, 都有可能 (并且并不罕见) 产生没有意义的结果。
最后一步是以 CVS 中的文件为基础生成 unified diff(1):
% cvs diff -uN > ../`basename ${PWD}`.diff
注意: 指定
-N
十分重要, 因为它确保了添加或删除的文件也出现在补丁中。 补丁将包含删除的文件, 在打上补丁时, 这些文件会被清空, 所以最好在 PR 中提醒 committer 删除它们。
根据 第 10 章 的指导提交您的补丁。