當今IT界,VCS版本控制系統(tǒng)的的使用已經(jīng)成了一種日常不可或缺部分迫悠。不光是程序員鹏漆、IT界甚至在其他領域也是逐漸了有了共識。通過Github寫書也不再是天方夜譚或者技術段子创泄,而是實實在在天天發(fā)生的事情艺玲。本文,我們回顧下歷史上主要版本控制系統(tǒng)(VCS)的發(fā)展過程鞠抑,涉及了內(nèi)容有:SCSS饭聚、RCS、CVS搁拙、SVN秒梳,Git和Mercurial。
概述
回顧VCS的發(fā)展歷程箕速,總體上可以劃分為三個階段酪碘。
第一代VCS,包括SCSS和RCS弧满。立足于對單個文件變化的跟蹤婆跑,檢出的文件一次只能由一個用戶在本地進行編輯,用戶通過自己的帳戶登錄到同一共享Unix主機方式實現(xiàn)庭呜。
第二代VCS滑进,包括CVS和SVN。通過引入網(wǎng)絡募谎,從而形成了包含正式意義上的項目版本的集中式版本存儲庫扶关。相比第一代VSC,有了實質(zhì)性的發(fā)展数冬,可以供多個用戶同時檢出并使用代碼节槐,但是他們都需要重新提交到同一中央存儲庫。存在的問題是嚴重依賴于中央存儲庫拐纱,對網(wǎng)絡和實時性同步要求很大铜异。
第三代VSC,包括Git和Mercurial秸架。V到現(xiàn)在發(fā)展成為了分布式VCS揍庄。在分布式VCS中,創(chuàng)建存儲庫的所有副本都是相同的东抹,無需一個集中的中央存儲庫蚂子。無需通過網(wǎng)絡實時同步內(nèi)容沃测,只需本地創(chuàng)建提交,分支和合并打開了路徑食茎,在合適時候再推送到遠端庫蒂破。
VCS重要軟件發(fā)展歷史時間表:
SCCS第一代版本管理系統(tǒng)
SCCS(Source Code Control System)是最早創(chuàng)建的VCS工具。它由貝爾實驗室的Marc Rochkind于1972年用C開發(fā)别渔。SCCS旨在解決源文件修訂跟蹤的問題附迷。此外,它還解決程序bug錯誤定位的問題钠糊。SCCS是現(xiàn)代VCS的鼻祖挟秤,至此后VCS發(fā)展30年到現(xiàn)在茁壯發(fā)展。
功能
和大多數(shù)現(xiàn)代的VCS一樣抄伍,SCCS支持一組命令艘刚,供開發(fā)人員做文件版本控制。主要實現(xiàn)的功能有:
檢入文件以使用SCCS跟蹤其歷史記錄截珍;
檢出特定的文件修訂以供審核或編譯攀甚;
檢出特定的文件修訂以進行編輯;
檢入新文件修訂以及說明更改的注釋岗喉;
還原檢出文件中所做的更改秋度;
基本分支和變更合并;
提供文件修訂歷史記錄钱床。
技術實現(xiàn)
當添加文件到SCCS進行跟蹤時荚斯,會創(chuàng)建一種稱為s文件或歷史文件特殊類型的文件。該文件使用以s開頭的原始文件名來命名查牌,存儲在名為SCCS的子目錄中事期。比如,一個名為test.txt的源文件將在./SCCS/目錄中創(chuàng)建一個名為s.test.txt的歷史文件纸颜。創(chuàng)建后兽泣,歷史記錄文件將包含原始文件的初始內(nèi)容以及一些元數(shù)據(jù)以幫助進行版本跟蹤。文件校驗和存儲在歷史記錄文件中胁孙,以驗證內(nèi)容是否遭到篡改唠倦。歷史記錄文件的內(nèi)容未經(jīng)過壓縮或編碼。由于原始文件的內(nèi)容存儲在歷史記錄文件中涮较,因此可以將檢出到到工作目錄進行查看稠鼻,編譯或編輯】衿保可以將對文件所做的進一步更改(例如枷餐,行添加,修改和刪除)檢入到歷史文件中,并增加修訂號毛肋。
SCCS檢入僅存儲增量或文件更改,而不是每次存儲整個文件內(nèi)容屋剑。這樣可以減小歷史記錄文件的大小润匙。每次檢入時,增量都存儲在歷史記錄文件內(nèi)部的稱為增量表的結(jié)構(gòu)中唉匾。如前所述孕讳,實際文件內(nèi)容或多或少是逐字復制的,帶有特殊的控制序列巍膘,用于標記已添加和已刪除內(nèi)容的各個部分的開頭和結(jié)尾厂财。由于SCCS歷史記錄文件不使用壓縮,因此它們通常比要跟蹤的實際文件大峡懈。
SCCS使用一種稱為交錯增量的增量方法璃饱,支持恒定時間檢出,而不管檢出的修訂版有多老肪康。即較舊的修訂版檢出所花費的時間不會比新的修訂版更長荚恶。
需要注意的重要一件事是,所有文件都在SCCS中被單獨跟蹤和檢入磷支。沒有辦法將更改作為一個原子單位的一部分檢入多個文件(和Git提交一樣)谒撼。每個跟蹤的文件都有一個對應的歷史文件,用于存儲其修訂歷史雾狈。
當檢出文件以在SCCS中進行編輯時廓潜,為了防止更改被其他用戶覆蓋,文件上將放置一個鎖善榛,但是這會限制多用戶的編輯從而開發(fā)效率辩蛋。
SCCS支持可以在特定文件內(nèi)存儲更改序列的分支。分支可以與原始版本合并回去锭弊,也可以與同一父級的其他分支版本合并堪澎。
基本命令
以下是最常見的SCCS命令的列表。
sccs create <filename.ext>:將新文件檢入SCCS并為其創(chuàng)建新的歷史記錄文件(默認在./SCCS/目錄中)味滞。
sccs get <filename.ext>:從相應的歷史文件中檢出文件樱蛤,并以只讀模式將其放置在工作目錄中。
sccs edit <filename.ext>:從相應的歷史文件中檢出文件進行編輯剑鞍。鎖定歷史記錄文件昨凡,以便其他用戶無法修改它。
sccs delta <filename.ext>:檢入對指定文件的修改蚁署。將提示填寫commit便脊,將更改存儲在歷史記錄文件中,然后刪除鎖光戈。
sccs prt <filename.ext>:顯示跟蹤文件的修訂日志哪痰。
sccs diffs <filename.ext>:顯示文件的當前工作副本與檢出時文件狀態(tài)之間的差異遂赠。
版本文件
一個SCCS歷史記錄文件示例:
RCS版本管理系統(tǒng)
RCS(Revision Control System)由Walter Tichy于1982年用C編寫,用以替代SCCS晌杰,SCCS當時還不是開源的跷睦。
功能
RCS與它的前任SCCS有許多共同之處,包括:
逐個文件處理修訂肋演;
跨多個文件的更改不能一起歸類為原子提交抑诸;
跟蹤文件旨在一次由一個用戶修改;
沒有網(wǎng)絡功能爹殊;
每個跟蹤文件的修訂都存儲在相應的歷史文件中蜕乡;
基本分支和修訂在單個文件中的合并。
技術實現(xiàn)
當將文件檢入RCS時梗夸,會在當前目錄下的./RCS/目錄中創(chuàng)建相應的歷史文件层玲。該文件后綴有.v,比如绒瘦,test.txt的文件將將創(chuàng)建test.txt.v的跟蹤文件称簿。
RCS使用反向增量方案來存儲文件更改。檢入文件后惰帽,文件內(nèi)容的完整快照將存儲在歷史記錄文件中憨降。修改文件并再次檢入后,將根據(jù)現(xiàn)有歷史文件內(nèi)容計算增量该酗。舊的快照將被丟棄授药,新的快照將被保存,并與增量一起恢復到較早的狀態(tài)呜魄。之所以稱為反向增量悔叽,是因為要檢出舊版本,RCS需要從文件的最新版本開始并應用連續(xù)的增量爵嗅,直到達到舊版本為止娇澎。由于始終可以使用當前修訂的完整快照,因此該方法可以非扯蒙梗快速地檢出當前修改趟庄。但是,檢出版本越老伪很,檢出花費的時間越長戚啥,因為需要針對當前快照計算越來越多的增量。
相比較SCCS花費相同的時間來獲取任何修改锉试。RCS歷史記錄文件中沒有存儲校驗和猫十,因此無法確保文件完整性。
基本命令
以下是最常見的RCS命令的列表:
ci <filename.ext>:將一個新文件檢入RCS并為其創(chuàng)建一個新的歷史記錄文件(默認在./RCS/目錄中)。
co <filename.ext>:從相應的歷史文件中檢出文件拖云,并以只讀模式將其放置在工作目錄中贷笛。
co -l <??filename.ext>:從相應的歷史文件中檢出文件以進行編輯。鎖定歷史記錄文件江兢,以便其他用戶無法修改它昨忆。
ci <filename.ext>:檢入文件更改并在其對應的歷史文件中為其創(chuàng)建一個新修訂。
merge <file-to-merge-into.ext> <parent.ext> <file-to-merge-from.ext>:合并更改來自同一父文件的兩個修改后的子對象杉允。
rcsdiff <filename.ext>:顯示文件的當前工作副本與檢出時文件狀態(tài)之間的差異。
rcsclean:刪除沒有鎖的工作文件席里。
RCS更多操作介紹叔磷,詳見GNU RCS說明手冊。
版本文件
RCS .v歷史記錄文件樣例
CVS第二代版本管理系統(tǒng)
CVS(Concurrent Versions System)由Dick Grune于1986年創(chuàng)建奖磁,主要是在第一代單機版本控制工具基礎上添加了網(wǎng)絡改基,使其網(wǎng)絡化協(xié)作化。CVS也是用C語言編寫的咖为。CVS開啟了VCS發(fā)展的第二個里程碑秕狰,開啟了第二代VCS工具的發(fā)展。CVS的網(wǎng)絡化使地理上分散的開發(fā)團隊可以協(xié)同開發(fā)躁染。
功能
CVS采用C/S架構(gòu)體系鸣哀,其代碼都都存儲在服務器端,開發(fā)者需從服務器上獲得一份代碼復制到本機吞彤,然后開發(fā)我衬。開發(fā)者可隨時將新代碼提交給服務器,也可以通過更新操作獲得最新的代碼饰恕,保持與其他開發(fā)者的一致挠羔。CVS提供了一組用于與項目中的文件進行交互的命令,但是使用RCS歷史文件格式和后臺命令埋嵌。
VCS歷史上破加,CVS首次允許多個開發(fā)人員檢出并同時處理相同的文件。CVS在處理多人同時修改頁面時雹嗦,采用"先允許修改范舀,再處理沖突"。
檢出:用來下載文件和建立服務器和本機目錄之間的對應關系俐银。不會修改本機已有文件的"只讀"屬性尿背;
Export輸出:用來下載服務器文件到本機,從而進行軟件的編譯發(fā)布捶惜;
更新:用于獲取當前最新版本田藐,也可以用于獲取某個特定版本;
Edit編輯:僅用來通知服務器,要編輯某個文件汽久。
unedit:僅用來通知服務器鹤竭,完成某個文件的編輯了,同時將本機文件置為"只讀"景醇;
Watch:實現(xiàn)監(jiān)視協(xié)作者edit文件狀態(tài)的情況臀稚,要實現(xiàn)這種監(jiān)控,要求所有人在自己本機修改文件之前三痰,都edit一下吧寺,并在commit之后,unedit一下散劫,別人才能收到通知稚机;
Commit:類似于檢入,不同的是获搏,其不修改本機文件的"只讀"屬性赖条,commit后你仍然可以繼續(xù)修改本機文件,必須unedit后文件屬性才改完"只讀"常熙。
技術實現(xiàn)
CVS通過使用集中式存儲庫模型纬乍,第一步是使用CVS在遠程服務器上建立集中式存儲庫。然后就可以將項目導入到存儲庫中裸卫,將項目導入CVS后仿贬,每個文件都被轉(zhuǎn)化為.v歷史文件,并存儲在被稱為模塊的中央目錄中彼城。該存儲庫通常位于可通過本地網(wǎng)絡或Internet訪問的遠程服務器上诅蝶。
開發(fā)人員通過檢出該模塊的副本,并復制到本地工作目錄中募壕。在此過程中不會文件被鎖定调炬,因此可以同時無限制的進行文件檢出。開發(fā)人員可以修改檢出的文件并根據(jù)需要提交更改舱馅。如果開發(fā)人員要提交更改缰泡,則其他開發(fā)人員將需要在提交更改之前先通過自動合并過程更新其工作副本。必要時候代嗤,需要先解決合并沖突棘钞。 CVS還提供了創(chuàng)建和合并分支的功能。
基本命令
export CVSROOT=<path/to/repository>:設置CVS存儲庫根目錄干毅,無需在每個命令中都指定它宜猜。
cvs import -m 'Import module' <module-name> <vendor-tag> <release-tag>:將文件目錄導入CVS模塊。
cvs checkout <module-name>:將模塊復制到工作目錄硝逢。
cvs commit <filename.ext>:將更改的文件提交回模塊姨拥。
cvs add <filename.txt>:添加一個新文件以跟蹤修訂绅喉。
cvs update:通過合并遠程存儲庫中存在的已提交更改而不是工作副本來更新工作目錄。
cvs status:顯示有關已檢出模塊工作副本的常規(guī)信息叫乌。
cvs tag <tag-name> <files>:將識別標記添加到單個文件或一組文件中柴罐。
cvs tag -b <new-branch-name>:在存儲庫中創(chuàng)建一個新分支(必須先檢出,然后在本地進行操作)憨奸。
cvs checkout -r <branch-name>:將現(xiàn)有分支檢出到工作目錄革屠。
cvs update -j <branch-to-merge>:將現(xiàn)有分支合并到本地工作副本中。
更多CVS操作排宰,詳見GNU CVS手冊似芝。
版本文件
CVS歷史記錄文件示例:
SVN,集大成者
Subversion由Collabnet公司在2000年創(chuàng)建板甘,后交由Apache 軟件基金會維護国觉。SVN也是用C編寫的,用于改善CVS虾啦,實現(xiàn)更強大的集中式解決方案。時至當下痕寓,仍有大量的公司依賴于SVN實現(xiàn)其項目管理傲醉。
技術實現(xiàn)
和CVS一樣呻率,SVN也使用集中式存儲庫模型硬毕。遠程用戶必須依賴網(wǎng)絡來實現(xiàn)連接才能將其更改提交到中央存儲庫。
Subversion引入了原子提交的功能礼仗,確保提交將完全成功吐咳,或者在發(fā)生問題時被完全放棄。在CVS中元践,如果提交操作中途失斁录埂(例如,由于網(wǎng)絡中斷)单旁,則存儲庫可能損壞和不一致的狀態(tài)沪羔。
Subversion中的提交或修訂可以包含多個文件和目錄。這樣可以允許用戶以項目為單位的跟蹤相關更改集象浑,而無需分別跟蹤每個文件的更改蔫饰。
Subversion用于跟蹤文件的存儲模型稱為FSFS(File System atop the File System),使用與運行的操作系統(tǒng)文件系統(tǒng)相匹配的文件和目錄結(jié)構(gòu)來創(chuàng)建其數(shù)據(jù)庫結(jié)構(gòu)愉豺。Subversion文件系統(tǒng)的獨特之處在于篓吁,它不僅可以跟蹤其包含的文件和目錄,還可以跟蹤這些文件和目錄的不同版本蚪拦,并且它們會隨著時間變化杖剪。它是一個具有附加時間維度的文件系統(tǒng)冻押。
Subversion以文件夾為基本管理單位≌瑁可以在Subversion中提交空文件夾翼雀,而在其它(甚至是Git)VCS中,無法管理空文件夾孩擂。
創(chuàng)建Subversion存儲庫后狼渊,將創(chuàng)建一個空的文件和文件夾數(shù)據(jù)庫作為其一部分。將創(chuàng)建一個名為db/revs的目錄类垦,其中存儲了已檢入(已提交)文件的所有修訂跟蹤信息狈邑。每次提交(可以包括對多個文件的更改)都存儲在revs目錄中的新文件中,并以從1開始的順序數(shù)字標識符命名蚤认。當首次提交文件時米苹,將存儲其全部內(nèi)容。為了節(jié)省空間砰琢,同一文件的在次提交時候?qū)H存儲變化部分蘸嘶,也稱為diffs或deltas。
另外陪汽,SVN還使用lz4或zlib壓縮算法壓縮增量训唱,以進一步減小其大小。
盡管每次都存儲文件增量而不是整個文件確實節(jié)省了存儲空間挚冤,但由于需要將所有增量捆綁在一起以重新創(chuàng)建文件的當前狀態(tài)况增,因此增加了檢出和提交操作的時間。默認情況下训挡,Subversion在存儲文件的新完整副本之前澳骤,每個文件最多可以存儲1023個增量。這樣可以實現(xiàn)存儲和速度之間的良好平衡澜薄。
SVN不使用常規(guī)的分支和標記系統(tǒng)为肮。一般的Subversion存儲庫布局是在根目錄中包含三個文件夾:
trunk/
brances/
tags/
trunk文件夾用于應用程序的生產(chǎn)版本。brances文件夾用于保存與各個分支相對應的子文件夾表悬。tags文件夾用于保存特定(通常是重要的)項目修訂的標簽弥锄。
基本命令
svn create <path-to-repository>:在指定目錄中創(chuàng)建一個新的空存儲庫。
svn import <path-to-project> <svn-url>:將文件目錄導入指定的Subversion存儲庫路徑蟆沫。
svn checkout <svn-path> <path-to-checkout>:將存儲的存儲庫路徑復制到所需的工作目錄籽暇。
svn commit -m 'Commit message':提交一組更改的文件和文件夾以及描述性的提交消息。
svn add <filename.txt>:添加一個新文件以跟蹤修訂饭庞。
svn update:通過合并svn服務器中存在的已提交更改而不是工作副本來更新工作副本戒悠。
svn status:顯示工作目錄中已更改的跟蹤文件的列表。
svn info:顯示有關已檢出副本的常規(guī)詳細信息列表舟山。
svn copy <branch-to-copy> <new-branch-path-and-name>:通過復制現(xiàn)有分支來創(chuàng)建一個新分支绸狐。
svn switch <existing-branch>:將工作目錄切換到現(xiàn)有分支卤恳。這將檢出指定的分支。
svn merge <existing-branch>:將指定的分支合并到工作目錄中檢出的當前分支中寒矿。請注意突琳,這需要在以后提交。
svn log:顯示活動分支的提交歷史記錄和相關的描述性消息符相。
版本文件
SVN修訂文件示例如下
第三代版本管理系統(tǒng)Git
Git由Linux之父Linus Torvalds于2005年創(chuàng)建用來替代Linux內(nèi)核開發(fā)用的商業(yè)的版本管理軟件BitKeeper拆融。主要是用C結(jié)合一些Shell腳本編寫的。由于其功能啊终,靈活性和速度镜豹,分布式版本管理、協(xié)作性蓝牲,使得Git成長為一個最出色的VCS軟件趟脂。由于GitHub,Gitlab等添加的協(xié)作性例衍,社交性功能使得Git風靡于世昔期,被廣泛使用。
技術實現(xiàn)
Git是分布式VCS佛玄,無需集中式的中央存儲卡镇眷,就可以正常工作。在Git中所有副本都創(chuàng)建為相等翎嫡,即便是遠程Git服務上也是是等價的副本。這是與第二代VCS最明顯得差異永乌,第二代集中式的版本管理惑申,必須要依靠中央服務器來提供用戶檢入和檢出。而在Git中開發(fā)人員可以本地任意開發(fā)翅雏,即使連不到遠程庫也不受任何影響圈驼,只需在網(wǎng)絡通暢時候,再將變化推送服務器即可望几。開發(fā)人員可以脫機在本地工作绩脆,直到準備與他人共享他們的工作為止。此時橄抹,可以將更改推送到其他存儲庫以進行檢查靴迫,測試或部署。
Blob對象
添加文件以使用Git進行跟蹤時楼誓,Git使用zlib壓縮算法對其進行壓縮玉锌。使用SHA-1哈希函數(shù)對結(jié)果進行哈希處理。這將產(chǎn)生一個唯一的哈希值疟羹,該值對應于該文件中的內(nèi)容主守。Git將其存儲在位于隱藏的.git/objects文件夾中的對象數(shù)據(jù)庫中禀倔。文件的名稱為生成的哈希值,內(nèi)容為壓縮的內(nèi)容参淫。這些對象文件稱為Blob救湖,每次將新文件添加到存儲庫時會創(chuàng)建Blob對象。
Git實現(xiàn)了一個staging索引涎才,該索引被設計為在提交的中間區(qū)域鞋既。在準備提交新更改時,它們的壓縮內(nèi)容在特殊的索引文件中被引用憔维,該文件采用樹對象的形式涛救。
樹對象是另一種Git對象,對應于文件目錄业扒,它將blob對象連接到它們的真實文件名检吆,文件許可權(quán)和到其他樹的鏈接,并以此方式表示特定文件和目錄集的狀態(tài)程储。一旦所有相關更改都準備好提交蹭沛,索引樹就可以提交到存儲庫,該存儲庫在Git對象數(shù)據(jù)庫中創(chuàng)建一個commit對象章鲤。
commit對象保存特定修訂的標題樹以及提交作者摊灭,電子郵件地址,日期和描述性提交消息败徊。每個commit對象還保存對其父提交的引用帚呼,因此隨著時間的推移,將建立項目開發(fā)的歷史記錄皱蹦。
如前所述煤杀,所有Git對象(Blob,tree和commit)都根據(jù)其哈希值進行壓縮沪哺,哈希處理并存儲在對象數(shù)據(jù)庫中沈自。這些被稱為松散對象。Git實現(xiàn)中沒有通過差異來節(jié)省空間辜妓,而都是全部內(nèi)容哈希鍵索引和壓縮鏡像枯途,所以,Git非臣危快卢鹦,因為每個文件修訂版的全部內(nèi)容都可以作為一個松散的對象來訪問转唉。但是四瘫,某些操作(例如八孝,將提交推送到遠程存儲庫,存儲太多對象或手動運行Git的垃圾收集命令)可能會導致Git將對象重新打包為打包文件灰瞻,在打包過程中腥例,采用反向差異并進行壓縮以消除多余的內(nèi)容并減小尺寸辅甥。該過程將生成包含對象內(nèi)容的.pack文件,每個文件都有一個對應的.idx索引文件燎竖,其中包含對打包對象及其在打包文件中位置的引用璃弄。
當將分支推送到遠程存儲庫或從遠程存儲庫拉出分支時,這些打包文件將通過網(wǎng)絡傳輸构回。提取或獲取分支時夏块,將打包文件解壓縮以在對象存儲庫中創(chuàng)建松散對象。
基本命令
git init:將當前目錄初始化為Git存儲庫(創(chuàng)建隱藏的.git文件夾及其內(nèi)容)纤掸。
git clone <git-url>:在指定的URL下載Git存儲庫的副本脐供。
git add <filename.ext>:將未跟蹤的文件或更改的文件添加到暫存區(qū)(在對象數(shù)據(jù)庫中創(chuàng)建相應的條目)。
git commit -m '提交消息':提交一組更改的文件和文件夾以及描述性提交消息借跪。
git status:顯示與工作目錄政己,當前分支,未跟蹤的文件掏愁,已修改的文件等狀態(tài)有關的信息歇由。
git branch <new-branch>:基于當前檢出的分支創(chuàng)建一個新分支。
git checkout <branch>:將指定的分支檢出到工作目錄中果港。
git merge <branch>:將指定的分支合并到工作目錄中檢出的當前分支中沦泌。
git pull:更新工作c通過合并遠程存儲庫中存在的已提交更改而不是工作副本來進行操作。
git push:將本地活動分支提交的松散對象打包到打包文件中辛掠,并傳輸?shù)竭h程存儲庫谢谦。
git log:顯示活動分支的提交歷史記錄和相關的描述性消息。
git stash:將工作目錄中所有未提交的更改保存到緩存中萝衩,以便以后可以檢索他宛。
有關Git內(nèi)部的更多信息,請參閱Pro Git書籍中有關Git內(nèi)部的章節(jié)
版本文件
Git對象文件示例:
Blob對象
.git/objects/a8/420ef73065a9e3e57fe8fd2d32dad28e332bd0
表示哈希值a8420ef73065a9e3e57fe8fd2d32dad28e332bd0
的Blob對象
可以使用:
git cat-file -t a8420ef73065a9e3e57fe8fd2d32dad28e332bd0
查看器對象類型為blob
使用git cat-file -p a8420ef73065a9e3e57fe8fd2d32dad28e332bd0
查看器內(nèi)容為hello,Chongchong!
Tree對象
.git/objects/ba/0ea2e2c2f9fc822ca16046f8d3f1f24660014c
表示哈希值為ba0ea2e2c2f9fc822ca16046f8d3f1f24660014c
的tree對象欠气,其類型為tree,值為:
040000 tree 887ad439b842a19be9a1922253872427763b0376 hello
Commit對象
.git/objects/da/7a3c9c71eb9da8022018fb5ce02a4625b753d5
表示哈希值為da7a3c9c71eb9da8022018fb5ce02a4625b753d5
的commit對象镜撩,其類型為commit预柒,值為
該次commit關聯(lián)到da7a3c9c71eb9da8022018fb5ce02a4625b753d5
的tree對象,commit消息為init
袁梗。
Mercurial 即將死去的另外一個選擇
Mercurial由Matt Mackall于2005年創(chuàng)建宜鸯,采用 Python編寫。它也是從托管Linux代碼庫的目標開始的遮怜,是目前次于Git的第二受歡迎的分布式VCS淋袖,但使用頻率不多。隨著最近BitBucket宣布將停止對Mercurial的支持锯梁,表示著Mercurial即將死去焰情,除了Git后沒有了另外的選擇。
技術實現(xiàn)
和Git一樣内舟,Mercurial是一個分布式版本控制系統(tǒng)初橘,它允許任何數(shù)量的開發(fā)人員獨立于其他人使用他們自己的項目副本验游。 Mercurial利用了許多與Git相同的技術,例如壓縮和SHA-1哈希保檐,但是采用了不同的方式耕蝉。
當提交新文件以在Mercurial中進行跟蹤時,將在隱藏目錄.hg/store/data/中為其創(chuàng)建相應的revlog文件夜只±菰冢可以將revlog(或修訂日志)文件看作是較舊的VCS(如CVS,RCS和SCCS)使用的歷史記錄文件的現(xiàn)代化版本盐肃。與Git為每個暫存文件的每個版本創(chuàng)建一個新的Blob不同爪膊,Mercurial只是在該文件的revlog中創(chuàng)建一個新條目。為了節(jié)省空間砸王,每個新條目僅包含先前版本的增量(更改)推盛。一旦達到閾值數(shù)量的增量,將再次存儲文件的完整快照谦铃。在應用許多增量來重建特定文件修訂版時耘成,這減少了查找時間。
這些文件修訂日志的名稱與它們跟蹤的文件匹配驹闰,但是后綴為.i和.d擴展名瘪菌。.d文件包含壓縮的增量內(nèi)容。.i文件用作索引嘹朗,以快速跟蹤.d文件中的不同修訂版本师妙。
Mercurial使用了另一種類型的修訂日志,稱為變更日志屹培。更改日志包含條目列表默穴,這些條目將每個提交與以下信息相關聯(lián):
Manifest nodeid:標識特定時間存在的完整文件修訂集;
父提交節(jié)點ID:這使Mercurial可以建立時間表或項目歷史記錄的分支褪秀。根據(jù)提交的類型(正常vs合并)蓄诽,存儲一個或兩個父ID;
提交人媒吗;
提交日期仑氛;
提交信息;
每個變更日志條目還會生成一個稱為其節(jié)點ID的哈希。
基本命令
hg init:將當前目錄初始化為Mercurial存儲庫(創(chuàng)建隱藏的.hg文件夾及其內(nèi)容)锯岖。
hg clone <hg-url>:在指定的URL下載Mercurial存儲庫的副本介袜。
hg add <filename.ext>:添加新文件以進行修訂跟蹤。
hg commit -m '提交消息':提交一組更改的文件和文件夾以及描述性提交消息嚎莉。
hg status:顯示與工作目錄米酬,未跟蹤文件,已修改文件等狀態(tài)有關的信息趋箩。
hg update <revision>:將指定的分支檢出到工作目錄中赃额。
hg merge <branch>:將指定的分支合并到工作目錄中檢出的當前分支中。
hg pull:從遠程存儲庫下載新修訂叫确,但不要將其合并到工作目錄中跳芳。
hg push:將新修訂版本傳輸?shù)竭h程存儲庫。
hg log:顯示活動分支的提交歷史記錄和相關的描述性消息竹勉。
版本文件
Mercurial 版本文件示例:
Manifest revlog
hey.txt208b6e0998e8099b16ad0e43f036ec745d58ec04
hi.txt74568dc1a5b9047c8041edd99dd6f566e78d3a42hi.txt74568dc1a5b9047c8041edd99dd6f566e78d3a42
revlog
總結(jié)
本文中飞盆,我們回顧了VCS版本控制的發(fā)展歷史,介紹了VCS版本控制系統(tǒng)技術演進過程次乓,對歷史上曾經(jīng)出現(xiàn)的主要VCS軟件進行了介紹和比較吓歇、還有各自的技術實現(xiàn)以及常見操作命令。