blob: db74d8ca3f3bb8ae9cbd44561273b5ea7720addb (
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
134
135
136
137
|
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-zh_TW.rst
:Original: :ref:`Documentation/process/7.AdvancedTopics.rst <development_advancedtopics>`
:Translator:
時奎亮 Alex Shi <alex.shi@linux.alibaba.com>
:校譯:
吳想成 Wu XiangCheng <bobwxc@email.cn>
胡皓文 Hu Haowen <src.res.211@gmail.com>
.. _tw_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更改等。所有類型
的檢查,只要它們能引導更好的代碼進入內核,都是受歡迎和值得的。
|