summaryrefslogtreecommitdiffstats
path: root/Documentation/translations/zh_CN/process/7.AdvancedTopics.rst
blob: 6d0dadae13b12ad1fa3313e5de468b202db480a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
.. include:: ../disclaimer-zh_CN.rst

:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>`

:Translator:

 时奎亮 Alex Shi <alex.shi@linux.alibaba.com>

:校译:

 吴想成 Wu XiangCheng <bobwxc@email.cn>

.. _cn_development_advancedtopics:

高级主题
========

现在,希望您能够掌握开发流程的工作方式。然而,还有更多的东西要学!本节将介绍
一些主题,这些主题对希望成为Linux内核开发过程常规部分的开发人员有帮助。

使用Git管理补丁
---------------

内核使用分布式版本控制始于2002年初,当时Linus首次开始使用专有的Bitkeeper应用
程序。虽然BitKeeper存在争议,但它所体现的软件版本管理方法却肯定不是。分布式
版本控制可以立即加速内核开发项目。现在有好几种免费的BitKeeper替代品。
但无论好坏,内核项目都已经选择了Git作为其工具。

使用Git管理补丁可以使开发人员的生活更加轻松,尤其是随着补丁数量的增长。Git也
有其粗糙的边角和一定的危险性,它是一个年轻和强大的工具,仍然在其开发人员完善
中。本文档不会试图教会读者如何使用git;这会是个巨长的文档。相反,这里的重点
将是Git如何特别适合内核开发过程。想要加快用Git速度的开发人员可以在以下网站上
找到更多信息:

	https://git-scm.com/

	https://www.kernel.org/pub/software/scm/git/docs/user-manual.html

同时网上也能找到各种各样的教程。

在尝试使用它生成补丁供他人使用之前,第一要务是阅读上述网页,对Git的工作方式
有一个扎实的了解。使用Git的开发人员应能进行拉取主线存储库的副本,查询修订
历史,提交对树的更改,使用分支等操作。了解Git用于重写历史的工具(如rebase)
也很有用。Git有自己的术语和概念;Git的新用户应该了解引用、远程分支、索引、
快进合并、推拉、游离头等。一开始可能有点吓人,但这些概念不难通过一点学习来
理解。

使用git生成通过电子邮件提交的补丁是提高速度的一个很好的练习。

当您准备好开始建立Git树供其他人查看时,无疑需要一个可以从中拉取的服务器。
如果您有一个可以访问因特网的系统,那么使用git-daemon设置这样的服务器相对
简单。同时,免费的公共托管网站(例如github)也开始出现在网络上。成熟的开发
人员可以在kernel.org上获得一个帐户,但这些帐户并不容易得到;更多有关信息,
请参阅 https://kernel.org/faq/ 。

正常的Git工作流程涉及到许多分支的使用。每一条开发线都可以分为单独的“主题
分支”,并独立维护。Git的分支很容易使用,没有理由不使用它们。而且,在任何
情况下,您都不应该在任何您打算让其他人从中拉取的分支中进行开发。应该小心地
创建公开可用的分支;当开发分支处于完整状态并已准备好时(而不是之前)才合并
开发分支的补丁。

Git提供了一些强大的工具,可以让您重写开发历史。一个不方便的补丁(比如说,
一个打破二分法的补丁,或者有其他一些明显的缺陷)可以在适当的位置修复,或者
完全从历史中消失。一个补丁系列可以被重写,就好像它是在今天的主线上写的一样,
即使你已经花了几个月的时间在写它。可以透明地将更改从一个分支转移到另一个
分支。等等。明智地使用git修改历史的能力可以帮助创建问题更少的干净补丁集。

然而,过度使用这种功能可能会导致其他问题,而不仅仅是对创建完美项目历史的
简单痴迷。重写历史将重写该历史中包含的更改,将经过测试(希望如此)的内核树
变为未经测试的内核树。除此之外,如果开发人员没有共享项目历史,他们就无法
轻松地协作;如果您重写了其他开发人员拉入他们存储库的历史,您将使这些开发
人员的生活更加困难。因此,这里有一个简单的经验法则:被导出到其他地方的历史
在此后通常被认为是不可变的。

因此,一旦将一组更改推送到公开可用的服务器上,就不应该重写这些更改。如果您
尝试强制进行无法快进合并的更改(即不共享同一历史记录的更改),Git将尝试强制
执行此规则。这可能覆盖检查,有时甚至需要重写导出的树。在树之间移动变更集以
避免linux-next中的冲突就是一个例子。但这种行为应该是罕见的。这就是为什么
开发应该在私有分支中进行(必要时可以重写)并且只有在公共分支处于合理的较新
状态时才转移到公共分支中的原因之一。

当主线(或其他一组变更所基于的树)前进时,很容易与该树合并以保持领先地位。
对于一个私有的分支,rebasing 可能是一个很容易跟上另一棵树的方法,但是一旦
一棵树被导出到外界,rebasing就不可取了。一旦发生这种情况,就必须进行完全
合并(merge)。合并有时是很有意义的,但是过于频繁的合并会不必要地扰乱历史。
在这种情况下建议的做法是不要频繁合并,通常只在特定的发布点(如主线-rc发布)
合并。如果您对特定的更改感到紧张,则可以始终在私有分支中执行测试合并。在
这种情况下,git“rerere”工具很有用;它能记住合并冲突是如何解决的,这样您
就不必重复相同的工作。

关于Git这样的工具的一个最大的反复抱怨是:补丁从一个存储库到另一个存储库的
大量移动使得很容易陷入错误建议的变更中,这些变更避开审查雷达进入主线。当内
核开发人员看到这种情况发生时,他们往往会感到不高兴;在Git树上放置未审阅或
主题外的补丁可能会影响您将来让树被拉取的能力。引用Linus的话:

::

   你可以给我发补丁,但当我从你那里拉取一个Git补丁时,我需要知道你清楚
   自己在做什么,我需要能够相信事情而 *无需* 手动检查每个单独的更改。

(http://lwn.net/articles/224135/)。

为了避免这种情况,请确保给定分支中的所有补丁都与相关主题紧密相关;“驱动程序
修复”分支不应更改核心内存管理代码。而且,最重要的是,不要使用Git树来绕过
审查过程。不时的将树的摘要发布到相关的列表中,在合适时候请求linux-next中
包含该树。

如果其他人开始发送补丁以包含到您的树中,不要忘记审阅它们。还要确保您维护正确
的作者信息; git “am”工具在这方面做得最好,但是如果补丁通过第三方转发给您,
您可能需要在补丁中添加“From:”行。

请求拉取时,请务必提供所有相关信息:树的位置、要拉取的分支以及拉取将导致的
更改。在这方面 git request-pull 命令非常有用;它将按照其他开发人员所期望的
格式化请求,并检查以确保您已记得将这些更改推送到公共服务器。

审阅补丁
--------

一些读者显然会反对将本节与“高级主题”放在一起,因为即使是刚开始的内核开发人员
也应该审阅补丁。当然,没有比查看其他人发布的代码更好的方法来学习如何在内核环境
中编程了。此外,审阅者永远供不应求;通过审阅代码,您可以对整个流程做出重大贡献。

审查代码可能是一副令人生畏的图景,特别是对一个新的内核开发人员来说,他们
可能会对公开询问代码感到紧张,而这些代码是由那些有更多经验的人发布的。不过,
即使是最有经验的开发人员编写的代码也可以得到改进。也许对(所有)审阅者最好
的建议是:把审阅评论当成问题而不是批评。询问“在这条路径中如何释放锁?”
总是比说“这里的锁是错误的”更好。

不同的开发人员将从不同的角度审查代码。部分人会主要关注代码风格以及代码行是
否有尾随空格。其他人会主要关注补丁作为一个整体实现的变更是否对内核有好处。
同时也有人会检查是否存在锁问题、堆栈使用过度、可能的安全问题、在其他地方
发现的代码重复、足够的文档、对性能的不利影响、用户空间ABI更改等。所有类型
的检查,只要它们能引导更好的代码进入内核,都是受欢迎和值得的。