0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核的git歷史記錄一些最奇怪的事情

Linux愛好者 ? 來源:未知 ? 作者:李倩 ? 2018-08-10 11:22 ? 次閱讀

我們通常認(rèn)為 git merges 有兩個(gè)父節(jié)點(diǎn)。例如,由我寫的最新Linux 內(nèi)核合并操作是提交2c5d955,這是 4.10-rc6 版本發(fā)行前準(zhǔn)備工作的一部分。它有兩個(gè)父節(jié)點(diǎn):

2c5d955Merge branch'parisc-4.10-3'of...

|

*- 2ad5d52parisc: Don't use BITS_PER_LONG in use ...

*- 53cd1ad Merge branch 'i2c/for-current'of...

Git 還支持章魚式的合并,這意味著可以有超過兩個(gè)父節(jié)點(diǎn)的合并。這對(duì)于我們那些從事小型項(xiàng)目開發(fā)的人來說,這似乎很奇怪:與三四個(gè)父節(jié)點(diǎn)合并會(huì)不會(huì)令人感到困惑?這得看情況而定。有時(shí)候,一個(gè)內(nèi)核的維護(hù)者需要一次同時(shí)合并幾十個(gè)單獨(dú)的歷史記錄。一個(gè)接著一個(gè)的30個(gè)合并提交比起單獨(dú)的一個(gè)30路(30個(gè)父節(jié)點(diǎn))合并更加令人困惑,特別是當(dāng)30路合并沒有沖突的時(shí)候。

章魚式合并可能比你想象地更常見。在內(nèi)核的提交歷史記錄中有649,306個(gè)提交。其中 46,930 (7.2%) 個(gè)提交是合并提交。在合并提交中,有 1,549 (3.3%) 是章魚式合并。(截止到我當(dāng)前的 git HEAD 指向的提交 566cf87 。)

$git log --oneline | wc -l

649306

$git log --oneline --merges | wc -l

46930

$git log --oneline --min-parents=3 | wc -l

1549

作為比較,Rails 的所有提交中的 20% 是合并提交 (12,401/63,111),但沒有一個(gè)章魚式合并。Rails 大概更能代表一般的工程; 我認(rèn)為大多數(shù)的 git 用戶甚至都不知道章魚式合并。

現(xiàn)在,顯而易見的問題是: 這些章魚式合并的規(guī)模有多大? 在這里每行開頭的 “>” 是續(xù)行符;這個(gè)命令寫了總共5行。這篇文章中的所有命令都是我在做實(shí)驗(yàn)的時(shí)候輸入到終端里面的,所以它們未必容易看懂。我對(duì)于結(jié)果更感興趣,貼出代碼只是為了滿足那些好奇的人。

$(git log --min-parents=2 --pretty='format:%h %P' |

>ruby -ne'/^(w+) (.*)$/ =~ $_; puts "#{$2.split.count} #{$1}"' |

>sort -n |

>tail -1)

662cde51f

66 個(gè)父節(jié)點(diǎn)!這么多的父節(jié)點(diǎn),這個(gè)提交到底發(fā)生了什么?

這讓許多歷史記錄可視化工具都無法正常運(yùn)行,引出了 Linus Torvalds 的一個(gè)回應(yīng):

我剛剛從 Takashi 那收到了一些消息,因此我看到了你的合并提交 2cde51fbd0f3 。這個(gè)提交有 66 個(gè)父節(jié)點(diǎn)。

[…]

它被拉?。╬ulled)了,并且狀況良好,但顯然它在 “章魚式合并很好” 和 “上帝” 之間做到了平衡,這不是一個(gè)章魚式合并,這是一個(gè)克蘇魯(一個(gè)章魚頭人神的巨人)式的合并。

正如我所看到的,這個(gè)有66個(gè)父節(jié)點(diǎn)的不同尋常的提交在某種程度上只是對(duì)于ASoc代碼修改的正常合并。ASoc 代表了芯片上的ALSA系統(tǒng)。ALSA系統(tǒng)是音頻子系統(tǒng);“單片系統(tǒng)是集成在單片硅芯片上計(jì)算機(jī)的術(shù)語。綜上所述,ASoc 是對(duì)嵌入式設(shè)備的聲音支持系統(tǒng)。

