這是我第一次發 patch 的全紀錄,並且由 visitorckw,以下簡稱小邱,在我犯錯時糾正我,大力感謝!
這 patch 的目標是在 linux kernel 裡修改錯字,並且是修 Document 裡的錯字,因為比較無傷大雅,推薦大家也這樣做!
向 linux kernel 發 patch 的唯一路徑是透過 email,不要到 linux kernel 的 github 的 PR 處做修改。
務必閱讀 官方文件 Submitting patches: the essential guide to getting your code into the kernel ,另外我參考了他人文章 提交第一份 Patch 到 Linux Kernel, 第一次給Linux Kernel發patch 結合出我的筆記
設定 git config、clone 下 kernel 原始碼、設定 smtp 的資料。
$ git config --global user.email "your email"
$ git config --name user.name "your name"
此設定是為了讓 Git 知道你的身份。在提交 patch 時,會附上你的 Signed-off-by 標籤,用來確認這是你自願提供的 patch
從官方的 Git 儲存庫中 clone Linux 核心源碼:
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
SMTP 設定,你可以透過配置 .gitconfig 來實現,這樣 Git 就能直接發送郵件 (我是使用 Gmail,因此以下配置 Gmail SMTP為例)
$ vi ~/.gitconfig
然後在最後加上以下設定:
[sendemail]
smtpencryption=tls
smtpserver=smtp.gmail.com
smtpuser=your@xxxx.com
smtpserverport=587
smtpPass=你的APP密碼
參數介紹
smtpEncryption = tls
:設定電子郵件傳輸時使用 TLS 加密。smtpServer = smtp.gmail.com
:指定 SMTP 伺服器的地址。這裡使用的是 Gmail 的 SMTP 伺服器。smtpUser = youremail@gmail.com
:指定發送郵件的使用者帳號(即你的 Gmail 帳號)。smtpServerPort = 587
:設定 SMTP 伺服器的 port ,587 是 Gmail 用來接受 TLS 加密連接的 port。smtpPass = 你的APP密碼
:由於 Gmail 不允許直接使用密碼發送郵件,你需要生成一個應用程式專用密碼來替代,這是必須的。進入 Google 帳戶,再點入安全性
("應用程式密碼",倘若跟我一樣找不到,就直接在網頁上方的搜尋欄,搜尋 "應用程式密碼")
設定好,就開始我們的創造 patch 的過程!
首先安裝 codespell
$ pip install codespell
接著在你在根目錄或是你想找錯字的目錄下的 terminal 打
$ codespell
就可以找到很多的錯字,但注意不要改到縮寫,linux kernel 有很多看起來奇怪的縮寫。改完、確定過後就可以儲存。
將修改存到暫存區(stage area)
$ git add .
將此修改從暫存區移到本地倉儲裡 (repository)。以下命令會展開編輯器能夠打 commit message (預設 nano,我是有再去設成 vim 打開)
$ git commit -s -v
參數解釋
-s
是 –signoffSigned-off-by
tag-v
是 –verbose寫 commit message的注意事項:
[PATCH]
,後來生成 patch 時它會自動補。標準的長相:
子系統: 總結修改
較詳細的說明修改
Signed-off-by: 名字 <email>
內文要說明
但我這只是修錯字,不需要寫這麼多。
注意:
我第一次的 commit message,如下圖:
後來被維護者提醒,我修改的子系統有自己的 subject prefix 規定,因此寫 commit 的標題時,也要去查查子系統是否有特別規定。
如我修改的 devicetree/binds的規定: Submitting Devicetree (DT) binding patches
倘若寫完 commit messaage 後,還要再修改這一個 commit,使用
$ commit --amend
做修改
小邱補充:
若是要準備發送 patch series (多個 commit) 並且要更動中間的 patch/commit 可能需要使用 git rebase -i
用 git format-patch
創建 patch
$ git format-patch master
: 會與 master 做比較,之後生成 patch
生成成功,會出現 patch 的檔名
接著手動檢查 patch 的風格
- 一個
from
行指出 patch 作者。後跟空行(僅當發送 patch 的人不是作者時才需要)。- commit message
- 一個空行 !
Signed-off-by:
。---
的標記線。- 任何其他不適合放在變更 log 的註釋。
diff
。
除了手動,還可以用腳本檢查 patch 是否存在風格的錯誤
$ ./scripts/checkpatch.pl patch檔名
舉例:
那麼就先去把錯誤修一修後,將步驟1 2走過一遍,並且要將多個 commit 做 squash。
$ git log --oneline
$ git rebase -i HEAD~3
這命令會打開編輯器,並顯示最近三個的提交
pick abc1234 Commit message 1
pick def5678 Commit message 2
pick ghi9012 Commit message 3
除第一個提交以外的pick改為squash
pick abc1234 Commit message 1
squash def5678 Commit message 2
squash ghi9012 Commit message 3
最後儲存退出編輯器。
書寫 commit message:
倘若在某維護者指出錯誤前,有人回信給你 reviewed-tag 或其他tag 時,在 commit message 裡,記得在你的 Signed-off tag 之前,按收到 tag 的順序加上。
之後生成 patch 指令如下,標題前綴 [PATCH v數字] (此舉例不是 patch series)
$ git format-patch master --subject-prefix='PATCH v2'
或是
$ git format-patch master -v 2
小邱補充:
另外有些子系統 (像是 net) 需要在此處標註說這個 patch 是要 apply 到當前主線的修正還是 apply 到 next 為下個 merge window 做準備
patch 中的---
以下是討論非 chagnelog 本身的資訊
此區可寫如下:
等內容。
以我第五版的 patch 的當範例
兩種確定要寄給誰的方式
./scripts/get_maintainer.pl [patch]
./scripts/get_maintainer.pl -f [修改檔案的相對路徑]
小邱說 commit_signer 是對此檔案或目錄比較多貢獻的人,這可以選擇不要寄,所以主要就是 maintainer, 子系統的 reviewer, support 與 open list 要寄,還有已經給 tag 的開發者!
因為 patch 的要求是純文字,所以不建議使用 Gmail 等 email 服務,它們會自動轉換格式或附加其他內容,純文字的發送需要在 Gmail 額外設定。
因此發 patch 較方便的方式是使用 git send-email 發信。
git send-email 使用:
$ git send-email --to 寄件人 --cc 寄件人 patch
簡單範例
$ git send-email --to laurent.pinchart@ideasonboard.com --cc devicetree@vger.kernel.org,visitorckw@gmail.com 0001-docs-devicetree-Fix-typo-in-lvds.yaml.patch
注意:
git send-email 不論你有沒有寄件人寫到,tag 的維護者,只要有在 patch 裡提及維護者的 email,此 patch 也會寄給他!
所以要測試寄信給自己,要先去 commit message 把 tag 拿掉,真正發信時,再記得把 tag 補回去!
恭喜你發出信囉! 接著等收信。
倘若犯錯太誇張,並且剛好維護者偏沒耐心的話,那可能會收不到回信。發信後一周後再仔細看看哪步驟做錯吧。
我 git config 的名字, email 與 github 不匹配。被小邱提醒,所以我去 github 改完又快速重跑以上流程。
我在第一版發信的時候,我用腳本找到 13 個的維護者與 open list,在發送郵件前很猶豫只是改錯字有需要寄這麼多人嗎? 我最終只寄了兩個維護者,其餘 11 個就都 Cc。我覺得不放心,跑去詢問 jserv 老師。他說: "只是改錯字,不用 Cc 太多人,先觀察這些開發者的活躍程度",所以初次發送 patch 的各位可以借鏡。另外,我後來也被維護者說我只是改錯字,花太多位開發者的時間了。
第二版寄件時 commit message 有加上給我 tag 的維護者。接著在我多次寄測試信給自己時,他也一併收到了…
我第三版是要多修一個錯字,發出第三版時,不知道要把所有的commit 合併成一個 commit。所以我就收到 k 先生的信,問說我怎麼把所有東西 drop掉了 …
小邱解釋:
不同版本代表前一個版本會直接被拋棄
文件裡面明明就有寫說你不可以期待維護者都有看過或者自己會去看前面的版本,所以你的 patch 要直接包含完整的資訊。
v1 Link: https://lore.kernel.org/lkml/20240901133046.962263-1-eleanor15x@gmail.com/
v2 Link: https://lore.kernel.org/lkml/20240903164242.2188895-1-eleanor15x@gmail.com/
v3 Link: https://lore.kernel.org/lkml/20240904125812.2761993-1-eleanor15x@gmail.com/
v4 Link: https://lore.kernel.org/lkml/20240904160118.2773055-1-eleanor15x@gmail.com/
v5 Link: https://lore.kernel.org/lkml/20240905151943.2792056-1-eleanor15x@gmail.com/
最終,Rob收了我的修改 (撒花慶祝!) Link: https://lore.kernel.org/lkml/172566015521.2278562.15089620078479163976.robh@kernel.org/
由於發 patch 過程,犯錯犯太多,感覺我是在 lkml 上發垃圾信的人,希望大家能借鏡我的錯誤,順利發出 patch !
最後的最後,感謝小邱指導!