一個涵蓋 Unix 44 年進化史的版本倉庫
http://www.dmst.aueb.gr/dds/pubs/conf/2015-MSR-Unix-History/html/Spi15c.html
This is an HTML rendering of a working paper draft that led to a publication. The publication should always be cited in preference to this draft using the following reference:
- Diomidis Spinellis. A repository with 44 years of Unix evolution. In MSR '15: Proceedings of the 12th Working Conference on Mining Software Repositories, pages 13-16. IEEE, 2015. Best Data Showcase Award. (doi:10.1109/MSR.2015.6)
This document is also available in PDF format.
The document's metadata is available in BibTeX format.
This material is presented to ensure timely dissemination of scholarly and technical work. Copyright and all rights therein are retained by authors or by other copyright holders. All persons copying this information are expected to adhere to the terms and constraints invoked by each author's copyright. In most cases, these works may not be reposted without the explicit permission of the copyright holder.
Diomidis Spinellis Publications
? 2015 IEEE. Personal use of this material is permitted. However, permission to reprint/republish this material for advertising or promotional purposes or for creating new collective works for resale or redistribution to servers or lists, or to reuse any copyrighted component of this work in other works must be obtained from the IEEE.
摘要
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