那么這樣的合并多久會(huì)發(fā)生一次呢?永遠(yuǎn)都不會(huì)發(fā)生。規(guī)模排第二的合并是 fa623d1 ,它僅僅有 30 個(gè)父節(jié)點(diǎn)。然而,因?yàn)樽銐虻谋尘爸R(shí),從 30 到 66 之間的巨大差距并不會(huì)令人感到驚訝。

一次 git 提交的父節(jié)點(diǎn)的數(shù)量大概是一種單側(cè)分布(通常非正式的說法是冪律分布,因?yàn)檫@里對(duì)這個(gè)不感興趣,所以不必嚴(yán)格正確)。軟件系統(tǒng)的許多屬性都屬于單側(cè)分布。等一下;我將會(huì)生成一個(gè)圖表來確定…(大量嚴(yán)格的圖表確定了)。是的,它確實(shí)是單側(cè)分布:

簡(jiǎn)單地說來, “單側(cè)分布”意味著小事件比大事件多得多,而且大事件的最大規(guī)模是沒有界限的。內(nèi)核的提交歷史中包含了 45,381 個(gè)兩個(gè)父節(jié)點(diǎn)的合并,但僅僅有一個(gè) 66個(gè)父節(jié)點(diǎn)的合并。假如考慮足夠多的開發(fā)歷史記錄的話,我們可能會(huì)看到多于66個(gè)父節(jié)點(diǎn)的合并。

單個(gè)函數(shù)或是單個(gè)模塊的代碼行數(shù)也是單側(cè)分布(大多數(shù)函數(shù)和模塊都很小,但是其中一些很大;想想 web app 中的 “User” 類)。同樣,對(duì)于模塊的變化率(大多數(shù)模塊都不會(huì)經(jīng)常變動(dòng),只有其中一些會(huì)不斷改動(dòng);再想想 “User” 類)。這些分布在軟件開發(fā)中無處不在,而且經(jīng)常在下面的雙對(duì)數(shù)坐標(biāo)圖中呈直線分布。

對(duì)于父節(jié)點(diǎn)的數(shù)量最大的提交,我們就討論到這。那么在差異方面的合并又怎樣呢?在差異方面,我的意思是被合并的兩個(gè)分支之間的差異。我們可以通過簡(jiǎn)單地比較合并節(jié)點(diǎn)的父節(jié)點(diǎn),然后統(tǒng)計(jì)它們差異的行數(shù)來衡量這一點(diǎn)。

例如,如果一個(gè)分支一年前從 master 分支分離出去,改變了一行代碼,之后被合并回 master 分支,在這段時(shí)間內(nèi)對(duì)于 master 分支的所有修改都會(huì)被統(tǒng)計(jì)到,同樣分離出去的分支上的改變也會(huì)被統(tǒng)計(jì)到。我們可以引出更直觀的差異概念,但因?yàn)?git 不會(huì)保留分支的元數(shù)據(jù),所以它們很難或者說是幾乎不可能計(jì)算出來。

在任何情況下,作為計(jì)算差異的起點(diǎn),下面是最近內(nèi)核合并的差異:

$git diff$(git log --merges -1 --pretty='format:%P') | wc -l

173

在英語中,這個(gè)命令的含義是這樣的:“比較最近合并的兩個(gè)父節(jié)點(diǎn),然后統(tǒng)計(jì)差異的行數(shù)?!睘榱苏页霾町愖疃嗟暮喜?,我們可以遍歷每個(gè)合并提交,用類似的方法統(tǒng)計(jì)差異的行數(shù)。然后,作為一個(gè)測(cè)試,我們將搜索所有合并中恰好有 2,000 行差異的分支。

$(git log --merges --pretty="%h" |

whilereadx;do

echo"$(git diff $(git log --pretty=%P $x -1) | wc -l)"$x

done > merges.txt)

$sort -nmerges.txt | grep'b2000b'

20003d6ce33

20007fedd7e

2000f33f6f0

(這個(gè)命令需要花費(fèi)很長(zhǎng)的時(shí)間運(yùn)行: 我想大約需要12小時(shí),盡管我已經(jīng)減少了許多。)

