sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/process/2.ProcessmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/zh_TW/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/it_IT/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ja_JP/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/ko_KR/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/pt_BR/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget%/translations/sp_SP/process/2.ProcessmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhR/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/process/2.Process.rsthKubh field_body)}(hA:ref:`Documentation/process/2.Process.rst ` h]h)}(h@:ref:`Documentation/process/2.Process.rst `h]h)}(hhh]hinline)}(hhh]h#Documentation/process/2.Process.rst}(hhhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc$translations/zh_CN/process/2.Process refdomainjreftyperef refexplicitrefwarn reftargetdevelopment_processuh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-hhhKubh)}(h0时奎亮 Alex Shi h]h)}(h/时奎亮 Alex Shi h](h时奎亮 Alex Shi <}(hjBhhhNhNubh reference)}(halex.shi@linux.alibaba.comh]halex.shi@linux.alibaba.com}(hjLhhhNhNubah}(h]h ]h"]h$]h&]refuri!mailto:alex.shi@linux.alibaba.comuh1jJhjBubh>}(hjBhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj>ubah}(h]h ]h"]h$]h&]uh1hhj-ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h校译h]h校译}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjrhhhKubh)}(h*吴想成 Wu XiangCheng h]h)}(h)吴想成 Wu XiangCheng h](h吴想成 Wu XiangCheng <}(hjhhhNhNubjK)}(hbobwxc@email.cnh]hbobwxc@email.cn}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:bobwxc@email.cnuh1jJhjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhjrubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhtarget)}(h.. _cn_development_process:h]h}(h]h ]h"]h$]h&]refidcn-development-processuh1jhKhhhhhhubhsection)}(hhh](htitle)}(h开发流程如何进行h]h开发流程如何进行}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKubh)}(hXv90年代早期的Linux内核开发是一件相当松散的事情,涉及的用户和开发人员相对较少。 由于拥有数以百万计的用户群,且每年有大约2000名开发人员参与进来,内核因此必须 发展出许多既定流程来保证开发的顺利进行。要参与到流程中来,需要对此流程的进行 方式有一个扎实的理解。h]hXv90年代早期的Linux内核开发是一件相当松散的事情,涉及的用户和开发人员相对较少。 由于拥有数以百万计的用户群,且每年有大约2000名开发人员参与进来,内核因此必须 发展出许多既定流程来保证开发的顺利进行。要参与到流程中来,需要对此流程的进行 方式有一个扎实的理解。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hhh](j)}(h总览h]h总览}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKubh)}(hX内核开发使用一个松散的、基于时间的滚动发布(rolling release)开发模型。 一个新的主内核发行版本(作为示例,我们将其称为 9.x) [1]_ 大约每两到三个月 发布一次,它带来了新特性、内部 API 的更改等。一个典型的版本包含大约 13,000 个变更集(changesets),涉及几十万行代码的修改。最近的发行版本及其日期可以 在这里找到 `维基百科 `_h](h内核开发使用一个松散的、基于时间的滚动发布(rolling release)开发模型。 一个新的主内核发行版本(作为示例,我们将其称为 9.x) }(hjhhhNhNubhfootnote_reference)}(h[1]_h]h1}(hjhhhNhNubah}(h]id3ah ]h"]h$]h&]jid5docnamejuh1jhjresolvedKubh 大约每两到三个月 发布一次,它带来了新特性、内部 API 的更改等。一个典型的版本包含大约 13,000 个变更集(changesets),涉及几十万行代码的修改。最近的发行版本及其日期可以 在这里找到 }(hjhhhNhNubjK)}(hL`维基百科 `_h]h 维基百科}(hjhhhNhNubah}(h]h ]h"]h$]h&]name 维基百科refuri:https://en.wikipedia.org/wiki/Linux_kernel_version_historyuh1jJhjubj)}(h= h]h}(h]id4ah ]h"] 维基百科ah$]h&]refurij.uh1j referencedKhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubhfootnote)}(hX0严格来说,Linux 内核并不采用语义化版本号方案,而是将 9.x 这一组数字 作为一个整体来标识主发行版本号。对于每一个版本,x 都会递增,但只有 当 x 被认为足够大时,9 才会递增(例如:Linux 5.0 是紧随 Linux 4.20 之后发布的)。 h](hlabel)}(h1h]h1}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1jIhjEubh)}(hX/严格来说,Linux 内核并不采用语义化版本号方案,而是将 9.x 这一组数字 作为一个整体来标识主发行版本号。对于每一个版本,x 都会递增,但只有 当 x 被认为足够大时,9 才会递增(例如:Linux 5.0 是紧随 Linux 4.20 之后发布的)。h]hX/严格来说,Linux 内核并不采用语义化版本号方案,而是将 9.x 这一组数字 作为一个整体来标识主发行版本号。对于每一个版本,x 都会递增,但只有 当 x 被认为足够大时,9 才会递增(例如:Linux 5.0 是紧随 Linux 4.20 之后发布的)。}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjEubeh}(h]jah ]h"]1ah$]h&]jajjuh1jChhhK"hjhhjKubh)}(hX对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开头,“合并 窗口”被打开。这时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内 核中。在这段时间内,新开发周期的大部分变更(以及所有主要变更)将以接近每天 1000次变更(“补丁”或“变更集”)的速度合并。h]hX对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开头,“合并 窗口”被打开。这时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内 核中。在这段时间内,新开发周期的大部分变更(以及所有主要变更)将以接近每天 1000次变更(“补丁”或“变更集”)的速度合并。}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK'hjhhubh)}(h(顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是经 提前收集、测试和分级的。稍后将详细描述该过程的工作方式。)h]h(顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是经 提前收集、测试和分级的。稍后将详细描述该过程的工作方式。)}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubh)}(hXf合并窗口持续大约两周。在这段时间结束时,Linus Torvalds将声明窗口已关闭,并 释放第一个“rc”内核。例如,对于目标为9.x的内核,在合并窗口结束时发生的释放 将被称为9.x-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一 个内核的时间已经到来。h]hXf合并窗口持续大约两周。在这段时间结束时,Linus Torvalds将声明窗口已关闭,并 释放第一个“rc”内核。例如,对于目标为9.x的内核,在合并窗口结束时发生的释放 将被称为9.x-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一 个内核的时间已经到来。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK/hjhhubh)}(hX在接下来的6到10周内,只有修复问题的补丁才应该提交给主线。有时会允许更大的 更改,但这种情况很少发生;试图在合并窗口外合并新功能的开发人员往往受不到 友好的接待。一般来说,如果您错过了给定特性的合并窗口,最好的做法是等待下一 个开发周期。(偶尔会对未支持硬件的驱动程序进行例外;如果它们不改变已有代码, 则不会导致回归,应该可以随时被安全地加入)。h]hX在接下来的6到10周内,只有修复问题的补丁才应该提交给主线。有时会允许更大的 更改,但这种情况很少发生;试图在合并窗口外合并新功能的开发人员往往受不到 友好的接待。一般来说,如果您错过了给定特性的合并窗口,最好的做法是等待下一 个开发周期。(偶尔会对未支持硬件的驱动程序进行例外;如果它们不改变已有代码, 则不会导致回归,应该可以随时被安全地加入)。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hjhhubh)}(hX随着修复程序进入主线,补丁速度将随着时间的推移而变慢。Linus大约每周发布一次 新的-rc内核;在内核被认为足够稳定并最终发布前,一般会达到-rc6到-rc9之间。 然后,整个过程又重新开始了。h]hX随着修复程序进入主线,补丁速度将随着时间的推移而变慢。Linus大约每周发布一次 新的-rc内核;在内核被认为足够稳定并最终发布前,一般会达到-rc6到-rc9之间。 然后,整个过程又重新开始了。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK:hjhhubh)}(h>例如,这里是5.4的开发周期进行情况(2019年):h]h>例如,这里是5.4的开发周期进行情况(2019年):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK>hjhhubh block_quote)}(hX============== ============================== 九月 15 5.3 稳定版发布 九月 30 5.4-rc1 合并窗口关闭 十月 6 5.4-rc2 十月 13 5.4-rc3 十月 20 5.4-rc4 十月 27 5.4-rc5 十一月 3 5.4-rc6 十一月 10 5.4-rc7 十一月 17 5.4-rc8 十一月 24 5.4 稳定版发布 ============== ============================== h]htable)}(hhh]htgroup)}(hhh](hcolspec)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjubhtbody)}(hhh](hrow)}(hhh](hentry)}(hhh]h)}(h 九月 15h]h 九月 15}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.3 稳定版发布h]h5.3 稳定版发布}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhj ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 九月 30h]h 九月 30}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhj+ubah}(h]h ]h"]h$]h&]uh1jhj(ubj)}(hhh]h)}(h5.4-rc1 合并窗口关闭h]h5.4-rc1 合并窗口关闭}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKBhjBubah}(h]h ]h"]h$]h&]uh1jhj(ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h十月 6h]h十月 6}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjbubah}(h]h ]h"]h$]h&]uh1jhj_ubj)}(hhh]h)}(h5.4-rc2h]h5.4-rc2}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjyubah}(h]h ]h"]h$]h&]uh1jhj_ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十月 13h]h 十月 13}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.4-rc3h]h5.4-rc3}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十月 20h]h 十月 20}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.4-rc4h]h5.4-rc4}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十月 27h]h 十月 27}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.4-rc5h]h5.4-rc5}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十一月 3h]h 十一月 3}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhj>ubah}(h]h ]h"]h$]h&]uh1jhj;ubj)}(hhh]h)}(h5.4-rc6h]h5.4-rc6}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjUubah}(h]h ]h"]h$]h&]uh1jhj;ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十一月 10h]h 十一月 10}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjuubah}(h]h ]h"]h$]h&]uh1jhjrubj)}(hhh]h)}(h5.4-rc7h]h5.4-rc7}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKHhjubah}(h]h ]h"]h$]h&]uh1jhjrubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十一月 17h]h 十一月 17}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.4-rc8h]h5.4-rc8}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十一月 24h]h 十一月 24}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.4 稳定版发布h]h5.4 稳定版发布}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]colsKuh1jhjubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhhhK@hjhhubh)}(hXC开发人员如何决定何时结束开发周期并创建稳定版本?最重要的指标是以前版本的 回归列表。不欢迎出现任何错误,但是那些破坏了以前能工作的系统的错误被认为是 特别严重的。因此,导致回归的补丁是不受欢迎的,很可能在稳定期内删除。h]hXC开发人员如何决定何时结束开发周期并创建稳定版本?最重要的指标是以前版本的 回归列表。不欢迎出现任何错误,但是那些破坏了以前能工作的系统的错误被认为是 特别严重的。因此,导致回归的补丁是不受欢迎的,很可能在稳定期内删除。}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKMhjhhubh)}(hX开发人员的目标是在稳定发布之前修复所有已知的回归。在现实世界中,这种完美是 很难实现的;在这种规模的项目中,变数太多了。需要说明的是,延迟最终版本只会 使问题变得更糟;等待下一个合并窗口的更改将变多,导致下次出现更多的回归错误。 因此,大多数内核发布时都会带有一部分已知的回归问题,不过希望它们都不是严重 的问题。h]hX开发人员的目标是在稳定发布之前修复所有已知的回归。在现实世界中,这种完美是 很难实现的;在这种规模的项目中,变数太多了。需要说明的是,延迟最终版本只会 使问题变得更糟;等待下一个合并窗口的更改将变多,导致下次出现更多的回归错误。 因此,大多数内核发布时都会带有一部分已知的回归问题,不过希望它们都不是严重 的问题。}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubh)}(h一旦一个稳定的版本发布,它的持续维护工作就被移交给“稳定团队”,目前由 Greg Kroah-Hartman领导。稳定团队将使用9.x.y编号方案不定期地发布稳定版本的 更新。h]h一旦一个稳定的版本发布,它的持续维护工作就被移交给“稳定团队”,目前由 Greg Kroah-Hartman领导。稳定团队将使用9.x.y编号方案不定期地发布稳定版本的 更新。}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKWhjhhubh)}(hX要合入更新版本,补丁必须(1)修复一个重要的缺陷,且(2)已经合并到 下一个开发版本主线中。内核通常会在其初始版本后的一个以上的开发周期内收到 稳定版更新。例如,5.2内核的历史如下(2019年):h]hX要合入更新版本,补丁必须(1)修复一个重要的缺陷,且(2)已经合并到 下一个开发版本主线中。内核通常会在其初始版本后的一个以上的开发周期内收到 稳定版更新。例如,5.2内核的历史如下(2019年):}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjhhubj)}(hX7============== =============================== 七月 7 5.2 稳定版发布 七月 13 5.2.1 七月 21 5.2.2 七月 26 5.2.3 七月 28 5.2.4 七月 31 5.2.5 ... ... 十月 11 5.2.21 ============== =============================== h]j)}(hhh]j)}(hhh](j)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjoubj)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jhjoubj)}(hhh](j)}(hhh](j)}(hhh]h)}(h七月 7h]h七月 7}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.2 稳定版发布h]h5.2 稳定版发布}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 七月 13h]h 七月 13}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKahjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.2.1h]h5.2.1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKahjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 七月 21h]h 七月 21}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.2.2h]h5.2.2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKbhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 七月 26h]h 七月 26}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKchj1ubah}(h]h ]h"]h$]h&]uh1jhj.ubj)}(hhh]h)}(h5.2.3h]h5.2.3}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKchjHubah}(h]h ]h"]h$]h&]uh1jhj.ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 七月 28h]h 七月 28}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjhubah}(h]h ]h"]h$]h&]uh1jhjeubj)}(hhh]h)}(h5.2.4h]h5.2.4}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjubah}(h]h ]h"]h$]h&]uh1jhjeubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 七月 31h]h 七月 31}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h5.2.5h]h5.2.5}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h...h]h...}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh]h)}(h...h]h...}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hhh](j)}(hhh]h)}(h 十月 11h]h 十月 11}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKghj ubah}(h]h ]h"]h$]h&]uh1jhj ubj)}(hhh]h)}(h5.2.21h]h5.2.21}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKghj$ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjoubeh}(h]h ]h"]h$]h&]colsKuh1jhjlubah}(h]h ]h"]h$]h&]uh1jhjhubah}(h]h ]h"]h$]h&]uh1jhhhK_hjhhubh)}(h*5.2.21是5.2版本的最终稳定更新。h]h*5.2.21是5.2版本的最终稳定更新。}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKjhjhhubh)}(h有些内核被指定为“长期”内核;它们将得到更长时间的支持。请参考以下链接 获取当前长期支持内核版本及其维护者的列表:h]h有些内核被指定为“长期”内核;它们将得到更长时间的支持。请参考以下链接 获取当前长期支持内核版本及其维护者的列表:}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKlhjhhubj)}(h.https://www.kernel.org/category/releases.html h]h)}(h-https://www.kernel.org/category/releases.htmlh]jK)}(hj|h]h-https://www.kernel.org/category/releases.html}(hj~hhhNhNubah}(h]h ]h"]h$]h&]refurij|uh1jJhjzubah}(h]h ]h"]h$]h&]uh1hhhhKohjvubah}(h]h ]h"]h$]h&]uh1jhhhKohjhhubh)}(h长期支持内核的选择纯粹是维护人员是否有需求和时间来维护该版本的问题。 目前还没有为即将发布的任何特定版本提供长期支持的已知计划。h]h长期支持内核的选择纯粹是维护人员是否有需求和时间来维护该版本的问题。 目前还没有为即将发布的任何特定版本提供长期支持的已知计划。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKqhjhhubeh}(h]id2ah ]h"]总览ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h补丁的生命周期h]h补丁的生命周期}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKuubh)}(hX补丁不会直接从开发人员的键盘进入主线内核。相反,有一个稍微复杂(如果有些非 正式)的过程,旨在确保对每个补丁进行质量审查,并确保每个补丁实现了一个在主线 中需要的更改。对于小的修复,这个过程可能会很快完成,,而对于较大或有争议的 变更,可能会持续数年。许多开发人员的沮丧来自于对这个过程缺乏理解或者试图绕过它。h]hX补丁不会直接从开发人员的键盘进入主线内核。相反,有一个稍微复杂(如果有些非 正式)的过程,旨在确保对每个补丁进行质量审查,并确保每个补丁实现了一个在主线 中需要的更改。对于小的修复,这个过程可能会很快完成,,而对于较大或有争议的 变更,可能会持续数年。许多开发人员的沮丧来自于对这个过程缺乏理解或者试图绕过它。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjhhubh)}(h为了减少这种挫败,本文将描述补丁如何进入内核。下面的介绍以一种较为理想化的 方式描述了这个过程。更详细的过程将在后面的章节中介绍。h]h为了减少这种挫败,本文将描述补丁如何进入内核。下面的介绍以一种较为理想化的 方式描述了这个过程。更详细的过程将在后面的章节中介绍。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjhhubh)}(h$补丁通常要经历以下阶段:h]h$补丁通常要经历以下阶段:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh bullet_list)}(hhh](h list_item)}(hX&设计。这就是补丁的真正需求——以及满足这些需求的方式——所在。设计工作通常 是在不涉及社区的情况下完成的,但是如果可能的话,最好是在公开的情况下完成 这项工作;这样可以节省很多稍后再重新设计的时间。 h]h)}(hX%设计。这就是补丁的真正需求——以及满足这些需求的方式——所在。设计工作通常 是在不涉及社区的情况下完成的,但是如果可能的话,最好是在公开的情况下完成 这项工作;这样可以节省很多稍后再重新设计的时间。h]hX%设计。这就是补丁的真正需求——以及满足这些需求的方式——所在。设计工作通常 是在不涉及社区的情况下完成的,但是如果可能的话,最好是在公开的情况下完成 这项工作;这样可以节省很多稍后再重新设计的时间。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h早期评审。补丁被发布到相关的邮件列表中,列表中的开发人员会回复他们可能有 的任何评论。如果一切顺利的话,这个过程应该会发现补丁的任何主要问题。 h]h)}(h早期评审。补丁被发布到相关的邮件列表中,列表中的开发人员会回复他们可能有 的任何评论。如果一切顺利的话,这个过程应该会发现补丁的任何主要问题。h]h早期评审。补丁被发布到相关的邮件列表中,列表中的开发人员会回复他们可能有 的任何评论。如果一切顺利的话,这个过程应该会发现补丁的任何主要问题。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX更广泛的评审。当补丁接近准备好纳入主线时,它应该被相关的子系统维护人员 接受——尽管这种接受并不能保证补丁会一直延伸到主线。补丁将出现在维护人员的 子系统树中,并进入 -next 树(如下所述)。当流程进行时,此步骤将会对补丁 进行更广泛的审查,并发现由于将此补丁与其他人所做的工作合并而导致的任何 问题。 h]h)}(hX更广泛的评审。当补丁接近准备好纳入主线时,它应该被相关的子系统维护人员 接受——尽管这种接受并不能保证补丁会一直延伸到主线。补丁将出现在维护人员的 子系统树中,并进入 -next 树(如下所述)。当流程进行时,此步骤将会对补丁 进行更广泛的审查,并发现由于将此补丁与其他人所做的工作合并而导致的任何 问题。h]hX更广泛的评审。当补丁接近准备好纳入主线时,它应该被相关的子系统维护人员 接受——尽管这种接受并不能保证补丁会一直延伸到主线。补丁将出现在维护人员的 子系统树中,并进入 -next 树(如下所述)。当流程进行时,此步骤将会对补丁 进行更广泛的审查,并发现由于将此补丁与其他人所做的工作合并而导致的任何 问题。}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最优先工作。 如果您的补丁得到了需要更改的反馈,那么您应该进行这些更改,或者解释为何 不应该进行这些更改。如果您的补丁没有评审意见,也没有被其相应的子系统或 驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核使其可被正常 应用,并不断地发送它以供审查和合并。 h]h)}(hX请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最优先工作。 如果您的补丁得到了需要更改的反馈,那么您应该进行这些更改,或者解释为何 不应该进行这些更改。如果您的补丁没有评审意见,也没有被其相应的子系统或 驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核使其可被正常 应用,并不断地发送它以供审查和合并。h]hX请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最优先工作。 如果您的补丁得到了需要更改的反馈,那么您应该进行这些更改,或者解释为何 不应该进行这些更改。如果您的补丁没有评审意见,也没有被其相应的子系统或 驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核使其可被正常 应用,并不断地发送它以供审查和合并。}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj8ubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h合并到主线。最终,一个成功的补丁将被合并到由LinusTorvalds管理的主线存储库 中。此时可能会出现更多的评论和/或问题;对开发人员来说应对这些问题并解决 出现的任何问题仍很重要。 h]h)}(h合并到主线。最终,一个成功的补丁将被合并到由LinusTorvalds管理的主线存储库 中。此时可能会出现更多的评论和/或问题;对开发人员来说应对这些问题并解决 出现的任何问题仍很重要。h]h合并到主线。最终,一个成功的补丁将被合并到由LinusTorvalds管理的主线存储库 中。此时可能会出现更多的评论和/或问题;对开发人员来说应对这些问题并解决 出现的任何问题仍很重要。}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(ha稳定版发布。大量用户可能受此补丁影响,因此可能再次出现新的问题。 h]h)}(h`稳定版发布。大量用户可能受此补丁影响,因此可能再次出现新的问题。h]h`稳定版发布。大量用户可能受此补丁影响,因此可能再次出现新的问题。}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXG长期维护。虽然开发人员在合并代码后可能会忘记代码,但这种行为往往会给开发 社区留下不良印象。合并代码消除了一些维护负担,因为其他人将修复由API更改 引起的问题。但是,如果代码要长期保持可用,原始开发人员应该继续为代码负责。 h]h)}(hXF长期维护。虽然开发人员在合并代码后可能会忘记代码,但这种行为往往会给开发 社区留下不良印象。合并代码消除了一些维护负担,因为其他人将修复由API更改 引起的问题。但是,如果代码要长期保持可用,原始开发人员应该继续为代码负责。h]hXF长期维护。虽然开发人员在合并代码后可能会忘记代码,但这种行为往往会给开发 社区留下不良印象。合并代码消除了一些维护负担,因为其他人将修复由API更改 引起的问题。但是,如果代码要长期保持可用,原始开发人员应该继续为代码负责。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhjhhubh)}(h内核开发人员(或他们的雇主)犯的最大错误之一是试图将流程简化为一个“合并到 主线”步骤。这种方法总是会让所有相关人员感到沮丧。h]h内核开发人员(或他们的雇主)犯的最大错误之一是试图将流程简化为一个“合并到 主线”步骤。这种方法总是会让所有相关人员感到沮丧。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id6ah ]h"]补丁的生命周期ah$]h&]uh1jhjhhhhhKuubj)}(hhh](j)}(h补丁如何进入内核h]h补丁如何进入内核}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKubh)}(hX只有一个人可以将补丁合并到主线内核存储库中:Linus Torvalds。但是,在进入 2.6.38内核的9500多个补丁中,只有112个(大约1.3%)是由Linus自己直接选择的。 内核项目已经发展到一个没有一个开发人员可以在没有支持的情况下检查和选择每个 补丁的规模。内核开发人员处理这种增长的方式是使用围绕信任链构建的助理系统。h]hX只有一个人可以将补丁合并到主线内核存储库中:Linus Torvalds。但是,在进入 2.6.38内核的9500多个补丁中,只有112个(大约1.3%)是由Linus自己直接选择的。 内核项目已经发展到一个没有一个开发人员可以在没有支持的情况下检查和选择每个 补丁的规模。内核开发人员处理这种增长的方式是使用围绕信任链构建的助理系统。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX内核代码库在逻辑上被分解为一组子系统:网络、特定体系结构支持、内存管理、视 频设备等。大多数子系统都有一个指定的维护人员,其总体负责该子系统中的代码。 这些子系统维护者(松散地)是他们所管理的内核部分的“守门员”;他们(通常) 会接受一个补丁以包含到主线内核中。h]hX内核代码库在逻辑上被分解为一组子系统:网络、特定体系结构支持、内存管理、视 频设备等。大多数子系统都有一个指定的维护人员,其总体负责该子系统中的代码。 这些子系统维护者(松散地)是他们所管理的内核部分的“守门员”;他们(通常) 会接受一个补丁以包含到主线内核中。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXp子系统维护人员每个人都管理着自己版本的内核源代码树,通常(并非总是)使用Git。 Git等工具(以及Quilt或Mercurial等相关工具)允许维护人员跟踪补丁列表,包括作者 信息和其他元数据。在任何给定的时间,维护人员都可以确定他或她的存储库中的哪 些补丁在主线中找不到。h]hXp子系统维护人员每个人都管理着自己版本的内核源代码树,通常(并非总是)使用Git。 Git等工具(以及Quilt或Mercurial等相关工具)允许维护人员跟踪补丁列表,包括作者 信息和其他元数据。在任何给定的时间,维护人员都可以确定他或她的存储库中的哪 些补丁在主线中找不到。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX当合并窗口打开时,顶级维护人员将要求Linus从存储库中“拉出”他们为合并选择 的补丁。如果Linus同意,补丁流将流向他的存储库,成为主线内核的一部分。 Linus对拉取中接收到的特定补丁的关注程度各不相同。很明显,有时他看起来很 关注。但是一般来说,Linus相信子系统维护人员不会向上游发送坏补丁。h]hX当合并窗口打开时,顶级维护人员将要求Linus从存储库中“拉出”他们为合并选择 的补丁。如果Linus同意,补丁流将流向他的存储库,成为主线内核的一部分。 Linus对拉取中接收到的特定补丁的关注程度各不相同。很明显,有时他看起来很 关注。但是一般来说,Linus相信子系统维护人员不会向上游发送坏补丁。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX子系统维护人员反过来也可以从其他维护人员那里获取补丁。例如,网络树是由首先 在专用于网络设备驱动程序、无线网络等的树中积累的补丁构建的。此存储链可以 任意长,但很少超过两个或三个链接。由于链中的每个维护者都信任那些管理较低 级别树的维护者,所以这个过程称为“信任链”。h]hX子系统维护人员反过来也可以从其他维护人员那里获取补丁。例如,网络树是由首先 在专用于网络设备驱动程序、无线网络等的树中积累的补丁构建的。此存储链可以 任意长,但很少超过两个或三个链接。由于链中的每个维护者都信任那些管理较低 级别树的维护者,所以这个过程称为“信任链”。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h显然,在这样的系统中,获取内核补丁取决于找到正确的维护者。直接向Linus发送 补丁通常不是正确的方法。h]h显然,在这样的系统中,获取内核补丁取决于找到正确的维护者。直接向Linus发送 补丁通常不是正确的方法。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id7ah ]h"]补丁如何进入内核ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(hNext 树h]hNext 树}(hj& hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj# hhhhhKubh)}(hX子系统树链引导补丁流到内核,但它也提出了一个有趣的问题:如果有人想查看为 下一个合并窗口准备的所有补丁怎么办?开发人员将感兴趣的是,还有什么其他的 更改有待解决,以了解是否存在需要担心的冲突;例如,更改核心内核函数原型的 修补程序将与使用该函数旧形式的任何其他修补程序冲突。审查人员和测试人员希望 在所有这些变更到达主线内核之前,能够访问它们的集成形式的变更。您可以从所有 相关的子系统树中提取更改,但这将是一项复杂且容易出错的工作。h]hX子系统树链引导补丁流到内核,但它也提出了一个有趣的问题:如果有人想查看为 下一个合并窗口准备的所有补丁怎么办?开发人员将感兴趣的是,还有什么其他的 更改有待解决,以了解是否存在需要担心的冲突;例如,更改核心内核函数原型的 修补程序将与使用该函数旧形式的任何其他修补程序冲突。审查人员和测试人员希望 在所有这些变更到达主线内核之前,能够访问它们的集成形式的变更。您可以从所有 相关的子系统树中提取更改,但这将是一项复杂且容易出错的工作。}(hj4 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubh)}(hX;解决方案以-next树的形式出现,在这里子系统树被收集以供测试和审查。这些树中 由Andrew Morton维护的较老的一个,被称为“-mm”(用于内存管理,创建时为此)。 -mm 树集成了一长串子系统树中的补丁;它还包含一些旨在帮助调试的补丁。h]hX;解决方案以-next树的形式出现,在这里子系统树被收集以供测试和审查。这些树中 由Andrew Morton维护的较老的一个,被称为“-mm”(用于内存管理,创建时为此)。 -mm 树集成了一长串子系统树中的补丁;它还包含一些旨在帮助调试的补丁。}(hjB hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubh)}(hX 除此之外,-mm 还包含大量由Andrew直接选择的补丁。这些补丁可能已经发布在邮件 列表上,或者它们可能应用于内核中未指定子系统树的部分。同时,-mm 作为最后 手段的子系统树;如果没有其他明显的路径可以让补丁进入主线,那么它很可能最 终选择-mm 树。累积在-mm 中的各种补丁最终将被转发到适当的子系统树,或者直接 发送到Linus。在典型的开发周期中,大约5-10%的补丁通过-mm 进入主线。h]hX 除此之外,-mm 还包含大量由Andrew直接选择的补丁。这些补丁可能已经发布在邮件 列表上,或者它们可能应用于内核中未指定子系统树的部分。同时,-mm 作为最后 手段的子系统树;如果没有其他明显的路径可以让补丁进入主线,那么它很可能最 终选择-mm 树。累积在-mm 中的各种补丁最终将被转发到适当的子系统树,或者直接 发送到Linus。在典型的开发周期中,大约5-10%的补丁通过-mm 进入主线。}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubh)}(hJ当前-mm 补丁可在“mmotm”(-mm of the moment)目录中找到:h]hJ当前-mm 补丁可在“mmotm”(-mm of the moment)目录中找到:}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubj)}(h$https://www.ozlabs.org/~akpm/mmotm/ h]h)}(h#https://www.ozlabs.org/~akpm/mmotm/h]jK)}(hjr h]h#https://www.ozlabs.org/~akpm/mmotm/}(hjt hhhNhNubah}(h]h ]h"]h$]h&]refurijr uh1jJhjp ubah}(h]h ]h"]h$]h&]uh1hhhhKhjl ubah}(h]h ]h"]h$]h&]uh1jhhhKhj# hhubh)}(hS然而,使用MMOTM树可能会十分令人头疼;它甚至可能无法编译。h]hS然而,使用MMOTM树可能会十分令人头疼;它甚至可能无法编译。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubh)}(h下一个周期补丁合并的主要树是linux-next,由Stephen Rothwell 维护。根据设计 linux-next 是下一个合并窗口关闭后主线的快照。linux-next树在Linux-kernel 和 Linux-next 邮件列表中发布,可从以下位置下载:h]h下一个周期补丁合并的主要树是linux-next,由Stephen Rothwell 维护。根据设计 linux-next 是下一个合并窗口关闭后主线的快照。linux-next树在Linux-kernel 和 Linux-next 邮件列表中发布,可从以下位置下载:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubj)}(h.https://www.kernel.org/pub/linux/kernel/next/ h]h)}(h-https://www.kernel.org/pub/linux/kernel/next/h]jK)}(hj h]h-https://www.kernel.org/pub/linux/kernel/next/}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jJhj ubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhhhKhj# hhubh)}(hLinux-next 已经成为内核开发过程中不可或缺的一部分;在一个给定的合并窗口中合并 的所有补丁都应该在合并窗口打开之前的一段时间内找到进入Linux-next 的方法。h]hLinux-next 已经成为内核开发过程中不可或缺的一部分;在一个给定的合并窗口中合并 的所有补丁都应该在合并窗口打开之前的一段时间内找到进入Linux-next 的方法。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj# hhubeh}(h]nextah ]h"]next 树ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h Staging 树h]h Staging 树}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhhhKubh)}(hX内核源代码树包含drivers/staging/目录,其中有许多驱动程序或文件系统的子目录 正在被添加到内核树中。它们在仍然需要更多的修正的时候可以保留在driver/staging/ 目录中;一旦完成,就可以将它们移到内核中。这是一种跟踪不符合Linux内核编码或 质量标准的驱动程序的方法,人们可能希望使用它们并跟踪开发。h]hX内核源代码树包含drivers/staging/目录,其中有许多驱动程序或文件系统的子目录 正在被添加到内核树中。它们在仍然需要更多的修正的时候可以保留在driver/staging/ 目录中;一旦完成,就可以将它们移到内核中。这是一种跟踪不符合Linux内核编码或 质量标准的驱动程序的方法,人们可能希望使用它们并跟踪开发。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hXGreg Kroah Hartman 目前负责维护staging 树。仍需要修正的驱动程序将发送给他, 每个驱动程序在drivers/staging/中都有自己的子目录。除了驱动程序源文件之外, 目录中还应该有一个TODO文件。TODO文件列出了驱动程序需要接受的暂停的工作, 以及驱动程序的任何补丁都应该抄送的人员列表。当前的规则要求,staging的驱动 程序必须至少正确编译。h]hXGreg Kroah Hartman 目前负责维护staging 树。仍需要修正的驱动程序将发送给他, 每个驱动程序在drivers/staging/中都有自己的子目录。除了驱动程序源文件之外, 目录中还应该有一个TODO文件。TODO文件列出了驱动程序需要接受的暂停的工作, 以及驱动程序的任何补丁都应该抄送的人员列表。当前的规则要求,staging的驱动 程序必须至少正确编译。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hXStaging 是一种让新的驱动程序进入主线的相对容易的方法,它们会幸运地引起其他 开发人员的注意,并迅速改进。然而,进入staging并不是故事的结尾;staging中 没有看到常规进展的代码最终将被删除。经销商也倾向于相对不愿意使用staging驱动 程序。因此,在成为一个合适的主线驱动的路上,staging 仅是一个中转站。h]hXStaging 是一种让新的驱动程序进入主线的相对容易的方法,它们会幸运地引起其他 开发人员的注意,并迅速改进。然而,进入staging并不是故事的结尾;staging中 没有看到常规进展的代码最终将被删除。经销商也倾向于相对不愿意使用staging驱动 程序。因此,在成为一个合适的主线驱动的路上,staging 仅是一个中转站。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubeh}(h]stagingah ]h"] staging 树ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h工具h]h工具}(hj( hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj% hhhhhKubh)}(hXL从上面的文本可以看出,内核开发过程在很大程度上依赖于在不同方向上聚集补丁的 能力。如果没有适当强大的工具,整个系统将无法在任何地方正常工作。关于如何使用 这些工具的教程远远超出了本文档的范围,但还是用一点篇幅介绍一些关键点。h]hXL从上面的文本可以看出,内核开发过程在很大程度上依赖于在不同方向上聚集补丁的 能力。如果没有适当强大的工具,整个系统将无法在任何地方正常工作。关于如何使用 这些工具的教程远远超出了本文档的范围,但还是用一点篇幅介绍一些关键点。}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj% hhubh)}(hX,到目前为止,内核社区使用的主要源代码管理系统是git。Git是在自由软件社区中开发 的许多分布式版本控制系统之一。它非常适合内核开发,因为它在处理大型存储库和 大量补丁时性能非常好。它也以难以学习和使用而著称,尽管随着时间的推移它变得 更好了。对于内核开发人员来说,对Git的某种熟悉几乎是一种要求;即使他们不将它 用于自己的工作,他们也需要Git来跟上其他开发人员(以及主线)正在做的事情。h]hX,到目前为止,内核社区使用的主要源代码管理系统是git。Git是在自由软件社区中开发 的许多分布式版本控制系统之一。它非常适合内核开发,因为它在处理大型存储库和 大量补丁时性能非常好。它也以难以学习和使用而著称,尽管随着时间的推移它变得 更好了。对于内核开发人员来说,对Git的某种熟悉几乎是一种要求;即使他们不将它 用于自己的工作,他们也需要Git来跟上其他开发人员(以及主线)正在做的事情。}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj% hhubh)}(hG现在几乎所有的Linux发行版都打包了Git。Git主页位于:h]hG现在几乎所有的Linux发行版都打包了Git。Git主页位于:}(hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj% hhubj)}(hhttps://git-scm.com/ h]h)}(hhttps://git-scm.com/h]jK)}(hjf h]hhttps://git-scm.com/}(hjh hhhNhNubah}(h]h ]h"]h$]h&]refurijf uh1jJhjd ubah}(h]h ]h"]h$]h&]uh1hhhhMhj` ubah}(h]h ]h"]h$]h&]uh1jhhhMhj% hhubh)}(h-此页面包含了文档和教程的链接。h]h-此页面包含了文档和教程的链接。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj% hhubh)}(hW在不使用git的内核开发人员中,最流行的选择几乎肯定是Mercurial:h]hW在不使用git的内核开发人员中,最流行的选择几乎肯定是Mercurial:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj% hhubj)}(h"http://www.seleric.com/mercurial/ h]h)}(h!http://www.seleric.com/mercurial/h]jK)}(hj h]h!http://www.seleric.com/mercurial/}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jJhj ubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1jhhhM hj% hhubh)}(hfMercurial与Git共享许多特性,但它提供了一个界面,许多人觉得它更易于使用。h]hfMercurial与Git共享许多特性,但它提供了一个界面,许多人觉得它更易于使用。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj% hhubh)}(h'另一个值得了解的工具是Quilt:h]h'另一个值得了解的工具是Quilt:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj% hhubj)}(h+https://savannah.nongnu.org/projects/quilt h]h)}(h*https://savannah.nongnu.org/projects/quilth]jK)}(hj h]h*https://savannah.nongnu.org/projects/quilt}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jJhj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhhhMhj% hhubh)}(hXaQuilt 是一个补丁管理系统,而不是源代码管理系统。它不会随着时间的推移跟踪历史; 相反,它面向根据不断发展的代码库跟踪一组特定的更改。一些主要的子系统维护人员 使用Quilt来管理打算向上游移动的补丁。对于某些树的管理(例如-mm),quilt 是 最好的工具。h]hXaQuilt 是一个补丁管理系统,而不是源代码管理系统。它不会随着时间的推移跟踪历史; 相反,它面向根据不断发展的代码库跟踪一组特定的更改。一些主要的子系统维护人员 使用Quilt来管理打算向上游移动的补丁。对于某些树的管理(例如-mm),quilt 是 最好的工具。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj% hhubeh}(h]id8ah ]h"]工具ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h 邮件列表h]h 邮件列表}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhhhMubh)}(hXb大量的Linux内核开发工作是通过邮件列表完成的。如果不加入至少一个某个列表, 就很难成为社区中的一个“全功能”成员。但是,Linux邮件列表对开发人员来说也是 一个潜在的危险,他们可能会被一堆电子邮件淹没、违反Linux列表上使用的约定, 或者两者兼而有之。h]hXb大量的Linux内核开发工作是通过邮件列表完成的。如果不加入至少一个某个列表, 就很难成为社区中的一个“全功能”成员。但是,Linux邮件列表对开发人员来说也是 一个潜在的危险,他们可能会被一堆电子邮件淹没、违反Linux列表上使用的约定, 或者两者兼而有之。}(hj% hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hG大多数内核邮件列表都托管在 kernel.org;主列表位于:h]hG大多数内核邮件列表都托管在 kernel.org;主列表位于:}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj hhubj)}(hhttps://subspace.kernel.org h]h)}(hhttps://subspace.kernel.orgh]jK)}(hjG h]hhttps://subspace.kernel.org}(hjI hhhNhNubah}(h]h ]h"]h$]h&]refurijG uh1jJhjE ubah}(h]h ]h"]h$]h&]uh1hhhhM"hjA ubah}(h]h ]h"]h$]h&]uh1jhhhM"hj hhubh)}(hj其他地方也有邮件列表;请查看 MAINTAINERS 文件,获取与特定子系统相关的列表。h]hj其他地方也有邮件列表;请查看 MAINTAINERS 文件,获取与特定子系统相关的列表。}(hjc hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM$hj hhubh)}(hX当然,内核开发的核心邮件列表是linux-kernel。这个列表是一个令人生畏的地方: 每天的信息量可以达到500条,噪音很高,谈话技术性很强,且参与者并不总是表现出 高度的礼貌。但是,没有其他地方可以让内核开发社区作为一个整体聚集在一起; 不使用此列表的开发人员将错过重要信息。h]hX当然,内核开发的核心邮件列表是linux-kernel。这个列表是一个令人生畏的地方: 每天的信息量可以达到500条,噪音很高,谈话技术性很强,且参与者并不总是表现出 高度的礼貌。但是,没有其他地方可以让内核开发社区作为一个整体聚集在一起; 不使用此列表的开发人员将错过重要信息。}(hjq hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM&hj hhubh)}(h6以下一些提示可以帮助在linux-kernel生存:h]h6以下一些提示可以帮助在linux-kernel生存:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM+hj hhubj)}(hhh](j)}(hp将邮件转移到单独的文件夹,而不是主邮箱文件夹。我们必须能够持续地忽略洪流。 h]h)}(ho将邮件转移到单独的文件夹,而不是主邮箱文件夹。我们必须能够持续地忽略洪流。h]ho将邮件转移到单独的文件夹,而不是主邮箱文件夹。我们必须能够持续地忽略洪流。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM-hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h不要试图跟上每一次谈话——没人会这样。重要的是要筛选感兴趣的主题(但请注意 长时间的对话可能会偏离原来的主题,尽管未改变电子邮件的主题)和参与的人。 h]h)}(h不要试图跟上每一次谈话——没人会这样。重要的是要筛选感兴趣的主题(但请注意 长时间的对话可能会偏离原来的主题,尽管未改变电子邮件的主题)和参与的人。h]h不要试图跟上每一次谈话——没人会这样。重要的是要筛选感兴趣的主题(但请注意 长时间的对话可能会偏离原来的主题,尽管未改变电子邮件的主题)和参与的人。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM/hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hO不要回复挑事的人。如果有人试图激起愤怒,请忽略他们。 h]h)}(hN不要回复挑事的人。如果有人试图激起愤怒,请忽略他们。h]hN不要回复挑事的人。如果有人试图激起愤怒,请忽略他们。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM2hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hXJ当回复Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留 Cc: 抄送头。如果没有确实的理由(如明确的请求),则不应删除收件人。一定要 确保你要回复的人在抄送列表中。这个惯例也使你不必在回复邮件时明确要求被抄送。 h]h)}(hXI当回复Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留 Cc: 抄送头。如果没有确实的理由(如明确的请求),则不应删除收件人。一定要 确保你要回复的人在抄送列表中。这个惯例也使你不必在回复邮件时明确要求被抄送。h]hXI当回复Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留 Cc: 抄送头。如果没有确实的理由(如明确的请求),则不应删除收件人。一定要 确保你要回复的人在抄送列表中。这个惯例也使你不必在回复邮件时明确要求被抄送。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM4hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h在提出问题之前,搜索列表存档(和整个网络)。有些开发人员可能会对那些显然 没有完成家庭作业的人感到不耐烦。 h]h)}(h在提出问题之前,搜索列表存档(和整个网络)。有些开发人员可能会对那些显然 没有完成家庭作业的人感到不耐烦。h]h在提出问题之前,搜索列表存档(和整个网络)。有些开发人员可能会对那些显然 没有完成家庭作业的人感到不耐烦。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h避免顶部回复(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难 理解,印象也很差,详细请查看 :ref:`Documentation/process/submitting-patches.rst ` h]h)}(h避免顶部回复(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难 理解,印象也很差,详细请查看 :ref:`Documentation/process/submitting-patches.rst `h](h避免顶部回复(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难 理解,印象也很差,详细请查看 }(hj hhhNhNubh)}(hI:ref:`Documentation/process/submitting-patches.rst `h]h)}(hj h]h,Documentation/process/submitting-patches.rst}(hj hhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]refdocj refdomainj" reftyperef refexplicitrefwarnjinterleaved_repliesuh1hhhhM;hj ubeh}(h]h ]h"]h$]h&]uh1hhhhM;hj ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h在正确的邮件列表发问。linux-kernel 可能是通用的讨论场所,但它不是寻找所有 子系统开发人员的最佳场所。 h]h)}(h在正确的邮件列表发问。linux-kernel 可能是通用的讨论场所,但它不是寻找所有 子系统开发人员的最佳场所。h]h在正确的邮件列表发问。linux-kernel 可能是通用的讨论场所,但它不是寻找所有 子系统开发人员的最佳场所。}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM?hj@ ubah}(h]h ]h"]h$]h&]uh1jhj hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhM-hj hhubh)}(hX最后一点——找到正确的邮件列表——是开发人员常出错的地方。在linux-kernel上 提出与网络相关的问题的人几乎肯定会收到一个礼貌的建议,转到netdev列表上提出, 因为这是大多数网络开发人员经常出现的列表。还有其他列表可用于scsi、video4linux、 ide、filesystem等子系统。查找邮件列表的最佳位置是与内核源代码一起打包的 MAINTAINERS文件。#h]hX最后一点——找到正确的邮件列表——是开发人员常出错的地方。在linux-kernel上 提出与网络相关的问题的人几乎肯定会收到一个礼貌的建议,转到netdev列表上提出, 因为这是大多数网络开发人员经常出现的列表。还有其他列表可用于scsi、video4linux、 ide、filesystem等子系统。查找邮件列表的最佳位置是与内核源代码一起打包的 MAINTAINERS文件。}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMBhj hhubeh}(h]id9ah ]h"] 邮件列表ah$]h&]uh1jhjhhhhhMubj)}(hhh](j)}(h开始内核开发h]h开始内核开发}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjt hhhhhMIubh)}(h关于如何开始内核开发过程的问题很常见——个人和公司皆然。同样常见的是失误,这 使得关系的开始比本应的更困难。h]h关于如何开始内核开发过程的问题很常见——个人和公司皆然。同样常见的是失误,这 使得关系的开始比本应的更困难。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMKhjt hhubh)}(hX公司通常希望聘请知名的开发人员来启动开发团队。实际上,这是一种有效的技术。 但它也往往是昂贵的,而且对增加有经验的内核开发人员的数量没有多大帮助。考 虑到时间投入,可以让内部开发人员加快Linux内核的开发速度。利用这段时间可以 让雇主拥有一批既了解内核又了解公司的开发人员,还可以帮助培训其他人。从中期 来看,这通常是更有利可图的方法。h]hX公司通常希望聘请知名的开发人员来启动开发团队。实际上,这是一种有效的技术。 但它也往往是昂贵的,而且对增加有经验的内核开发人员的数量没有多大帮助。考 虑到时间投入,可以让内部开发人员加快Linux内核的开发速度。利用这段时间可以 让雇主拥有一批既了解内核又了解公司的开发人员,还可以帮助培训其他人。从中期 来看,这通常是更有利可图的方法。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMNhjt hhubh)}(hX可以理解的是,单个开发人员往往对起步感到茫然。从一个大型项目开始可能会很 吓人;人们往往想先用一些较小的东西来试试水。由此,一些开发人员开始创建修补 拼写错误或轻微编码风格问题的补丁。不幸的是,这样的补丁会产生一定程度的噪音, 这会分散整个开发社区的注意力,因此,它们越来越被人不看重。希望向社区介绍 自己的新开发人员将无法通过这些方式获得他们期待的反响。h]hX可以理解的是,单个开发人员往往对起步感到茫然。从一个大型项目开始可能会很 吓人;人们往往想先用一些较小的东西来试试水。由此,一些开发人员开始创建修补 拼写错误或轻微编码风格问题的补丁。不幸的是,这样的补丁会产生一定程度的噪音, 这会分散整个开发社区的注意力,因此,它们越来越被人不看重。希望向社区介绍 自己的新开发人员将无法通过这些方式获得他们期待的反响。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMThjt hhubh)}(hDAndrew Morton 为有抱负的内核开发人员提供了如下建议h]hDAndrew Morton 为有抱负的内核开发人员提供了如下建议}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMZhjt hhubh literal_block)}(hX 所有内核开发者的第一个项目肯定应该是“确保内核在您可以操作的所有 机器上始终完美运行”。通常的方法是和其他人一起解决问题(这可能需 要坚持!),但就是如此——这是内核开发的一部分。h]hX 所有内核开发者的第一个项目肯定应该是“确保内核在您可以操作的所有 机器上始终完美运行”。通常的方法是和其他人一起解决问题(这可能需 要坚持!),但就是如此——这是内核开发的一部分。}hj sbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j hhhM^hjt hhubh)}(h!(http://lwn.net/Articles/283982/)h](h(}(hj hhhNhNubjK)}(hhttp://lwn.net/Articles/283982/h]hhttp://lwn.net/Articles/283982/}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jJhj ubh)}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMbhjt hhubh)}(hX在没有明显问题需要解决的情况下,通常建议开发人员查看当前的回归和开放缺陷 列表。从来都不缺少需要解决的问题;通过解决这些问题,开发人员将从该过程获得 经验,同时与开发社区的其他成员建立相互尊重。h]hX在没有明显问题需要解决的情况下,通常建议开发人员查看当前的回归和开放缺陷 列表。从来都不缺少需要解决的问题;通过解决这些问题,开发人员将从该过程获得 经验,同时与开发社区的其他成员建立相互尊重。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMdhjt hhubeh}(h]id10ah ]h"]开始内核开发ah$]h&]uh1jhjhhhhhMIubeh}(h](jid1eh ]h"](开发流程如何进行cn_development_processeh$]h&]uh1jhhhhhhhKexpect_referenced_by_name}j jsexpect_referenced_by_id}jjsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jN generatorN datestampN source_linkN source_urlN toc_backlinksjfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj5 error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}1]jasrefids}j]jasnameids}(j jj j jjj8j5jkjjjj j j j j" j j j jq jn j j u nametypes}(j j jj8jkjj j j" j jq j uh}(jjj jjjjjj5j/jjEjjj jj j# j j j j% jn j j jt u footnote_refs}ju ]jas citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes]jEa citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jC K sRparse_messages](hsystem_message)}(hhh]h)}(heUnexpected possible title overline or transition. Treating it as ordinary text because it's so short.h]hgUnexpected possible title overline or transition. Treating it as ordinary text because it’s so short.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypeINFOlineKgsourcehuh1j hjubj )}(hhh]h)}(heUnexpected possible title overline or transition. Treating it as ordinary text because it's so short.h]hgUnexpected possible title overline or transition. Treating it as ordinary text because it’s so short.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypej lineKgsourcehuh1j hjubetransform_messages]j )}(hhh]h)}(hhh]h