4 向组件贡献修改
Yocto 项目和 OpenEmbedded 非常欢迎贡献。 系统具有很高的可配置性和灵活性,我们理解开发者会希望根据具体用途扩展、配置或优化它。
4 通过邮件列表贡献:为什么不使用网页工作流?
Yocto 项目和 OpenEmbedded 的许多关键组件都通过邮件列表提交补丁来维护。 相比 GitHub、GitLab 等基于网页的工作流,这种方式看起来有些传统。 由于经常被问到这个问题,我们在此说明使用邮件列表的原因。
一个重要原因是我们重视同行审阅。针对项目核心部分提出修改时, 让更多人审阅会很有帮助。虽然最终由一位维护者决定是否接受补丁, 但实际审阅来自许多人,维护者事先未必知道谁会参与。 那些意料之外的审阅者,往往能发现最值得关注的问题。
相比之下,“GitHub”式工作流通常由维护者独自审阅,或明确邀请指定人员审阅。 我们认为,开放的同行审阅为代码带来了显著价值,离开邮件列表会损害代码质量。
还应看到,许多开发者已经使用这一工作流多年,并围绕它建立了工具和流程。 改变这种方式可能使项目失去关键参与者,同样不利于项目。
项目也很清楚,潜在的新贡献者可能不喜欢邮件列表,更倾向于网页图形界面。
由于我们认为那种方式不适合本项目,正在确保
patchwork 可用于跟踪补丁状态,
并研究如何通过工具向用户提供更多状态反馈。
我们也在改进 patchtest 等工具,使贡献在进入邮件列表前得到测试,
并完善工作流文档:十年前的常识,对今天的开发者可能已经不那么熟悉。
4 准备提交修改
4 配置 Git
首先安装 Git 软件包。Debian 和 Ubuntu 的示例如下::
sudo apt install git-core git-email
然后设置 Git 用于标识提交的姓名和电子邮件地址::
git config --global user.name "Ada Lovelace"
git config --global user.email "ada.lovelace@gmail.com"
Git 默认在补丁末尾添加包含 Git 版本的签名行。 这并不提供有用信息,建议用以下命令去掉::
git config --global format.signature ""
4 克隆待修改组件的 Git 仓库
按照 确定所属组件 确定待修改组件后, 克隆其 Git 仓库。以下以 OpenEmbedded-Core 为例::
git clone https://git.openembedded.org/openembedded-core
cd openembedded-core
4 创建新分支
从上游仓库的参考分支(通常名为 master)出发,
在本地 Git 仓库创建用于修改的新分支::
$ git checkout <ref-branch>
$ git checkout -b my-changes
如果要提交几组完全无关的修改,应为每一组分别创建分支。
4 实现并提交修改
在每个分支中,应将修改拆分成小而独立、范围可控的单元。 这样便于审阅和合并、变基,也能保持清晰的历史,方便将来查阅。
为此,应当 每项修改对应一个 Git 提交,最终对应一个待提交的补丁。 需要时可参考 Linux 内核文档的 进一步建议。
例如,添加多个新配方时,每个配方应单独提交。 升级已有配方时,通常应在添加新版本的同一提交中删除旧版本。
暂存修改: 对每个修改过的文件运行
git add。 如果要暂存全部修改,也可以使用git add -A。提交修改: 此时可以创建独立提交。 对每个提交,使用
git commit -s,指定要包含的文件或目录::$ git commit -s file1 file2 dir1 dir2 ...
要包含所有已暂存文件::
$ git commit -sa
git commit的-s选项会在提交说明中添加 "Signed-off-by:" 行。 Linux 内核贡献也有相同要求。添加此行表示提交者同意以下 开发者来源证明 1.1:Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.用一行概括修改;如需更多解释,再在提交正文中详细说明。 摘要通常显示在简短提交列表中,因此应简洁、明确,让读者快速理解修改内容。 修改配方时,以配方名称为前缀;否则使用被修改文件路径的简短形式。
备注
要寻找合适的摘要前缀,可以查看之前修改相同文件或目录的提交::
git log --oneline <paths>
提交正文应详细说明改了什么、为什么改,以及采用的方法。 说明如何测试修改也很有帮助。应尽可能提供充分细节。
备注
对于简单修改,如果一行摘要已足够说明,提交正文可以为空。
如果修改解决了具有缺陷跟踪 ID 的特定问题,在提交正文中引用该 ID。 Yocto 项目使用以下约定,必须用实际 Bugzilla ID 替换 bug-id::
single-line summary of change Fixes [YOCTO #bug-id] detailed description of change
如果其他人参与了补丁,可以在正文中加入标签,认可他们的贡献:
Reported-by:报告该缺陷的人的姓名和邮箱。 这样可以鼓励继续报告问题,并让报告者知道反馈得到了处理。Suggested-by:提出修改思路的人的姓名和邮箱。Tested-by、Reviewed-by:测试修改或审阅代码的人的姓名和邮箱。 通常由接受补丁的维护者添加;如果你先向他人征求过审阅, 或在新一轮补丁系列中重新提交未修改的补丁,也可自行加入已有标签。Cc:希望收到修改副本的人的姓名和邮箱,供git send-email使用。
更多建议见 Linux 内核文档的 标签使用说明。
备注
可以使用
git commit --amend修改已有提交说明,补充遗漏的贡献者标签。
4 测试修改
每次贡献都应测试相应修改。Yocto 项目提供多种测试,覆盖不同领域; 应根据修改选择适用的测试。例如:
对影响构建环境的修改:
bitbake-selftest:测试 BitBake 内部修改。
oe-selftest:测试 BitBake 运行的不同组合。
oe-build-perf-test:测试常见构建场景的性能。对配方修改:
ptest:运行软件包自身的测试(如果有)。
testimage:构建并启动镜像,在其中运行测试用例。如果适用,还应确保
native和nativesdk变体能够构建。对 SDK 相关修改:
testsdk:构建、安装 SDK,并对其运行测试。
testsdk_ext:构建、安装可扩展 SDK,并对其运行测试。
此列表仅供参考,并不完整。详见 Yocto 项目测试类型概览。
4 生成补丁
通过电子邮件提交补丁的一般准备步骤如下:
描述分支中的修改: 如果分支中有多个提交,建议提供封面信, 介绍即将发送的补丁系列。
一种合适的做法是将封面信内容保存在分支描述中::
git branch --edit-description
命令会打开文本编辑器,填写修改说明。可以随时更新描述, Git 会将其与补丁一起用于生成封面信。
建议第一行写标题,作为封面信的邮件主题。
为分支生成补丁:
git format-patch为分支中的每个提交生成补丁文件。 需要传入该分支起始的参考分支。如果上一步无需分支描述::
$ git format-patch <ref-branch>
如果填写了分支描述,还应生成封面信::
$ git format-patch --cover-letter --cover-from-description=auto <ref-branch>
命令执行后,当前目录中会出现带编号的
.patch文件。 封面信位于0000-cover-letter.patch。备注
--cover-from-description=auto让git format-patch使用分支描述的第一段作为封面信标题。 也可以只传入更容易记住的--cover-letter, 但每次生成补丁后都要手动编辑主题。审阅每个补丁文件: 发送前的最后检查常常能帮助你从不同角度审视修改, 发现拼写、空格等问题,以及本不打算修改的行甚至文件。 封面信也应包含在检查范围内。
必要时,按照 根据补丁审阅意见修改 修改提交。
4 使用 Patchtest 验证补丁
openembedded-core 提供 patchtest,
检查补丁格式是否正确,以及是否包含维护所需的重要信息,例如 Signed-off-by。
它不执行功能测试,目前仅支持 openembedded-core 分支的补丁。
配置步骤如下::
pip install -r meta/lib/patchtest/requirements.txt
source oe-init-build-env
bitbake-layers add-layer ../meta-selftest
完成配置并生成补丁文件后,可运行::
patchtest --patch <patch_name>
若要遍历并测试某个目录中的多个补丁,使用::
patchtest --directory <directory_name>
默认情况下,patchtest 根据自身模块的文件路径,
确定检查补丁所用的仓库和测试套件。
要针对其他仓库或使用另一组测试,可使用 --repodir 和 --testdir::
patchtest --patch <patch_name> --repodir <path/to/repo> --testdir <path/to/testdir>
注意,patchtest 设计为独立测试每个补丁。
如果补丁依赖同一系列中先前的修改,"merge on head" 测试可能产生误报。
这样使用 patchtest,可以在提交维护者审阅前,对修改的整体质量作最后检查。
4 通过电子邮件发送补丁
4 使用 Git 发送补丁
通过邮件提交补丁时,必须避免自己或邮件客户端引入空白或 HTML 格式变化。
接收补丁的维护者需要能够直接保存邮件,并使用 git am 应用它。
git send-email 是通过邮件发送补丁最可靠的方式,
可以避免普通邮件客户端破坏正文空白。
它还会正确地将补丁作为 内联附件,
普通客户端很难在不破坏换行的情况下做到这一点。
如果使用普通附件,审阅者便无法引用具体修改并发表评论。
4 配置 Git 发送邮件
git send-email 可以使用本地或远程邮件传输代理(MTA),
例如 msmtp、sendmail,也可以通过 ~/.gitconfig 直接配置 SMTP。
以下以 Google Mail 账户为例,设置通过常用 SMTP 服务器发送邮件::
git config --global sendemail.smtpserver smtp.gmail.com
git config --global sendemail.smtpserverport 587
git config --global sendemail.smtpencryption tls
git config --global sendemail.smtpuser ada.lovelace@gmail.com
git config --global sendemail.smtppass = XXXXXXXX
这些设置会写入主目录中的 .gitconfig。
如果既不能使用本地 MTA,也不能使用 SMTP, 请确保邮件客户端不会改动正文,例如把空格变成制表符或自动折行。 Pine(或 Alpine)和 Mutt 是适合的客户端。 更多信息见 Linux 内核文档中的 Linux 邮件客户端说明。
使用这些客户端时,直接将补丁放入邮件正文。
4 查找合适的邮件列表
应将补丁发送到适当的邮件列表,让相关贡献者审阅,并由相应维护者合入。 具体列表取决于修改的代码位置。
如果有人对补丁有疑问,通常会在列表中提出。 如果没有负面审阅意见,受影响层的维护者通常会接收并测试补丁,测试成功后合入。
一般而言,每个组件(例如层)都应有 README,说明修改发往何处及应遵循的流程。
如果新配方既不适合 OpenEmbedded-Core (OE-Core), 也不适合 meta-openembedded, 应在 https://layers.openembedded.org 寻找合适的层。 如果未来还会有类似配方,可以考虑 创建自己的层。
如有疑问,请在 yocto 通用邮件列表, 或 openembedded-devel 列表询问。
4 订阅邮件列表
确定合适的邮件列表后,如果尚未订阅,需要先订阅。
向未订阅的列表发送补丁时,邮件会以无法投递退回。
如果不希望接收列表中的所有消息,可以将订阅方式设为 "no email"。 你仍然是订阅者,可以发信,但不会收到列表邮件。 有人回复你的消息时,其客户端通常仍会默认把你的地址加入对话收件人。
也可以通过浏览器查看列表归档中的新消息; 对于归档在 https://lore.kernel.org 的列表,还可以通过独立新闻组源或 Git 仓库访问。
4 发送补丁邮件
现在可以发送补丁。git send-email 的典型用法如下::
git send-email --to <mailing-list-address> *.patch
仔细检查每封邮件的主题和收件人列表,然后允许命令发送。
git send-email 会自动抄送提交中 Signed-off-by、Reported-by
等标签列出的人。
为 meta-openembedded 或 openembedded-core 之外的其他层发送补丁时, 请添加相应前缀,明确补丁适用的层::
git format-patch --subject-prefix="meta-oe][PATCH" ...
备注
也可以不预先生成补丁文件,直接发送。但必须先仔细检查修改,
因为 git send-email 只会展示各补丁的标题。
分支中只有一个补丁时,可以使用::
git send-email --to <mailing-list-address> -1
如果有多个补丁及封面信,可以发送参考分支到当前分支顶端之间的全部提交::
git send-email --cover-letter --cover-from-description=auto --to <mailing-list-address> -M <ref-branch>
4 排查邮件问题
4 修正 From 身份
一个常见问题是,收到的补丁中 From 字段与 Signed-off-by 不一致。
使用启用了 https://en.wikipedia.org/wiki/DMARC 的域发送邮件时,典型示例如下::
From: "Linus Torvalds via lists.openembedded.org <linus.torvalds=kernel.org@lists.openembedded.org>"
git am 使用 From 字段恢复正确的提交作者姓名。
以下配置会在邮件正文开头增加 From 字段,
使维护者不必手动修正作者信息::
git config --global sendemail.from "linus.torvalds@kernel.org"
sendemail.from 应与 user.email 一致,后者出现在提交的 Signed-off-by 中。
4 简化 git send-email 的使用
可以通过 Git 配置节省时间,避免每次记住全部选项。
为某个仓库设置正确的邮件列表地址::
git config --local sendemail.to openembedded-devel@lists.openembedded.org
如果列表要求主题包含层前缀(仅适用于仓库只有一个层的情况)::
git config --local format.subjectprefix "meta-something][PATCH"
4 使用脚本向上游推送修改并请求拉取
较大的补丁系列更适合发送拉取请求,其中除了补丁,还包含可供拉取的分支地址。
先为修改创建本地分支,推送到可访问的仓库,再使用 openembedded-core 的
create-pull-request 和 send-pull-request 脚本,
生成并发送附带分支链接的补丁系列供审阅。
完成 准备提交修改 中的步骤后,按以下流程向上游 "contrib" Git 仓库推送:
备注
关于向上游推送修改的一般 Git 知识,参见 Git 社区书籍。
申请上游 contrib 仓库的推送权限: 向
helpdesk@yoctoproject.org发送邮件:附上 SSH 公钥,通常名为
id_rsa.pub.。 如果没有,可运行ssh-keygen -t rsa -b 4096 -C "your_email@example.com"生成。列出计划贡献的仓库。
提供希望在
-contrib仓库中使用的分支前缀。
向 contrib 上游推送提交: 将修改推送到该仓库::
$ git push upstream_remote_repo local_branch_name
例如,你有向
meta-intel-contrib推送的权限, 正在本地 your_name/README分支工作。 以下命令将本地提交推送到该上游仓库中同名的分支::$ git push meta-intel-contrib your_name/README
确定通知对象: 确定需要通知的维护者或邮件列表。
提交修改前必须明确这一点,可以使用以下方法:
维护信息文件: 查看 OpenEmbedded-Core (OE-Core) 中
meta/conf/distro/include下的maintainers.inc,确定代码负责人。按文件查找: 使用 Git, 运行以下命令,查看某个文件的提交者简表::
git shortlog -- filename
传入感兴趣的文件名即可。返回结果不按历史顺序排列, 而是按姓名分组列出提交者,由此可以看到谁完成了该文件的大部分修改。
查找邮件列表: 参见前面的 查找合适的邮件列表。
发起拉取请求: 通过拉取请求通知维护者或邮件列表,修改已推送。
Yocto 项目提供
create-pull-request和send-pull-request两个脚本, 方便生成并发送拉取请求,位于 OpenEmbedded-Core (OE-Core) 的scripts。这些脚本可以正确格式化请求,不会引入空白或 HTML 格式变化。 维护者无论直接还是通过列表收到补丁,都应能够直接从邮件保存并应用。 因此推荐使用这些脚本发送补丁。
首先创建拉取请求。以下命令指定已推送修改的 contrib 上游仓库, 并为生成的补丁文件提供主题::
$ ./scripts/create-pull-request -u meta-intel-contrib -s "Updated Manual Section Reference in README"
脚本会在当前目录的
pull-PID 文件夹中生成*.patch,其中一个是封面信。运行
send-pull-request前,必须编辑封面信,加入修改信息。 编辑完成后发送请求。以下命令指定补丁目录和邮件地址,此处地址是邮件列表::$ ./scripts/send-pull-request -p ~/meta-intel/pull-10565 -t meta-intel@lists.yoctoproject.org
脚本为交互式,需要按提示操作。
备注
要查看帮助,传入
-h::$ ./scripts/create-pull-request -h $ ./scripts/send-pull-request -h
4 向稳定发布分支提交修改
向 Yocto 项目稳定分支提议修改,与上述流程有所不同。 稳定分支修改必须解决明确的缺陷或 CVE,并谨慎避免引入新问题或破坏向后兼容性。 通常,修复必须先被 master 接受,才能回移到稳定分支; 除非问题不影响 master,或 master 的修复方式不适合回移。
稳定分支列表、各分支状态和维护者信息见 版本页面。
备注
稳定分支补丁应为独立、便于人工阅读和理解的修改。 复杂度高、提交数量多或修改行数很多的 CVE 及其他修复, 会增加维护和规模化处理的难度,因此不太可能被接受。
通常不接受面向已终止支持(EOL)分支的修改。
具体提交步骤如下:
明确待修复的缺陷或 CVE: 收集相关信息,以便随提交一起提供。
CVE 跟踪详见 检查漏洞。
检查 master 是否已有修复: 已有修复时,进入稳定分支的路径最直接。
master 已有修复:通过邮件申请回移。 向相关稳定分支维护者和邮件列表发送邮件,说明缺陷或 CVE、 master 上的修复提交哈希,以及希望回移到哪些稳定分支。
master 尚无修复:先向 master 提交。 这样可确保修复经过项目正常的补丁审阅与测试流程, 也避免 master 本身仍留有未解决的问题。 master 接受后,再按上述方式申请回移。
修复不适用于 master:直接提交稳定分支补丁。 这应是最后的选择。通常出现在 master 使用了已包含上游修复的新软件版本, 或 master 的修复引入了不向后兼容的变化时。 此时遵循 准备提交修改 及后续章节的步骤,但在补丁邮件主题中加入目标稳定分支名。 可以通过
git format-patch的--subject-prefix指定。 例如,向 "wrynose" 分支提交::git format-patch --subject-prefix='wrynose][PATCH' ...
4 根据补丁审阅意见修改
提交后,可能收到社区成员或自动 patchtest 服务的反馈。 发现的问题通常必须解决,补丁才能被项目接受。 应根据反馈修订提交,并向相关列表发送更新版本。
不要通过在分支顶端追加新提交来修复审阅指出的问题。 应始终提供已经解决这些问题的一组新提交。
备注
建议抄送曾为上一版提供反馈的审阅者。
可以在提交正文中添加 CC 标签::
CC: William Shakespeare <bill@yoctoproject.org>
单个补丁可用 git commit --amend 修改;
多个补丁可通过交互式变基重新修改和排序::
git rebase -i <ref-branch>
实际操作可参考 交互式变基教程。
发送修订版本时,还应将邮件主题中的 [PATCH] 改成
[PATCH v2]、[PATCH v3] 等,标明迭代次数。
可以向 git format-patch 传入 -v 和版本号::
git format-patch -v2 <ref-branch>
通过 git format-patch 生成更新补丁后,最好为每个补丁添加版本变更记录,
说明各轮之间的变化。记录放在补丁的 --- 标记之后,
表示它属于本次补丁邮件,但不应进入提交说明及 Git 历史。
这能帮助维护者和审阅者快速理解各版本变化,不必再搜索邮件列表等其他来源。
例如::
<patch title>
<commit message>
<Signed-off-by/other trailers>
---
changes in v4:
- provide a clearer commit message
- fix spelling mistakes
changes in v3:
- replace func() to use other_func() instead
changes in v2:
- this patch was added in v2
---
<diffstat output>
<unified diff>
最后,务必测试修订后的修改,尤其不要仅编辑 git format-patch 生成的补丁文件就重发。
4 跟踪补丁状态
Yocto 项目使用 Patchwork 实例
跟踪提交到各邮件列表的补丁状态,并支持自动化补丁测试。
每个补丁都会检查常见错误及格式偏差;发现问题时,patchtest 会通知提交者,
以减轻维护者的审阅负担。
备注
系统并不完美,修改有时会在处理过程中被遗漏。 如果补丁一段时间没有进展和反馈,询问状态是合理的。
几天没有反馈的补丁也可能已经合入,可以运行 git pull branch 检查。
许多层维护者接受补丁后并不会发送确认邮件。
如果几天后仍没有回复也没有合入,可能是补丁被遗漏,或相关审阅者暂时不在。
此时可以回复自己的邮件,提醒并请求反馈。
备注
功能冻结期间,功能补丁和配方升级补丁的审阅可能推迟, 因为此时不合入这类修改,可能需要等冻结结束。
维护者通常还会用 -next 分支在正式合入前测试提交。
因此,查看补丁是否进入这些分支,也能了解它的状态。
OpenEmbedded-Core 常用测试分支如下:
openembedded-core 的 "master-next": 位于 openembedded-core,包含对核心元数据的候选修改。
meta-yocto 的 "master-next": 位于 meta-yocto,包含对 meta-yocto 的候选修改。
类似地,项目维护的稳定分支也可能有对应的 -next 分支,收集候选修改。
例如,"openembedded-core" 和 "meta-yocto" 仓库中的
blacksail-next 和 wrynose-next。
其他层也可能有类似测试分支,但没有统一要求或标准,请查看所贡献层的文档。
4 接受 AI 生成的代码
Yocto 项目和 OpenEmbedded 对生成式 AI 工具的使用遵循 Linux 基金会的指导: https://www.linuxfoundation.org/legal/generative-ai。
本文件现有的全部准则仍须遵守,包括 配方风格指南。 此外,在 实现并提交修改 所述要求之外,还需满足以下条件。
所有 AI 生成的代码都必须在提交说明中明确标注,放在 Signed-off-by 行之前。
同时强烈建议,提交中的补丁或代码也通过注释或其他方式表明其由 AI 生成。
以下是格式正确的提交说明示例::
component: Add the ability to ...
AI-Generated: Uses GitHub Copilot
Signed-off-by: Your Name <your.name@domain>
Signed-off-by 必须由你本人填写,不能由 AI 助手代写。
贡献修改时,这一签署行仍然是必需的,
开发者来源证明 1.1 的规定仍然适用。
此外,你必须确认 AI 贡献符合 Linux 基金会政策,具体包括:
确保生成式 AI 工具的条款不会对输出的使用施加与项目开源许可证、 知识产权政策或开源定义不一致的合同限制。
如果 AI 输出包含由第三方创作或拥有版权的既有材料,包括已有开源代码, 贡献之前应确认已获得第三方权利人的许可,允许使用、修改并向项目贡献这些材料。 许可可以是符合项目许可政策的开源许可证或公有领域声明等形式。 同时,应随贡献提供第三方权利的声明和署名,以及适用许可证条款的信息。