我認(rèn)為合并的差異大小遵循單側(cè)分布,就像父節(jié)點(diǎn)數(shù)量的統(tǒng)計(jì)一樣。所以它應(yīng)該在雙對(duì)數(shù)坐標(biāo)圖表中顯示為一條直線。讓我檢查一下….對(duì)了:

我把差異的大小定在1000行左右(注:前面用2000行,得到的數(shù)據(jù)太少),否則沒有足夠的樣本來生成有效的曲線。

右下角難看的原因部分是因?yàn)榱炕瘑栴},另一部分是由于缺乏大量的提交導(dǎo)致樣本數(shù)量較小,與之前的圖表情況一樣。

現(xiàn)在,顯而易見的問題是: 提交歷史中差異最大的合并是哪個(gè)?

$sort -nmerges.txt | tail -1

22445760f44dd18

22,445,760 行差異!這看起來根本不可能這么大-因?yàn)椴町惖男袛?shù)比整個(gè)內(nèi)核源代碼的行數(shù)都大。

Greg Kroah-Hartman 在2016年9月19做了這一提交,當(dāng)時(shí)正處在 4.8-rc6 版本的開發(fā)期間。Greg 是 Linus Torvalds 的 “副官” 之一 – 他(Linus)最親近,最值得信賴的開發(fā)者。簡(jiǎn)單地說,副官們構(gòu)成了內(nèi)核 pull request 樹中的第一層。Greg 負(fù)責(zé)維護(hù)內(nèi)核的穩(wěn)定分支,驅(qū)動(dòng)程序內(nèi)核,USB 子系統(tǒng)和其他幾個(gè)子系統(tǒng)。

在更加仔細(xì)的研究這個(gè)合并之前,我們需要一點(diǎn)背景知識(shí)。通常我們把合并作為菱形分支模式(先分支,然后合并,見下圖)的一部分:

在2014年,Greg 開始在一個(gè)新的倉(cāng)庫開發(fā) Greybus (移動(dòng)設(shè)備總線),這就好像是他創(chuàng)建了一個(gè)全新的項(xiàng)目一樣。最后,Greybus 的開發(fā)工作完成時(shí),它就被合并到了內(nèi)核中。但因?yàn)樗菑囊粋€(gè)嶄新的倉(cāng)庫開始的,所以它和內(nèi)核的中的其他源代碼沒有共同的歷史記錄。所以除了2005年我們公認(rèn)的初始提交之外,這個(gè)合并為內(nèi)核又添加了一個(gè) “初始提交”。這個(gè)倉(cāng)庫現(xiàn)在有兩條獨(dú)立的初始提交,而不是通常的菱形分支模式:

通過查看合并提交的兩個(gè)父節(jié)點(diǎn)中分別存在多少文件,我們可以看到一些蛛絲馬跡:

$git log -1f44dd18 | grep'Merge:'

Merge: 93954527398a66

$git ls-tree -r9395452 | wc -l

55499

$git ls-tree -r7398a66 | wc -l

148

一條分支存在大量的文件,因?yàn)樗苏麄€(gè)內(nèi)核的源文件。而另一條僅僅包含了很少的文件,因?yàn)樗闹皇?Greybus 的歷史記錄。

像章魚式合并一樣,這會(huì)讓一些 git 用戶感到奇怪。但是內(nèi)核開發(fā)人員是專家級(jí)的 git 用戶,并傾向于放棄使用這個(gè)功能,但絕對(duì)不是盲目的放棄

最后一個(gè)問題:這種情況到底發(fā)生了多少次??jī)?nèi)核中有多少獨(dú)立的 “初始化” 提交?事實(shí)上是四次:

如果我們要畫出這些提交,為了清楚起見,我們忽略所有其他的歷史記錄,如下圖:

這四個(gè)提交中的每一個(gè)都是離當(dāng)前內(nèi)核版本庫 HEAD 節(jié)點(diǎn)很遙遠(yuǎn)的祖先節(jié)點(diǎn),并且都沒有父節(jié)點(diǎn)。從 git 的角度來看,內(nèi)核歷史“開始”了不同的四次,所有的這些提交最終都被合并在一起。

