一個涵蓋 Unix 44 年進化史的版本倉庫
摘要
Unix 操作系統的進化歷史,可以從一個版本控制倉庫中窺見,時間跨度從 1972 年的 5000 行內核代碼開始,到 2015 年成為一個含有 26,000,000 行代碼的被廣泛使用的系統。該倉庫包含 659,000 條提交,和 2306 次合併。倉庫部署了被普遍採用的 Git 系統用於儲存其代碼,並且在時下流行的 GitHub 上建立了存檔。它由來自 貝爾實驗室 , 伯克利大學 ,386BSD 團隊所開發的系統軟體的 24 個快照綜合定製而成,這包括兩個老式倉庫和一個開源 FreeBSD 系統的倉庫。總的來說,可以確認其中的 850 位個人貢獻者,更早些時候的一批人主要做基礎研究。這些數據可以用於一些經驗性的研究,在軟體工程,信息系統和軟體考古學領域。
1、介紹
Unix 操作系統作為一個主要的工程上的突破而脫穎而出,得益於其模範的設計、大量的技術貢獻、它的開發模型及廣泛的使用。Unix 編程環境的設計已經被視為一個提供非常簡潔、強大而優雅的設計 [1] 。在技術方面,許多對 Unix 有直接貢獻的,或者因 Unix 而流行的特性就包括 [2] :用高級語言編寫的可移植部署的內核;一個分層式設計的文件系統;兼容的文件,設備,網路和進程間 I/O;管道和過濾架構;虛擬文件系統;和作為普通進程的可由用戶選擇的不同 shell。很早的時候,就有一個龐大的社區為 Unix 貢獻軟體 [3] ,[4,pp. 65-72] 。隨時間流逝,這個社區不斷壯大,並且以現在稱為開源軟體開發的方式在工作著 [5,pp. 440-442] 。Unix 和其睿智的晚輩們也將 C 和 C++ 編程語言、分析程序和詞法分析生成器(yacc,lex)、文檔編製工具(troff,eqn,tbl)、腳本語言(awk,sed,Perl)、TCP/IP 網路、和 配置管理系統 (SCSS,RCS,Subversion,Git)發揚廣大了,同時也形成了現代互聯網基礎設施和網路的最大的部分。
幸運的是,一些重要的具有歷史意義的 Unix 材料已經保存下來了,現在保持對外開放。儘管 Unix 最初是由相對嚴格的協議發行,但在早期的開發中,很多重要的部分是通過 Unix 的版權擁有者之一(Caldera International) (LCTT 譯註:2002年改名為 SCO Group)以一個自由的協議發行。通過將這些部分再結合上由 加州大學伯克利分校 和 FreeBSD 項目組開發或發布的開源軟體,貫穿了從 1972 年六月二十日開始到現在的整個系統的開發。
通過規劃和處理這些可用的快照以及或舊或新的配置管理倉庫,將這些可用數據的大部分重建到一個新合成的 Git 倉庫之中。這個倉庫以數字的形式記錄了過去44年來最重要的數字時代產物的詳細的進化。下列章節描述了該倉庫的結構和內容(第2節)、創建方法(第3節)和該如何使用(第4節)。
2、數據概覽
這 1GB 的 Unix 歷史倉庫可以從 GitHub 上克隆 1 。如今 2 ,這個倉庫包含來自 850 個貢獻者的 659,000 個提交和 2,306 個合併。貢獻者有來自 貝爾實驗室 的 23 個員工, 伯克利大學 的 計算機系統研究組 (CSRG)的 158 個人,和 FreeBSD 項目的 660 個成員。
這個倉庫的生命始於一個 Epoch 的標籤,這裡面只包含了證書信息和現在的 README 文件。其後各種各樣的標籤和分支記錄了很多重要的時刻。
- Research-VX 標籤對應來自 貝爾實驗室 六個研究版本。從 Research-V1 (4768 行 PDP-11 彙編代碼)開始,到以 Research-V7 (大約 324,000 行代碼,1820 個 C 文件)結束。
- Bell-32V 是第七個版本 Unix 在 DEC/VAX 架構上的移植。
- BSD-X 標籤對應 伯克利大學 釋出的 15 個快照。
- 386BSD-X 標籤對應該系統的兩個開源版本,主要是 Lynne 和 William Jolitz 寫的適用於 Intel 386 架構的內核代碼。
- FreeBSD-release/X 標籤和分支標記了來自 FreeBSD 項目的 116 個發行版。
另外,以 -Snapshot-Development 為後綴的分支,表示該提交由來自一個以時間排序的快照文件序列而合成;而以一個 -VCS-Development 為後綴的標籤,標記了有特定發行版出現的歷史分支的時刻。
倉庫的歷史包含從系統開發早期的一些提交,比如下面這些。
commit c9f643f59434f14f774d61ee3856972b8c3905b1
Author: Dennis Ritchie <research!dmr>
Date: Mon Dec 2 18:18:02 1974 -0500
Research V5 development
Work on file usr/sys/dmr/kl.c
兩個發布之間的合併代表著系統發生了進化,比如 BSD 3 的開發來自 BSD2 和 Unix 32/V,它在 Git 倉庫里正是被表示為帶兩個父節點的圖形節點。
更為重要的是,以這種方式構造的倉庫允許 git blame,就是可以給源代碼行加上注釋,如版本、日期和它們第一次出現相關聯的作者,這樣可以知道任何代碼的起源。比如說,檢出 BSD-4 這個標籤,並在內核的 pipe.c 文件上運行一下 git blame,就會顯示出由 Ken Thompson 寫於 1974,1975 和 1979年的代碼行,和 Bill Joy 寫於 1980 年的。這就可以自動(儘管計算上比較費事)檢測出任何時刻出現的代碼。
圖1:各個重大 Unix 發行版的代碼來源
如上圖所示,現代版本的 Unix(FreeBSD 9)依然有相當部分的來自 BSD 4.3,BSD 4.3 Net/2 和 BSD 2.0 的代碼塊。有趣的是,這圖片顯示有部分代碼好像沒有保留下來,當時激進地要創造一個脫離於伯克利(386BSD 和 FreeBSD 1.0)所釋出代碼的開源操作系統。FreeBSD 9 中最古老的代碼是一個 18 行的隊列,在 C 庫裡面的 timezone.c 文件里,該文件也可以在第七版的 Unix 文件里找到,同樣的名字,時間戳是 1979 年一月十日 - 36 年前。
3、數據收集和處理
這個項目的目的是以某種方式鞏固從數據方面說明 Unix 的進化,通過將其併入一個現代的版本倉庫,幫助人們對系統進化的研究。項目工作包括收錄數據,分類並綜合到一個單獨的 Git 倉庫里。
圖2:導入 Unix 快照、倉庫及其合併
項目以三種數據類型為基礎(見圖2)。首先,早期發布版本的快照,獲取自 Unix 遺產社會歸檔 3 、包括了 CSRG 全部的源代碼歸檔的 CD-ROM 鏡像 4 , Oldlinux 網站 5 和 FreeBSD 歸檔 6 。 其次,以前的和現在的倉庫,即 CSRG SCCS [6] 倉庫,FreeBSD 1 CVS 倉庫,和現代 FreeBSD 開發的 Git 鏡像 7 。前兩個都是從和快照相同的來源獲得的。
最後,也是最費力的數據源是 初步研究 。釋出的快照並沒有提供關於它們的源頭和每個文件貢獻者的信息。因此,這些信息片段需要通過 初步研究 驗證。至於作者信息主要通過作者的自傳,研究論文,內部備忘錄和舊文檔掃描件;通過閱讀並且自動處理源代碼和幫助頁面補充;通過與那個年代的人用電子郵件交流;在 StackExchange 網站上貼出疑問;查看文件的位置(在早期的內核版本的源代碼,分為 usr/sys/dmr
和 /usr/sys/ken
兩個位置);從研究論文和幫助手冊披露的作者找到源代碼,從一個又一個的發行版中獲取。(有趣的是,第一和第二的 研究版 幫助頁面都有一個 「owner」 部分,列出了作者(比如,Ken)及對應的系統命令、文件、系統調用或庫函數。在第四版中這個部分就沒了,而在 BSD 發行版中又浮現了 「Author」 部分。)關於作者信息更為詳細地寫在了項目的文件中,這些文件被用於匹配源代碼文件和它們的作者和對應的提交信息。最後,關於源代碼庫之間的合併信息是獲取自 NetBSD 項目所維護的 BSD 家族樹 8 。
作為本項目的一部分而開發的軟體和數據文件,現在可以在線獲取 9 ,並且,如果有合適的網路環境,CPU 和磁碟資源,可以用來從頭構建這樣一個倉庫。關於主要發行版的作者信息,都存儲在本項目的 author-path
目錄下的文件里。它們的內容中帶有正則表達式的文件路徑後面指出了相符的作者。可以指定多個作者。正則表達式是按線性處理的,所以一個文件末尾的匹配一切的表達式可以指定一個發行版的默認作者。為避免重複,一個以 .au
後綴的獨立文件專門用於映射作者的 識別號 和他們的名字及 email。這樣一個文件為每個與該系統進化相關的社區都建立了一個: 貝爾實驗室 , 伯克利大學 ,386BSD 和 FreeBSD。為了真實性的需要,早期 貝爾實驗室 發行版的 emails 都以 UUCP 注釋 方式列出(例如, research!ken
)。FreeBSD 作者的識別映射,需要導入早期的 CVS 倉庫,通過從如今項目的 Git 倉庫里拆解對應的數據構建。總的來說,由 1107 行構成了注釋作者信息的文件(828 個規則),並且另有 640 行用於映射作者的識別號到名字。
現在項目的數據源被編碼成了一個 168 行的 Makefile
。它包括下面的步驟。
Fetching 從遠程站點複製和克隆大約 11GB 的鏡像、歸檔和倉庫。
Tooling 從 2.9 BSD 中為舊的 PDP-11 歸檔獲取一個歸檔器,並調整它以在現代的 Unix 版本下編譯;編譯 4.3 BSD 的 compress 程序來解壓 386BSD 發行版,這個程序不再是現代 Unix 系統的組成部分了。
Organizing 用 tar 和 cpio 解壓縮包;合併第六個研究版的三個目錄;用舊的 PDP-11 歸檔器解壓全部一個 BSD 歸檔;掛載 CD-ROM 鏡像,這樣可以作為文件系統處理;合併第 8 和 62 的 386BSD 磁碟鏡像為兩個獨立的文件。
Cleaning 恢復第一個研究版的內核源代碼文件,這個可以通過 OCR 從列印件上得到近似其原始狀態的的格式;給第七個研究版的源代碼文件打補丁;移除發行後被添加進來的元數據和其他文件,為避免得到錯誤的時間戳信息;修復毀壞的 SCCS 文件;用一個定製的 Perl 腳本移除指定到多個版本的 CVS 符號、刪除與現在衝突的 CVS Attr 文件、用 cvs2svn 將 CVS 倉庫轉換為 Git 倉庫,以處理早期的 FreeBSD CVS 倉庫。
在倉庫 再現 中有一個很有意思的部分就是,如何導入那些快照,並以一種方式聯繫起來,使得 git blame 可以發揮它的魔力。快照導入到倉庫是基於每個文件的時間戳作為一系列的提交實現的。當所有文件導入後,就被用對應發行版的名字給標記了。然後,可以刪除那些文件,並開始導入下一個快照。注意 git blame 命令是通過回溯一個倉庫的歷史來工作的,並使用 啟發法 來檢測文件之間或文件內的代碼移動和複製。因此,刪除掉的快照間會產生中斷,以防止它們之間的代碼被追蹤。
相反,在下一個快照導入之前,之前快照的所有文件都被移動到了一個隱藏的後備目錄里,叫做 .ref
(引用)。它們保存在那,直到下個快照的所有文件都被導入了,這時候它們就會被刪掉。因為 .ref
目錄下的每個文件都精確對應一個原始文件,git blame 可以知道多少源代碼通過 .ref
文件從一個版本移到了下一個,而不用顯示出 .ref
文件。為了更進一步幫助檢測代碼起源,同時增加 再現 的真實性,每個發行版都被 再現 為一個有增量文件的分支(-Development)與之前發行版之間的合併。
上世紀 80 年代時期,只有 伯克利大學 開發的文件的一個子集是用 SCCS 版本控制的。在那個期間,我們的統一倉庫里包含了來自 SCCS 的提交和快照的增量文件的導入數據。對於每個發行版,可用最近的時間戳找到該 SCCS 提交,並被標記為一個與發行版增量導入分支的合併。這些合併可以在圖2 的中間看到。
將各種數據資源綜合到一個倉庫的工作,主要是用兩個腳本來完成的。一個 780 行的 Perl 腳本(import-dir.pl
)可以從一個單獨的數據源(快照目錄、SCCS 倉庫,或者 Git 倉庫)中,以 Git fast export 格式導出(真實的或者綜合的)提交歷史。輸出是一個簡單的文本格式,Git 工具用這個來導入和導出提交。其他方面,這個腳本以一些東西為參數,如文件到貢獻者的映射、貢獻者登錄名和他們的全名間的映射、哪個導入的提交會被合併、哪些文件要處理和忽略、以及「引用」文件的處理。一個 450 行的 Shell 腳本創建 Git 倉庫,並調用帶適當參數的 Perl 腳本,來導入 27 個可用的歷史數據資源。Shell 腳本也會運行 30 個測試,比較特定標籤的倉庫和對應的數據源,核對查看的目錄中出現的和沒出現的,並回溯查看分支樹和合併的數量,git blame 和 git log 的輸出。最後,調用 git 作垃圾收集和倉庫壓縮,從最初的 6GB 降到分發的 1GB 大小。
4、數據使用
該數據可以用於軟體工程、信息系統和 軟體考古學 領域的經驗性研究。鑒於它從不間斷而獨一無二的存在了超過了 40 年,可以供軟體進化和跨代更迭參考。從那時以來,處理速度已經成千倍地增長、存儲容量擴大了百萬倍,該數據同樣可以用於軟體和硬體技術 交叉進化 的研究。軟體開發從研究中心到大學,到開源社區的轉移,可以用來研究組織文化對於軟體開發的影響。該倉庫也可以用於學習著名人物的實際編程,比如 Turing 獎獲得者(Dennis Ritchie 和 Ken Thompson)和 IT 產業的大佬(Bill Joy 和 Eric Schmidt)。另一個值得學習的現象是代碼的長壽,無論是單行的水平,或是作為那個時代隨 Unix 發布的完整的系統(Ingres、 Lisp、 Pascal、 Ratfor、 Snobol、 TMP),和導致代碼存活或消亡的因素。最後,因為該數據讓 Git 感到了壓力,底層的軟體倉庫存儲技術達到了其極限,這會推動版本管理系統領域的工程進度。
圖3:Unix 發行版的代碼風格進化
圖3 根據 36 個主要 Unix 發行版描述了一些有趣的代碼統計的趨勢線(用 R 語言的局部多項式回歸擬合函數生成),驗證了代碼風格和編程語言的使用在很長的時間尺度上的進化。這種進化是軟硬體技術的需求和支持、軟體構築理論,甚至社會力量所驅動的。圖片中的日期計算了出現在一個給定發行版中的所有文件的平均日期。正如可以從中看到,在過去的 40 年中,標示符和文件名字的長度已經穩步從 4 到 6 個字元增長到 7 到 11 個字元。我們也可以看到注釋數量的少量穩步增加,以及 goto 語句的使用量減少,同時 register 這個類型修飾符的消失。
5、未來的工作
可以做很多事情去提高倉庫的正確性和有效性。創建過程以開源代碼共享了,通過 GitHub 的 拉取請求 ,可以很容易地貢獻更多代碼和修復。最有用的社區貢獻將使得導入的快照文件的覆蓋面增長,以便歸屬於某個具體的作者。現在,大約 90,000 個文件(在 160,000 總量之外)通過默認規則指定了作者。類似地,大約有 250 個作者(最初 FreeBSD 那些)僅知道其識別號。兩個都列在了 build 倉庫的 unmatched 目錄里,歡迎貢獻數據。進一步,BSD SCCS 和 FreeBSD CVS 的提交共享相同的作者和時間戳,這些可以結合成一個單獨的 Git 提交。導入 SCCS 文件提交的支持會被添加進來,以便引入倉庫對應的元數據。最後,也是最重要的,開源系統的更多分支會添加進來,比如 NetBSD、 OpenBSD、DragonFlyBSD 和 illumos。理想情況下,其他歷史上重要的 Unix 發行版,如 System III、System V、 NeXTSTEP 和 SunOS 等的當前版權擁有者,也會在一個允許他們的合作夥伴使用倉庫用於研究的協議下釋出他們的系統。
鳴謝
本文作者感謝很多付出努力的人們。 Brian W. Kernighan, Doug McIlroy 和 Arnold D. Robbins 在貝爾實驗室(Bell Labs)的登錄識別號方面提供了幫助。 Clem Cole, Era Erikson, Mary Ann Horton, Kirk McKusick, Jeremy C. Reed, Ingo Schwarze 和 Anatole Shaw 在 BSD 的登錄識別號方面提供了幫助。BSD SCCS 的導入代碼是基於 H. Merijn Brand 和 Jonathan Gray 的工作。
這次研究由歐盟 ( 歐洲社會基金 ) 和 希臘國家基金 通過 國家戰略參考框架 的 Operational Program " Education and Lifelong Learning" - Research Funding Program: Thalis - Athens University of Economics and Business - Software Engineering Research Platform ,共同出資贊助。
引用
1 M. D. McIlroy, E. N. Pinson, and B. A. Tague, "UNIX time-sharing system: Foreword," The Bell System Technical Journal, vol. 57, no. 6, pp. 1899-1904, July-August 1978.
2 D. M. Ritchie and K. Thompson, "The UNIX time-sharing system," Bell System Technical Journal, vol. 57, no. 6, pp. 1905-1929, July-August 1978.
3 D. M. Ritchie, "The evolution of the UNIX time-sharing system," AT&T Bell Laboratories Technical Journal, vol. 63, no. 8, pp. 1577-1593, Oct. 1984.
4 P. H. Salus, A Quarter Century of UNIX. Boston, MA: Addison-Wesley, 1994.
5 E. S. Raymond, The Art of Unix Programming. Addison-Wesley, 2003.
6 M. J. Rochkind, "The source code control system," IEEE Transactions on Software Engineering, vol. SE-1, no. 4, pp. 255-265, 1975.
腳註
1 - https://github.com/dspinellis/unix-history-repo
2 - Updates may add or modify material. To ensure replicability the repository's users are encouraged to fork it or archive it.
3 - http://www.tuhs.org/archive_sites.html
4 - https://www.mckusick.com/csrg/
5 - http://www.oldlinux.org/Linux.old/distributions/386BSD
6 - http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/
7 - https://github.com/freebsd/freebsd
8 - http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/share/misc/bsd-family-tree
9 - https://github.com/dspinellis/unix-history-make
via: http://www.dmst.aueb.gr/dds/pubs/conf/2015-MSR-Unix-History/html/Spi15c.html
作者:Diomidis Spinellis譯者:wi-cuckoo 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive