rcs (revision control system)
早在70年代末80年代初,vcs的概念已經存在,比如unix平台的rcs (revision control system)。rcs是由walter f. tichy使用c開發。rcs對檔案進行集中式管理,主要目的是避免多人合作情況下可能出現的衝突。如果多使用者同時寫入同乙個檔案,其寫入結果可能相互混合和覆蓋,從而造成結果的混亂。你可以將檔案交給rcs管理。rcs允許多個使用者同時讀取檔案,但只允許乙個使用者鎖定(locking)並寫入檔案 (類似於多執行緒的mutex)。這樣,當乙個程式設計師登出(check-out,見rcs的co命令)某個檔案並對檔案進行修改的時候。只有在這個程式完成修改,並登入(check-in,見rcs的ci命令)檔案時,其他程式設計師才能登出檔案。基本上rcs使用者所需要的,就是co和ci兩個命令。在co和ci之間,使用者可以對原檔案進行許多改變(change, or file delta)。一旦重新登入檔案,這些改變將儲存到rcs系統中。通過check-in將改變永久化的過程叫做提交(commit)。
cvs (concurrent versions system)
2023年,dick grune寫了一系列的shell指令碼用於版本管理,並最終以這些指令碼為基礎,構成了cvs (concurrent versions system)。cvs後來用c語言重寫。cvs是開源軟體。在當時,stallman剛剛舉起gnu的大旗,掀起開源允許的序幕。cvs被包含在gnu的軟體包中,並因此得到廣泛的推廣,最終擊敗諸多商業版本的vcs,呈一統天下之勢。
cvs繼承了rcs的集中管理的理念。在cvs管理下的檔案構成乙個庫(repository)。與rcs的鎖定檔案模式不同,cvs採用複製-修改-合併(copy-modify-merge)的模式,來實現多線開發。cvs引進了分支(branch)的概念。多個使用者可以從主幹(也就是中心庫)建立分支。分支是主幹檔案在本地複製的副本。使用者對本地副本進行修改。使用者可以在分支提交(commit)多次修改。使用者在分支的工作結束之後,需要將分支合併到主幹中,以便讓其他人看到自己的改動。所謂的合併,就是cvs將分支上發生的變化應用到主幹的原檔案上。
cvs也有許多常常被人詬病的地方,比如下面幾條:
1、合併不是原子操作(atomic operation):如果有兩個使用者同時合併,那麼合併結果將是某種錯亂的混合體。如果合併的過程中取消合併,不能撤銷已經應用的改變。
2、檔案的附加資訊沒有被追蹤:一旦納入cvs的管理,檔案的附加資訊(比如上次讀取時間)就被固定了。cvs不追蹤它所管理檔案的附加資訊的變化。
3、主要用於管理ascii檔案:不能方便的管理binary檔案和unicode檔案
svn(
subversion)
subversion的開發者karl fogel和jim blandy是長期的cvs使用者。贊助開發的collabnet, inc.希望他們寫乙個cvs的替代vcs。這個vcs應該有類似於cvs的工作方式,但對cvs的缺陷進行改進,並提供一些cvs缺失的功能。這就好像劉備從曹營拉出來單幹的劉備一樣。
總體上說,subversion在許多方面沿襲cvs,也是集中管理庫,通過記錄改變來追蹤歷史,允許分支和合併,但並不鼓勵過多分支。subversion在一些方面得到改善。subversion的合併是原子操作。它可以追蹤檔案的附加資訊,並能夠同樣的管理binary和unicode檔案。但cvs和subversion又有許多不同:
與cvs的,v檔案儲存模式不同,subversion採用關係型資料庫來儲存改變集。vcs相關資料變得不透明。
cvs中的版本是針對某個檔案的,cvs中每次commit生成乙個檔案的新版本。subversion中的版本是針對整個檔案系統的(包含多個檔案以及檔案組織方式),每次commit生成乙個整個專案檔案系統樹的新版本。
git
git的作者是linus torvald。對,就是寫linux kernel的那個linus torvald。linus在貢獻了最初的linux kernel源**之後,一直領導著linux kernel的開發。linus torvald本人相當厭惡cvs(以及subversion)。然而,作業系統核心是複雜而龐大的**「怪獸」 (2023年的linux kernel有1500萬行**,windows的**不公開,估計遠遠超過這一數目)。linux核心小組最初使用.tar檔案來管理核心**,但這遠遠無法匹配linux核心**的增長速度。linus轉而使用bitkeeper作為開發的vcs工具。bitkeeper是一款分布式的vcs工具,它可以快速的進行分支和合併。然而由於使用證書方面的爭議(bitkeeper是閉源軟體,但給linux核心開發人員發放免費的使用證書),linus最終決定寫一款開源的分布式vcs軟體:git。
對於乙個開發專案,git會儲存blob, tree, commit和tag四種物件。
1、檔案被儲存為blob物件。
2、資料夾被儲存為tree物件。tree物件儲存有指向檔案或者其他tree物件指標。
上面兩個物件類似於乙個unix的檔案系統,構成了乙個檔案系統樹。
3、乙個commit物件代表了某次提交,它儲存有修改人,修改時間和附加資訊,並指向乙個檔案樹。這一點與subversion類似,即每次提交為乙個檔案系統樹。commit是檔案集的改動。
4、乙個tag物件包含有tag的名字,並指向乙個commit物件。tag是給commit的標籤。
可以看到,與cvs,subversion儲存改變(file delta)的方式形成對照,git儲存的不是改變,而是此時的檔案本身。由於不需要遵循改變路徑來計算歷史版本,所以git可以快速的查閱歷史版本。git可以直接提取兩個commit所儲存的檔案系統樹,並迅速的算出兩個commit之間的改變。
在整個開發過程中,可能會有許多次提交(commit)。每次commit的時候,git並不總是複製所有的物件。git會檢驗所有物件的hash值。如果該物件的hash值已經存在,說明該物件已經儲存過,並且沒有發生改變,所以git只需要調整新建tree或者commit中的指標,讓它們指向已經儲存過的物件就可以了。git在commit的時候,只會新建hash值發生改變的物件。如下圖所示,我們建立新的commit的時候,只需要新建乙個commit物件,乙個tree物件和乙個blob物件就足夠了,而不需要新建整個檔案系統樹。
由於git建立、合併和刪除分支的成本極為低廉,所以git鼓勵根據需要建立多個分支。實際上,如果分支位於不同的站點(site),屬於不同的開發者,那麼就構成了分布式的多分支開發模式。每個開發者都在本地複製有自己的庫,並可以基於本地庫建立多個本地分支工作。開發者可以在需要的時候,選取某個本地分支與遠端分支合併。git可以方便的建立乙個分布式的小型開發團隊。比如我和朋友兩人各有乙個庫,各自開發,並相互拉對方的庫到本地庫合併(如果上面master,develop代表了兩個屬於不同使用者的分支,就代表了這一情況)。當然,git也允許集中式的公共倉庫存在,或者多層的公共倉庫,每個倉庫享有不同的優先順序。git的優勢不在於引進了某種開發模式,而是給了你設計開發模式的自由。
git:
菜鳥教程:
官方教程:
參考:
版本控制工具
1.vss 不常用 visual source safe 美國微軟公司的產品,目前常用的版本為6.0版。配置管理的功能比較基本,提供檔案的版本跟蹤功能,安全性不高 微軟不再對vss提供技術支援。2.cvs 不常用 concurrent version system 開發源 的配置管理工具 源於uni...
版本控制工具 SVN
學習svn的 svn入門使用 伺服器 tigris svn 客戶端 tortoise svn 伺服器的搭建 tigris svn server 1.6.5 2 建立中心庫 svnadmin create d share svnrepo 3 修改許可權配置 修改conf svnserve.conf 檔...
版本控制工具 SVN vs GIT
最近由於學校放假,不給留宿,所以一直忙於找房子,今天終於安頓下來了,之前總以為這一天離我還很遠,沒想到竟然來的這麼快。不過也好,遲早都要來的,早來早面對。凡事都有他的好的一面,只要我們心是向陽的。就好比今天我與大家分享的話題,svn vs git。我對版本控制工具用的不多,目前最常用的就是svn,但...