tl; dr:
近年のLinuxはそれほどファ●ックではない。最大の"F値"は25で、単一のファイルに集中していた。
もくてき
ファッ●クと言えばLinuxの風物詩と言える時期もあったが、最近は落ちついてきた印象はある。それでも fuck
コマンド やメーリングリスト等では言及は有る。
では、それを印象付けるような出来事としては何があったのだろうか。今回、コミットログおよびそのソースコードdiffにおけるF-wordの登場回数を F 値 (F value) と定義し、最もF値の高いコミット(the most F-valued commit)を探してみることにした。
(ソースコードdiffにおける登場回数であるため、F-wordを削除したコミットも高いF値が与えられることに注意する)
全てのコミットを git show
する
最近シェルスクリプト代わりにCMakeを使っているので今回もCMakeで書いた。
基本的には git rev-list HEAD
でコミットのリストを出力し、それをcommit hash先頭の3文字 000
- fff
に分類して(= 16**3 = 4096分割)ビルドターゲットとし、 ninja
に並列実行させている。
Linuxのリポジトリ( https://github.com/torvalds/linux )では、
$ git rev-list HEAD | wc -l
897506
HEADに繋がるコミットは約90万コミットあるようだ。ただし、 このリポジトリにはGit以前のコミットが含まれない事に注意する 。
コミットのF値を求める
コミットのF値は普通にgrepで求められる。
$ git show -p -w HEAD | grep -ci fuck
0
HEAD
のF値は当然のごとくゼロ、F-wordを含むソースコードの周辺行を編集したコミット https://github.com/torvalds/linux/commit/4b550488f894c899aa54dc935c8fee47bca2b7df では1となる。
$ git show -p -w 4b550488f894c899aa54dc935c8fee47bca2b7df | grep -ci fuck
1
流石にgrepをそのまま使うと時間が掛かるので、ripgrep( https://github.com/BurntSushi/ripgrep )のような高速grepツールで纏めて求めるのが良い。
$ rg -ci fuck
fa/76/fa7662aad7dc033a61ff2f705c33cbb301d0552d.diff:1
f4/db/f4dbc4c20f05ccf6986b0de429f7552b21a1b362.diff:1
51/53/51533b615e605d86154ec1b4e585c8ca1b0b15b7.diff:1
29/57/2957c9e61ee9c37e7ebf2c8acab03e073fe942fd.diff:2
36/5b/365bff806e9faba000fb4956c7486fbf3a746d96.diff:1
5b/5f/5b5f9560354dc5a3a27ce57a86aec6b98531ee21.diff:1
96/39/963945bf93e46b9bf71a07bf9c78183e0f57733a.diff:1
b2/e1/b2e1b30290539b344cbaff0d9da38012e03aa347.diff:2
F値の高いコミット
LinuxのgitリポジトリでもっともF値が高いコミットは 最初のコミット 、つまり、gitに移行したタイミングのLinuxソースコード自体で、その値は 堂々の56 となった。
$ git show -p -w 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 | grep -ci fuck
56
流石にこのコミットは殿堂入りとしても良いだろう。
そうでないコミットのtop3は、
- 25 https://github.com/torvalds/linux/commit/686957e71d34beffe2b29cf5fb2e05025972020b
- 24 https://github.com/torvalds/linux/commit/9e0c7afd0ec6e6d788df14270b2b1b8f21a384a8
- 12 https://github.com/torvalds/linux/commit/a44d924c81d43ddffc985aca14aeeaf1abd6dd22
何と全部同じファイル arch/mips/pci/ops-bridge.c
に対する処理 となっている。このファイルはLinuxの歴史における F-キング と言っても差し支えないだろう。
このファイルはF値24のコミットでファイル pci-ip27.c
から分割されて作られた。元のファイルを見ると、このファイルはLinuxがgitで管理され始めた当初からかなりFだったことがわかる。
- https://github.com/torvalds/linux/blob/1da177e4c3f41524e886b7f1b8a0c1fc7321cac2/arch/mips/pci/pci-ip27.c#L90 - Gitの最初のコミット時点で既に多くのF-wordを含む
逆に言えば、このように突出したF値を持つファイルはgit移行後には作られていないということになるわけで、少くともソースコードの面ではあまりLinuxはFでは無いと言えるだろう。
ちなみに現時点のLinuxカーネルソースコードで最大のF値を持つコードは drivers/net/ethernet/sun/sunhme.c
で、その値は たったの2 となっている。先に挙げた ops-bridge.c
の現在のF値はゼロであり、F値 12 のコミットで一掃されている。
cleaned up language in arch/mips/pci/ops-bridge.c
このコミット自体は2019年に行われているが、2018年にはわかりづらい表現のパッチ提案 https://lkml.org/lkml/2018/12/1/105 が存在し、F値25のコミットでも多少の文法改善を試みている https://github.com/torvalds/linux/commit/686957e71d34beffe2b29cf5fb2e05025972020b 。
かんそう
少くともGit移行後に限れば、ソフトウェアとしてのLinuxカーネルはあまり高いF値を持っていないことがわかった。Git移行以前については調査の余地はあると見られるが、フ●ァックの印象は人間活動によるものと言ってよさそうだ。
F値よりも良い指標が必要かもしれない。例えば、F値をコミット毎に定義するよりも、F-wordの生存期間といった別の指標が考えられる。
今回のF値評価では、 ops-bridge.c
にしか注目できなかった。特にdiff行の抽出では行の移動に弱く、コミットにおけるF値を過大評価してしまう。しかし、今のところファイルを超えた移動を良く表現できるフォーマットが存在しない。git blame
ではdiff以外に行の移動についても考察しており -M
や -C
で抽出を行わせることができる。