這四個(gè)提交中的第一個(gè)(在我們輸出的底部)是2005年的初始化提交,也就是我們通常認(rèn)為的初始化提交。第二個(gè)是文件系統(tǒng) btrfs 的開發(fā),它是獨(dú)立倉(cāng)庫完成的。第三個(gè)是 Greybus,同樣也是獨(dú)立倉(cāng)庫完成的,我們之前已經(jīng)說過。

第四個(gè)初始化提交,a101ad9,很奇怪,正如下面看到的:

$git show --oneline --stat a101ad9

a101ad9 Share upstreaming patches

README.md | 2 ++

1file changed,2insertions(+)

它剛創(chuàng)建了一個(gè) README.md 文件。但隨后,它就立即被合并到正常的內(nèi)核歷史的提交 e5451c8 中了!

$git show e5451c8

commit e5451c8f8330e03ad3cfa16048b4daf961af434f

Merge: a101ad93cf42ef

Author: Laxman Dewangan

Date: Tue Feb2319:37:082016 +0530

為什么有人會(huì)創(chuàng)建一個(gè)只包含兩行文本的 README 文件的初始化提交,然后立即合并到主線的歷史記錄中呢?我想不出任何理由,所以我懷疑這是一個(gè)意外!但它沒有造成任何危害;它只是很奇怪。(更新:這是個(gè)意外,Linus用他一貫的方式回應(yīng)了。)

順便提一句,這也是歷史記錄中差異數(shù)量排第二的提交,僅僅因?yàn)樗且粋€(gè)不相關(guān)提交的合并,就像我們仔細(xì)研究過的 Greybus 的合并一樣。

現(xiàn)在你知道了:Linux 內(nèi)核的 git 歷史記錄一些最奇怪的事情。一共有 1,549 個(gè)章魚式合并,其中有一個(gè)是擁有 66 個(gè)父節(jié)點(diǎn)的提交。差異最多的合并有 22,445,760 行差異,盡管它有點(diǎn)技術(shù)性因?yàn)樗蛡}(cāng)庫的其他部分沒有公共的歷史記錄。內(nèi)核擁有四個(gè)獨(dú)立的初始化提交,其中一個(gè)是失誤導(dǎo)致的。盡管上面的這些都不會(huì)出現(xiàn)在絕大多數(shù)的 git 倉(cāng)庫中,但是所有的這些功能都是在 git 的設(shè)計(jì)范圍之內(nèi)的。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 芯片
    +關(guān)注

    關(guān)注

    450

    文章

    49636

    瀏覽量

    417169
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207912
  • 嵌入式設(shè)備
    +關(guān)注

    關(guān)注

    0

    文章

    109

    瀏覽量

    16903

原文標(biāo)題:Linux 內(nèi)核 Git 歷史記錄中,最大最奇怪的提交信息是這樣的

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    鴻蒙原生應(yīng)用元服務(wù)開發(fā)-Web歷史記錄導(dǎo)航

    /向后瀏覽上個(gè)/下個(gè)歷史記錄。 在下面的示例中,點(diǎn)擊應(yīng)用的按鈕來觸發(fā)前端頁面的后退操作。 // xxx.ets import web_webview from \'@ohos.web.webview
    發(fā)表于 05-20 15:14

    怎樣清除protel99se的歷史文件記錄

    只要?jiǎng)?chuàng)建新文件,就會(huì)在文件菜單留下記錄,即使文件已刪除,文件菜單里仍然會(huì)有歷史記錄,怎樣清除這個(gè)歷史記錄呢?請(qǐng)老師解答,萬分感謝!
    發(fā)表于 04-23 17:30

    LabVIEW的輸入框可以做成帶歷史記錄的嗎?

    請(qǐng)問,LabVIEW的數(shù)值控件可以做成像百度樣的,可以有歷史記錄顯示并可以選擇那樣的嗎?
    發(fā)表于 10-28 10:09

    Cosmic STM8編譯器修訂歷史記錄?

    Cosmic STM8編譯器修訂歷史記錄?以上來自于谷歌翻譯以下為原文 Cosmic STM8 compiler revision history?
    發(fā)表于 05-13 16:07

    創(chuàng)建藍(lán)牙盒子在訂單歷史記錄中看不到

    你好,我想訂購(gòu)個(gè)樣品來嘗試建立個(gè)自己的藍(lán)牙盒子。在我發(fā)送請(qǐng)求后,它會(huì)顯示您的訂單已成功創(chuàng)建,但我無法在訂單歷史記錄中看到它。關(guān)閉選項(xiàng)卡后,它會(huì)再次顯示圖表中的項(xiàng)目。以上來自于谷歌翻譯以下為原文
    發(fā)表于 07-22 06:55

    LINUX怎么清除歷史記錄命令

    目的很簡(jiǎn)單,就是清除linux下的歷史命令linux 下輸入history 命令顯示歷史敲過的命令
    發(fā)表于 07-25 07:45

    Agilent 81200數(shù)據(jù)發(fā)電機(jī)/分析儀平臺(tái)更改和修正歷史記錄

    81200 SW更改和增強(qiáng)歷史記錄(Apr02)
    發(fā)表于 08-28 06:33

    帶中移動(dòng)模組M6315的機(jī)器上傳到云平臺(tái)的歷史記錄的時(shí)間和機(jī)器本身記錄的時(shí)間不致,

    帶中移動(dòng)模組M6315的機(jī)器上傳到云平臺(tái)的歷史記錄的時(shí)間和機(jī)器本身記錄的時(shí)間不致,有些相差個(gè)多月,是什么原因?要從哪些方向去分析?
    發(fā)表于 10-22 16:56

    追蹤項(xiàng)目歷史

    歷史記錄的方式取決于您是在Altium Designer中查看歷史記錄還是通過網(wǎng)頁瀏覽器在DigiPCBA工作區(qū)中查看歷史記錄。鑒于在每個(gè)區(qū)域可以訪問不同的功能,接下來就讓我們簡(jiǎn)單了解
    發(fā)表于 03-30 10:07

    富士康收入創(chuàng)造歷史記錄 并未受蘋果新手機(jī)高價(jià)格影響

    富士康集團(tuán)位高管表示,無論是三季度還是今年前三季度,富士康的收入都創(chuàng)造了歷史記錄。
    的頭像 發(fā)表于 10-14 09:57 ?4586次閱讀

    2018年DRAM銷售額創(chuàng)歷史記錄新高 同比增長(zhǎng)39%

    據(jù)報(bào)道,市場(chǎng)研究公司DRAMeXchange在3月4日?qǐng)?bào)道稱,全球DRAM市場(chǎng)去年的銷售額達(dá)到99,655百萬美元,同比增長(zhǎng)39%,創(chuàng)歷史記錄新高。
    發(fā)表于 03-10 09:58 ?1452次閱讀

    微軟Edge瀏覽器更新:已支持同步歷史記錄

    據(jù)Windows Central報(bào)道,微軟Edge瀏覽器剛剛獲得了項(xiàng)新功能,用戶可以跨設(shè)備打開瀏覽歷史記錄
    的頭像 發(fā)表于 11-18 09:24 ?1936次閱讀

    QQ、Tim等存在讀取瀏覽器歷史記錄現(xiàn)象

    日前,有網(wǎng)友反饋QQ、Tim等軟件會(huì)讀取本地瀏覽器的歷史記錄資料,引發(fā)大家對(duì)隱私、安全等問題的擔(dān)憂。
    的頭像 發(fā)表于 01-19 11:13 ?2216次閱讀
    QQ、Tim等存在讀取瀏覽器<b class='flag-5'>歷史記錄</b>現(xiàn)象

    uModule解決方案組合主板修訂歷史記錄(DC1758A)

    uModule解決方案組合主板修訂歷史記錄(DC1758A)
    發(fā)表于 04-19 11:05 ?4次下載
    uModule解決方案組合主板修訂<b class='flag-5'>歷史記錄</b>(DC1758A)

    鴻蒙開發(fā)實(shí)例:【demo-搜索歷史記錄

    HarmonyOs-demo-搜索歷史記錄
    的頭像 發(fā)表于 03-26 22:40 ?469次閱讀
    鴻蒙開發(fā)實(shí)例:【demo-搜索<b class='flag-5'>歷史記錄</b>】