關聯回顧
開源,是先進生產模式對傳統生產模式的超越
開源發展簡史:從自由到開源,從開源到開放
開源的價值觀
全圖說開源軟件的發展歷史
2005年,Linus Torvalds開發Git這個開源的分布式代碼版本控制系統軟件的時候,他可能沒有意識到自己的開發會一統江湖。2022年的一份年度開發者調查問卷中,Git在開發者的使用率壓倒性地高達93.9%。那么Git是如何做到成功的呢?它到底有哪些特點是其他版本管理軟件沒有考慮到的呢?我們今天來談一下這個話題。
集中還是分布,這是基本理念的差異Git之所以是被極客Linus Torvalds 開發出來的,而不是被一個大公司開發出來的,因為他們的開發模式有著根本理念的差別:集中式開發和分布式開發。
集中式開發:我一定要用你。你必須保證你的代碼是有用的。
分布式開發:我不Care你。你要說服我你的代碼是有用的。
集中式開發,不能容忍人力資源的浪費,人員之間的關系也相對固化的,層級關系也是相對嚴格的。代碼責任路徑也是金字塔式的。集中式開發,一般發生在已經有固定的雇員的項目團隊。這些雇員是簽了雇傭合同的,是要領薪水的,是要占用項目的人力成本的,所以,他們必須要為項目創造價值,必須要有績效考核,每位開發者都不是混飯吃的,每位團隊成員都有對應的代碼責任田,每個人或者某幾個人為某幾個代碼文件或者文件目錄負責。
分布式開發,發生在開源項目里,基本是根據興趣和利益牽引而誘發的非穩態合作。分布式合作之前,團隊各方人員大多并未相識相知。所以這種開發構建的前提就是項目創始人不認識你,你要讓他(她)認識你,你先主動來找他(她),來證明你值得他(她)認識和合作,如果你沒有說服他(她),僅僅是他(她)的粉絲,那他(她)自然也沒有什么問題,或者也能滿足其虛榮感:“你愿意拿我的代碼開啟自嗨模式,我不Care。”這種非穩態的合作關系,必然允許人力資源的浪費(而且,這也是開源項目的常態),也不太講究人員關系的固化,不存在所謂的雇傭關系。修改的代碼是否被別人接受由別人來決定。項目核心或者發起人自己來決定要去合并誰的代碼,而這種信任也是動態變化的。
寫到這兒,我覺得這個和社交網絡(同樣是另外一種分布式網絡)的微博分享有些類似。Push在這里不那么重要,你可以分享發布微博(Push),但是沒有人關注你,沒有人給你小愛心,也就是自娛自樂而已。Pull貌似更重要,Pull的主動權在對方手里,對方可以給你點贊,給你評論,甚至Follow你了,以后每次你發布什么都給你點贊,這樣你的分享才顯得更有意義。而轉發,可以類比為fork,如果在你的轉發上還有所修改,甚至有新的心得體會評論,這就相當于在你的分支上修改。你覺得誰的評論寫的好,再轉發助推一次,又相當于Pull,合入到了你的主分支。
由于這種基本理念和開發模式的本質差別,導致代碼管理的方式,會產生極大的不同。
針對代碼倉的數據備份策略集中式管理
集中式管理,往往對代碼是當作寶貴資源或者價值產出看待的。因為不可能允許團隊的開發者都擁有代碼。防賊防盜防程序員。項目時時刻刻防著這些開發者,也許哪一天解除了雇傭關系,他們離職了,跳槽了,是絕對不能讓他們把代碼帶離公司的。這是公司的寶貴代碼財富,必須要進行各種安全管理。代碼倉,每位開發者,一般都是針對自己的代碼責任田范圍才有訪問和修改的權限,而對其他的代碼不允許看,不能改。這種權限設置一定是嚴格的文件級的安全權限管理體系。所以,代碼倉,一定是集中化管理的。
集中管理,就一定會使用服務器-客戶端的維護模式。服務器存放完整的代碼倉。而客戶端,僅存放開發者需要關注的責任田代碼。服務器一定要做到足夠的安全防護,還要考慮到容災備份,因為一旦服務器出現宕機或者擁塞,對整個團隊的工作都會是全局的影響。而且,如果服務器的存儲考慮不周,真的出現了硬盤故障,導致代碼倉代碼丟失,那簡直就是晴天霹靂。
分布式管理
分布式管理則不同,因為是開源項目,所以整個項目,凡是已經在官方發布的項目代碼倉的內容,所有人可以隨便看,隨便改,完全可以下載到本地,也就是每個人都有一個項目官方發布的完整備份。
可能有些人會抱怨Git的項目官方發布的代碼倉完整下載備份到本地會占用很大的存儲空間。這個其實不是開源項目的發起者所關心的。如果想玩開源項目,這點兒存儲空間的成本是非常低廉的。另外,這里還有一個非常重要的和集中式管理的數據備份策略問題。分布式存儲,會避免集中存儲引發的服務器宕機和硬盤損壞導致的重大數據丟失。分布式意味著每個開發者的電腦上都是一個數據“備份”節點。每個開發者本機不僅檢查文件的最新快照,還完整地映射了存儲庫,包括它的完整歷史。哪一天,項目發起者的主倉服務器發生了宕機或者硬盤損壞導致部分文件丟失,只需要向項目團隊其他成員的電腦中讀取,就可以恢復對應的代碼倉。
數據存儲策略的不同集中式管理的數據存儲
從概念上講,大多數代碼版本管理系統將信息存儲為基于文件的更改列表,比如:CVS、Subversion、Perforce、Bazaar 、SVN等。這些工具將它們存儲的信息視為一組文件以及隨時間對每個文件所做的更改進行版本標注(這通常被描述為基于增量的版本控制)。這種好處是對于每個版本的存儲都是增量存儲。當然缺點也很明顯,就是很多存儲的版本都不是完整版本。不過反正數據都存在服務器,開發者也不會看到完整的版本,所以這個缺點對于集中式管理而言,也還說得過去。
分布式管理的數據存儲
既然是分布式存儲,每個開發者都有項目的完整備份,就不能像集中式管理那樣來玩數據存儲了。于是Git引入了快照(Snapshots)的概念。
Git 認為項目的數據更像是微型文件系統的一系列快照。每次提交或保存項目狀態時,Git 基本上都會拍下當時所有文件的樣子,并存儲對該快照的引用。為了提高效率,如果文件沒有更改,Git 不會再次存儲該文件,只是指向它已經存儲的先前相同文件的鏈接。Git 將其數據視為快照流(stream of snapshots)。這是 Git 和幾乎所有其他版本管理系統之間的一個重要區別。這種做法,讓每個開發者都可以在本地有一個完整的項目備份。以至于絕大多數開發者的操作都是本地的,因此這也是Git速度為什么如此超凡脫俗,碾壓對手的根本原因。
代碼合并策略差異
集中式管理的代碼合并策略
集中式代碼管理的模式很簡單,代碼保存在共享代碼倉里。你可以checkout代碼進行修改,這個時候,代碼倉對應的文件會打好標記。對應文件后面又有開發者想要進行修改,他(她)就要進入一種排隊機制。要等待你合并完之后,他(她)再更新,再修改合并。也就是一種串行機制。所以如果一個代碼責任田由多個人一同維護的話,他們之間就要做好某些事前約定,避免出現上述的尷尬情況,甚至出現不必要的代碼覆蓋。
分布式管理的代碼合并策略
分布式管理則不同,由于開源項目的每個開發者都有一個項目官方發布的完整備份。這種完整備份,會給開發者帶來幾個好處:
-
開發者會有機會了解到整個項目的全貌,或者至少可以了解到他(她)希望了解到一些關聯文件的源代碼到底是怎么寫的。
-
開發者會在本地離線工作,不必擔心沒有連上互聯網無法編輯或者commit提交代碼。這些工作都可以在本地完成。如果你在飛機上、或者網絡不是很好的環境、或者你人在你根本不信任的公共WiFi環境下,你想干活,你根本不用連上網,你就可以離線提交代碼,然后等你連上網,Git會幫你做上傳(Git做的這些都是后臺默默地干的,你不必關心)。
-
開發者可以在本地建立多個分支,隨便怎么折騰,不用去擔心對線上的主分支有什么影響。直到開發者有信心了,他(她)自己再決定是否同意這些分支被其他人看到或者被合并到的可能(push到自己的公共代碼倉)。
說到這兒,我不得不補充一下,為什么Linus Torvalds這么執著地要求本地代碼倉地完備性,以及要離線工作。在2007年Google Talk上,Torvalds揭秘了他的動因。因為這個哥們特別看中他編碼環境的安全性。他正在寫的代碼,是不希望給任何人看到的,為了保證安全性,這個服務器有3層防火墻,幾乎完全和互聯網隔絕。所以如果沒有本地完整備份,以及大部分操作都在本地完成的話,他在那種幾乎離線的狀況下貌似也干不了什么。
當然,如果你的修改想要被官方接受,合入到主分支下一個版本發布,你可能要說服這個項目的集成管理員(Integration Manager),給他(她)寫一封長長的翔實郵件(至少是有說服力的),告訴他(她)你改的代碼有多牛逼,要求他(她)Pull你的修改。當然,你也要做好心理準備:集成管理員可能不鳥你:)因為他(她)有這個權力。
如果你足夠厲害(或者幸運),反正被集成管理員看中了,他(她)會合入(merge)你的代碼到官方發布的代碼倉,并準備下一次發布。我還是喜歡官方發布的代碼倉Git的英文名字:Blessed Repository,給這個代碼倉籠罩了一種神圣的光環:)在很多小項目中,集成管理員往往就是開源項目的發起人。每個項目發起人可能在合代碼的時候,心中也在默默地祈福:希望這個項目一定要成功哈:)
當然,如果你的項目復雜度上升到一定程度,一個集成管理員已經搞不定了,集成管理員就可以升級為司令員(Dictator)(編者注:我這里不能直接翻譯英文,但是大家也能從這些命名中看出Linus Torvalds這類極客經常喜歡干的事情,就是自嘲。),他(她)把項目代碼倉進行了拆分,比如按照某些子系統模式劃分子倉。這里司令員(也就是之前的集成管理員)在之前的工作中,應該能發現某幾個開發者在某些領域有特長(而他(她)也往往是根據這種觀察而劃分的子倉),他(她)就可以授權這些開發者負責某個子倉。這些開發者被稱為副官(Lieutenant)。所有的副官其實都是一個針對自己負責子代碼倉的集成管理員,按照小項目運作的方式維護對應子倉的master分支。他們也稱為仁慈的司令員(benevolent dictator)。最后司令員會把副官的master分支合并到自己的master分支,合并到官方發布的代碼倉(Blessed Repository)中去。
為了方便開發者的離線編程,Git還給開發者提供了一種暫存區(Staging area)的機制。這個暫存區給開發者一個再想一想的機會。也就是你的很多修改可以是先提交到暫存區里(git add)的,然后再一并提交到你的代碼倉(git commit)。這種機制很暖心,當然,這個特性不應該是分布式開發特有的,在集中式開發管理環境下,這個功能也可以開發出來。
自由與約束
集中式開發和分布式開發在開發者自由與約束方面,基本策略也有差別。
集中式開發
集中式開發是制定了非常多的規則,開發者只能在這些規則下進行,甚至為了確保主分支的穩定性,很多規則已經脫離了版本管理系統本身,而是通過專業的項目經理進行額外的跟進管理,比如提交前是否進行了單元測試,集成測試,是否完整地運行了測試套件,以及要寫各種文檔和報告,所有代碼必須有嚴謹的命名規范,注釋規范,提交步驟,甚至還得有一個故障庫關聯,讓開發者嚴格地自檢自查和修正。可以這么講吧,在集中式開發的規則下,開發者的自由是很少的,約束是很多的。總結一下,就是:規定你干的才能干,其他的都不能干!
分布式開發
分布式開發很少制定規則,有也是很少的規則,或者通過工具自動支持和實現。一個明顯的規則就是開源項目必須得遵守開源許可證協議。目的是留給開發者最大程度的操作自由。當然,在分布式開發的文化下,自驅力比被安排要重要得多,因為團隊可以有很多開發者,多你一個不多,少你一個不少。你要想在團隊中立足,或者有所建樹,就只能靠自己的打拼與貢獻,是否被集成管理者,副官或者項目發起人看中。當然,由于互不相識,聯系方式單一,你們的這種從不信任到信任的過程建立在郵件溝通過程中一般是漫長的,在項目開發過程中是需要不斷磨合的。當然,如果某些開發者只是沖著學習的心態,看看代碼,膜拜一下大神,這也是開發者的自由。總結一下,就是:規定你不能干的別干,其他的都能干!
寫在最后和Git同時代的有很多的版本管理系統,包括:SVN、CVS、Subversion、Perforce、Bazaar 、BitKeeper和Monotone。相比于其他的,BitKeeper和Monotone是去中心化的。今天上文談到的大部分Git的優勢都是圍繞著集中化和分布式版本管理工具的比較,沒有去刻意比較BitKeeper和Monotone。
沒有使用BitKeeper,這里面有商業化的原因。當時Torvalds確實動過念頭想直接用BitKeeper,這是一個專用軟件,當時采用的是 BitMover 許可證,不是真正開源的,所以包括GNU 項目創始人Richard Stallman在內的一些人對使用BitKeeper表示了非常大的意見。甚至Linux 內核郵件列表中還因此爆發了激烈的口水戰。Torvalds也是被逼無奈,自己直接開發了一個工具,還戲虐地稱為它Git(英式英語俚語“不愉快的人”),并直接把Git通過GNU 通用公共許可證 2.0 版(開源許可證)開源,這才有了后續的故事。這算不算是一種有心栽花花不開,無心插柳柳成蔭呢?就由大家來評判了。
當然你可能也還要問,那他為啥也不想用Monotone呢?Monotone也是開源的,而且Monotone也使用 SHA-1來識別修訂并確保數據沒有因意外損壞而更改,看似沒什么大毛病啊?我們要理解Torvalds的性格,他是個追求完美的人。他對C++編寫的Monotone的性能表現不滿意,他認為當時的 Monotone 還沒有達到像 Linux 內核開發這樣大的項目所需的性能水平,所以用C語言開發了Git。
最后談到Git能成功,Torvalds要感謝當時在Google工作的濱野純(Junio C Hamano),他慧眼識珠,把Git的維護工作交給了這位日本軟件工程師牽頭,而濱野純也確實沒有讓他失望。Git后來在濱野純的領導下,聚攏了大量的開發者一同支持和共建,不斷地改進和完善Git,至今已經出了65個版本或補丁,讓它在保持簡潔易懂的干凈界面前提下,豐富了更多的功能、插件和工具,成長為當之無愧的世界最優秀的開源版本管理軟件。
原文標題:河套IT TALK 25:Git為什么能夠成功,而其他的失敗了?
文章出處:【微信公眾號:開源技術服務中心】歡迎添加關注!文章轉載請注明出處。
-
開源技術
+關注
關注
0文章
389瀏覽量
7928 -
OpenHarmony
+關注
關注
25文章
3714瀏覽量
16256
原文標題:河套IT TALK 25:Git為什么能夠成功,而其他的失敗了?
文章出處:【微信號:開源技術服務中心,微信公眾號:共熵服務中心】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論