SVN與Git版本控制的優(yōu)缺點(diǎn)差異全面分析
一、集中式vs分布式
1.Subversion屬于集中式的版本控制系統(tǒng)
集中式的版本控制系統(tǒng)都有一個單一的集中管理的服務(wù)器,保存所有文件的修訂版本,而協(xié)同工作的人們都通過客戶端連到這臺服務(wù)器,取出最新的文件或者提交更新。
Subversion的特點(diǎn)概括起來主要由以下幾條:
- 每個版本庫有唯一的URL(官方地址),每個用戶都從這個地址獲取代碼和數(shù)據(jù);
- 獲取代碼的更新,也只能連接到這個唯一的版本庫,同步以取得最新數(shù)據(jù);
- 提交必須有網(wǎng)絡(luò)連接(非本地版本庫);
- 提交需要授權(quán),如果沒有寫權(quán)限,提交會失?。?/li>
- 提交并非每次都能夠成功。如果有其他人先于你提交,會提示“改動基于過時的版本,先更新再提交”… 諸如此類;
- 沖突解決是一個提交速度的競賽:手快者,先提交,平安無事;手慢者,后提交,可能遇到麻煩的沖突解決。
好處:
每個人都可以一定程度上看到項(xiàng)目中的其他人正在做些什么。而管理員也可以輕松掌控每個開發(fā)者的權(quán)限。
缺點(diǎn):中央服務(wù)器的單點(diǎn)故障。
若是宕機(jī)一小時,那么在這一小時內(nèi),誰都無法提交更新、還原、對比等,也就無法協(xié)同工作。如果中央服務(wù)器的磁盤發(fā)生故障,并且沒做過備份或者備份得不夠及時的話,還會有丟失數(shù)據(jù)的風(fēng)險。最壞的情況是徹底丟失整個項(xiàng)目的所有歷史更改記錄,被客戶端提取出來的某些快照數(shù)據(jù)除外,但這樣的話依然是個問題,你不能保證所有的數(shù)據(jù)都已經(jīng)有人提取出來。
Subversion原理上只關(guān)心文件內(nèi)容的具體差異。每次記錄有哪些文件作了更新,以及都更新了哪些行的什么內(nèi)容。
2.Git屬于分布式的版本控制系統(tǒng)
Git記錄版本歷史只關(guān)心文件數(shù)據(jù)的整體是否發(fā)生變化。Git 不保存文件內(nèi)容前后變化的差異數(shù)據(jù)。
實(shí)際上,Git 更像是把變化的文件作快照后,記錄在一個微型的文件系統(tǒng)中。每次提交更新時,它會縱覽一遍所有文件的指紋信息并對文件作一快照,然后保存一個指向這次快照的索引。為提高性能,若文件沒有變化,Git 不會再次保存,而只對上次保存的快照作一連接。
在分布式版本控制系統(tǒng)中,客戶端并不只提取最新版本的文件快照,而是把原始的代碼倉庫完整地鏡像下來。這么一來,任何一處協(xié)同工作用的服務(wù)器發(fā)生故障,事后都可以用任何一個鏡像出來的本地倉庫恢復(fù)。這類系統(tǒng)都可以指定和若干不同的遠(yuǎn)端代碼倉庫進(jìn)行交互。籍此,你就可以在同一個項(xiàng)目中,分別和不同工作小組的人相互協(xié)作。你可以根據(jù)需要設(shè)定不同的協(xié)作流程。
另外,因?yàn)镚it在本地磁盤上就保存著所有有關(guān)當(dāng)前項(xiàng)目的歷史更新,并且Git中的絕大多數(shù)操作都只需要訪問本地文件和資源,不用連網(wǎng),所以處理起來速度飛快。用SVN的話,沒有網(wǎng)絡(luò)或者斷開VPN你就無法做任何事情。但用Git的話,就算你在飛機(jī)或者火車上,都可以非常愉快地頻繁提交更新,等到了有網(wǎng)絡(luò)的時候再上傳到遠(yuǎn)程的鏡像倉庫。換作其他版本控制系統(tǒng),這么做幾乎不可能,抑或是非常麻煩。
Git具有以下特點(diǎn):
Git中每個克隆(clone)的版本庫都是平等的。你可以從任何一個版本庫的克隆來創(chuàng)建屬于你自己的版本庫,同時你的版本庫也可以作為源提供給他人,只要你愿意。
Git的每一次提取操作,實(shí)際上都是一次對代碼倉庫的完整備份。
提交完全在本地完成,無須別人給你授權(quán),你的版本庫你作主,并且提交總是會成功。
甚至基于舊版本的改動也可以成功提交,提交會基于舊的版本創(chuàng)建一個新的分支。
Git的提交不會被打斷,直到你的工作完全滿意了,PUSH給他人或者他人PULL你的版本庫,合并會發(fā)生在PULL和PUSH過程中,不能自動解決的沖突會提示您手工完成。
沖突解決不再像是SVN一樣的提交競賽,而是在需要的時候才進(jìn)行合并和沖突解決。
Git 也可以模擬集中式的工作模式
Git版本庫統(tǒng)一放在服務(wù)器中
可以為 Git 版本庫進(jìn)行授權(quán):誰能創(chuàng)建版本庫,誰能向版本庫PUSH,誰能夠讀?。寺。┌姹編?/p>
團(tuán)隊(duì)的成員先將服務(wù)器的版本庫克隆到本地;并經(jīng)常的從服務(wù)器的版本庫拉(PULL)最新的更新;
團(tuán)隊(duì)的成員將自己的改動推(PUSH)到服務(wù)器的版本庫中,當(dāng)其他人和版本庫同步(PULL)時,會自動獲取改變
Git 的集中式工作模式非常靈活
你完全可以在脫離Git服務(wù)器所在網(wǎng)絡(luò)的情況下,如移動辦公/出差時,照常使用代碼庫
你只需要在能夠接入Git服務(wù)器所在網(wǎng)絡(luò)時,PULL和PUSH即可完成和服務(wù)器同步以及提交
Git提供 rebase 命令,可以讓你的改動看起來是基于最新的代碼實(shí)現(xiàn)的改動
Git 有更多的工作模式可以選擇,遠(yuǎn)非 Subversion可比
二、版本庫與工作區(qū)
Subversion的工作區(qū)和版本庫是截然分開的,而Git的工作區(qū)和版本庫是如影隨形的。
1.SVN的版本庫和工作區(qū)是分離的
Subversion 的工作區(qū)和版本庫物理上分開:Subversion的版本庫和工作區(qū)是存儲在不同路徑下,一般是在不同的主機(jī)中,Subversion的企業(yè)級部署中,版本庫在服務(wù)器上,只能通過 https, http, svn 等協(xié)議訪問,而不能直接被用戶接觸到。
Subversion的工作區(qū)是一份版本庫在某個歷史狀態(tài)下的快照,如:版本庫最新的數(shù)據(jù)檢出到工作區(qū)。
Subversion的工作區(qū)中每一個目錄下都包含一個名為 .svn 的控制目錄(隱藏的目錄),該目錄的作用是:
① 標(biāo)識工作區(qū)和版本庫的對應(yīng)關(guān)系。
② 包含一份該子目錄下檢出文件的原始拷貝。當(dāng)文件改動的差異比較或者本地改動的回退時,可以直接參考原始拷貝而無須通過網(wǎng)絡(luò)訪問遠(yuǎn)程版本庫。
Subversion 的 .svn 控制目錄會引入很多麻煩:
① .svn 下的文件原始考本,會導(dǎo)致在目錄下按照文件內(nèi)容搜索時,多出一倍的搜索時間和搜索結(jié)果。
② .svn 很容易在集成時,引入產(chǎn)品中,尤其是 Web 應(yīng)用,將 .svn 目錄帶入Web服務(wù)器會導(dǎo)致安全隱患。因?yàn)橐粋€不允許目錄瀏覽的Web目錄,可以通過 .svn/entries 文件查看到該目錄下可能存在的文件。
2 .Git 的版本庫和工作區(qū)如影隨形
Git 的版本庫和工作區(qū)在同一個目錄下,工作區(qū)的根目錄有一個.git的子目錄,這個名為 .git的目錄就是版本庫本身,它是Git 用來保存元數(shù)據(jù)和對象數(shù)據(jù)庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時候,實(shí)際拷貝的就是這個目錄里面的數(shù)據(jù)。所以千萬要小心刪除這個文件。
工作區(qū)中其他文件為工作區(qū)文件,可能是從 .git 中檢出的,或者是要檢入的,或者是運(yùn)行產(chǎn)生的臨時文件等。
版本庫可以脫離工作區(qū)而存在,成為 bare(赤裸)版本庫??梢杂?–bare參數(shù)來創(chuàng)建。但是工作區(qū)不能脫離版本庫而存在,即工作區(qū)的根目錄下必須有一個名為 .git 的版本庫克隆文件。
Git 的版本庫因?yàn)榫驮诠ぷ鲄^(qū)中,能直接被用戶接觸到。
① 用戶可以編輯 .git/config 文件,修改配置,增添新的源
② 用戶可以編輯 .git/info/exclude 文件,創(chuàng)建本地忽略…
Git 的工作區(qū)中只在工作區(qū)的根目錄下有一個 .git 目錄,此外再無任何控制目錄。Git 工作區(qū)下唯一的 .git 目錄是版本庫,并非 .svn 的等價物,如果刪除了 .git 目錄,而又沒有該版本庫的其他鏡像(克?。┑脑挘闫茐牧苏麄€歷史,版本庫也永遠(yuǎn)的失去了。
Git 在本地的 .git 版本庫,提供了完全的改動歷史。除了和其他人數(shù)據(jù)交換外,任何版本庫相關(guān)的操作都在本地完成,更多的本地操作,避免了冗長的網(wǎng)絡(luò)延遲,大大節(jié)省了時間。例如:查看 log,切換到任何歷史版本等操作都無須連接網(wǎng)絡(luò)。
Git如何保證安全:本地創(chuàng)建一個Git庫,因?yàn)楣ぷ鲄^(qū)和庫是在同一個目錄中,如果工作區(qū)刪除了,或者所在的磁盤分區(qū)格式化了,數(shù)據(jù)不是全都沒有了么?其實(shí)我們可以這樣做:
① 在一個磁盤分區(qū)中創(chuàng)建版本庫(最好是用 –bare 參數(shù)創(chuàng)建),然后在另外的磁盤分區(qū)中克隆一個新的作為工作區(qū)。在工作區(qū)的提交要不時的PUSH到另外分區(qū)的版本庫,這樣就實(shí)現(xiàn)了本地的數(shù)據(jù)鏡像。你甚至可以在本地創(chuàng)建更多的版本庫鏡像,安全性要比Subversion的一個庫加上一個工作區(qū)安全。
② 另一個辦法:把你的版本庫共享給他人,當(dāng)他人克隆了你的版本庫時,你就擁有了一個異地備份。
三、全局版本號和全球版本號
SVN的全局版本號和CVS的每個文件都獨(dú)立維護(hù)一套版本號相比,是一個非常大的進(jìn)步。在看似簡單的全局版本號的背后,是Subversion提供對于事物處理的支持,每一個事物處理(即一次提交)都具有整個版本庫全局唯一的版本號。
Git的版本號則更進(jìn)一步,版本號是全球唯一的。Git 對于每一次提交,通過對文件的內(nèi)容或目錄的結(jié)構(gòu)計(jì)算出一個SHA-1 哈希值,得到一個40位的十六進(jìn)制字符串,Git將此字符串作為版本號。
1. SVN與Git版本號比較
所有保存在Git 數(shù)據(jù)庫中的數(shù)據(jù)都是用此40位的哈希值作索引的,而不是靠文件名。
使用哈希值作版本號的好處就是對于一個分布式的版本控制系統(tǒng),每個人每次提交后形成的版本號都不會出現(xiàn)重復(fù)。另一好處是保證數(shù)據(jù)的完整性,因?yàn)楣V凳歉鶕?jù)內(nèi)容或目錄結(jié)構(gòu)計(jì)算出來的,所以我們還可以據(jù)此來判斷數(shù)據(jù)內(nèi)容是否被篡改。
SVN 的版本號是連續(xù)的,可以預(yù)判下一個版本號,而 Git 的版本號則不是。
因?yàn)?subversion 是集中式版本控制,很容易實(shí)現(xiàn)版本號的連續(xù)性。Git 是分布式的版本控制系統(tǒng),而且 Git 采用 40 位長的哈希值作為版本號,每個人的提交都是各自獨(dú)立完成的,沒有先后之分(即使提交有先后之分,也由于PUSH/PULL的方向和時機(jī)而不同)。Git 的版本號雖然不連續(xù),但是是有線索的,即每一個版本都有對應(yīng)的父版本(一個或者兩個),進(jìn)而可以形成一個復(fù)雜的提交鏈
Git 的版本號簡化:Git 可以使用從左面開始任意長度的字串作為簡化版本號,只要該簡化的版本號不產(chǎn)生歧義。一般采用7位的短版本號(只要不會出現(xiàn)重復(fù)的,你也可以使用更短的版本號)。
四、部分檢出
Subversion可以將整個庫檢出到工作區(qū),也可以將某個目錄檢出到工作區(qū)。對于要使用一個龐大、臃腫的版本庫的用戶來說,部分檢出是非常方便和實(shí)際的。
但是Git只能全部檢出,不支持按照目錄進(jìn)行的部分檢出。
1. SVN的部分檢出
在SVN中,從倉庫checkout的一個工作樹,每個子目錄下都維護(hù)著自己的.svn目錄,記錄著該目錄中文件的修改情況以及和服務(wù)器端倉庫的對應(yīng)關(guān)系。所以SVN可以checkout部分路徑下的內(nèi)容(部分檢出),而不用checkout整個版本庫或分支。
Subversion 有一條命令:svn export ,可以將 subversion 版本庫的一個目錄下所有內(nèi)容導(dǎo)出到指定的目錄下。Subversion 需要 svn export 命令是因?yàn)樵撁羁梢詫?dǎo)出一個干凈的目錄,即不包含 .svn 目錄(包含配置文件和文件原始拷貝)。
2. Git的檢出
Git 沒有部分檢出,這并不是說只有將整個庫克隆下來才能查看文件。有很多 git 工具,提供直接瀏覽git庫的功能,例如 gitweb, trac 的 git 版本庫瀏覽, redmine 的 git 版本庫瀏覽。
Git-submodule 可以實(shí)現(xiàn)版本庫的模塊化:Git 通過子模塊處理這個問題。
子模塊允許你將一個Git 倉庫當(dāng)作另外一個Git倉庫的子目錄。這允許你克隆另外一個倉庫到你的項(xiàng)目中并且保持你的提交相對獨(dú)立。
Git 為什么沒有實(shí)現(xiàn) svn export 的功能?由于git的本地倉庫信息完全維護(hù)在project根目錄的.git目錄下,(不像svn一樣,每個子目錄下都有單獨(dú)的.svn目錄)。所以,只要clone,checkout然后刪除.git目錄就可以了。
五、更新和提交
1.更新操作
在SVN中,因?yàn)橹挥幸粋€中心倉庫,所以所謂的遠(yuǎn)程更新,也就是svn update ,通過此命令來使工作區(qū)和版本庫保持同步。
對于git來說,別人的改動是存在于遠(yuǎn)程倉庫上的,所以git checkout命令盡管在某些功能上和svn中的update類似(例如取倉庫特定版本的內(nèi)容),但是在遠(yuǎn)程更新這一點(diǎn)上,還是不同的,不屬于git checkout的功能涵蓋范圍。
Git使用git fetch和git pull來完成遠(yuǎn)程更新任務(wù),fetch操作只是將遠(yuǎn)程數(shù)據(jù)庫的object拷貝到本地,然后更新remotes head的refs,git pull 的操作則是在git fetch的基礎(chǔ)上對當(dāng)前分支外加merge操作。
2.SVN中的commit命令
對于SVN來說,由于是中心式的倉庫管理形式,所以并不存在特殊的遠(yuǎn)程提交的概念,所有的commit操作都可以認(rèn)為是對遠(yuǎn)程倉庫的更新動作。在工作區(qū)中對文件進(jìn)行添加、修改、刪除操作要同步到版本庫,必須使用 commit命令。
add 命令,是將未標(biāo)記為版本控制狀態(tài)的文件標(biāo)記為添加狀態(tài),并在下次提交時入庫。
delete命令,是通過SVN來刪除文件,并在下次提交后有效。
Subversion 有提交列表功能,即將某些文件加入一個修改列表,提交可以只提交處于該列表的文件。
3.Git中的暫存區(qū)域(stage)
Git 管理項(xiàng)目時,文件在三個工作區(qū)域中流轉(zhuǎn):Git 的本地數(shù)據(jù)目錄,工作目錄以及暫存區(qū)域。暫存區(qū)域(stage)是介于 workcopy 和 版本庫HEAD 版本的一種中間狀態(tài)。所謂的暫存區(qū)域只不過是個簡單的文件,一般都放在git 目錄中。有時候人們會把這個文件叫做索引文件,不過標(biāo)準(zhǔn)說法還是叫暫存區(qū)域。
要將一個文件納入版本管理的范疇,首先是要用gitadd將文件納入stage的監(jiān)控范圍,只有更新到stage中的內(nèi)容才會在commit的時候被提交。另外,文件本身的改動并不會自動更新到stage中,每次的任何修改都必須重新更新到stage中去才會被提交。對于工作區(qū)直接刪除的文件,需要用 git rm 命令進(jìn)行標(biāo)記,在下次提交時,在版本庫中刪除。
工作區(qū)的文件改動(新增文件,修改文件,刪除文件),必須用 git add 或者 git rm 命令標(biāo)識,使得改動進(jìn)入 stage
提交只對加入 stage 的改動進(jìn)行提交
如果一個文件改動加入 stage 后再次改動,則后續(xù)改動不改變 stage。即該文件的改動有兩個狀態(tài),一個是標(biāo)記到 stage 中并將在下次提交時入庫的改動,另外的后續(xù)改動則不被提交,除非再次使用 git add 命令將改動加入到 stage 中。
Git的stag讓你在提交的時候清楚的知道git將要提交哪些改動。除非提交的時候使用 -a 參數(shù)(不建議使用)。
我們可以從文件所處的位置來判斷其狀態(tài):如果是git目錄中保存著的特定版本文件,就屬于已提交狀態(tài);如果作了修改并已放入暫存區(qū)域,就屬于已暫存狀態(tài);如果自上次取出后,作了修改但還沒有放到暫存區(qū)域,就是已修改狀態(tài),如果取出后未進(jìn)行修改則是未修改狀態(tài)。
在git中,因?yàn)橛斜镜貍}庫和remote倉庫之分,所以也就區(qū)別于commit 操作,存在額外的push命令,用于將本地倉庫的數(shù)據(jù)更新到遠(yuǎn)程倉庫中去。git push 可以選擇需要提交的、更新的分支以及制定該分支在遠(yuǎn)程倉庫上的名字。
六、分支和里程碑的實(shí)現(xiàn)
幾乎每一種版本控制系統(tǒng)都以某種形式支持分支。使用分支意味著你可以從開發(fā)主線上分離開來,然后在不影響主線的同時繼續(xù)工作。在很多版本控制系統(tǒng)中,這是個昂貴的過程,常常需要創(chuàng)建一個源代碼目錄的完整副本,對大型項(xiàng)目來說會花費(fèi)很長時間。
輕量級分支/里程碑的含義是,創(chuàng)建分支/里程碑的復(fù)雜度是o(1),不會因?yàn)榘姹編斓挠育嫶蠖兊镁徛?。在CVS中,創(chuàng)建分支的復(fù)雜度是o(n)的,導(dǎo)致大的版本庫的的分支創(chuàng)建非常緩慢。
1.Subversion的分支/里程碑
Subversion輕量級分支和里程碑的實(shí)現(xiàn)是通過svn cp命令,即帶歷史的拷貝就是創(chuàng)建快速創(chuàng)建分支和里程碑的秘籍。Subversion的版本庫有特殊的設(shè)計(jì),當(dāng)你復(fù)制一個目錄,你不需要擔(dān)心版本庫會變得十分巨大—Subversion并不是拷貝所有的數(shù)據(jù),相反,它只是建立了一個已存在目錄樹的入口。這種“廉價的拷貝”就是創(chuàng)建分支/里程碑是輕量級的原因。
由于Svn的分支和標(biāo)簽是來自目錄拷貝,約定俗成是拷貝在 branches/和tags/目錄下。所謂分支,tag等概念都只是倉庫中不同路徑上的一個對象或索引而已,和普通的路徑并沒有什么本質(zhì)的區(qū)別,誰也不能阻止在一個提交中同時修改不同分支中的數(shù)據(jù)。
里程碑是對某個歷史提交所起的一個別名,作為歷史的標(biāo)記,是不應(yīng)該被更改的。svn的里程碑要建立到 tags/目錄下,要求不要在tags/下的里程碑目錄下進(jìn)行提交。但是誰也阻止不了對未進(jìn)行權(quán)限控制的里程碑的篡改。
2.Git 的輕量級分支和里程碑
Git中的分支實(shí)際上僅是一個包含所指對象校驗(yàn)和(40個字符長度SHA-1 哈希值)的文件,所以創(chuàng)建和銷毀一個分支就變得非常廉價。說白了,新建一個分支就是向一個文件寫入41個字節(jié)(版本號外加一個換行符)那么簡單,自然速度就很快了。 Git的實(shí)現(xiàn)與項(xiàng)目復(fù)雜度無關(guān),它永遠(yuǎn)可以在幾毫秒的時間內(nèi)完成分支的創(chuàng)建和切換。這和大多數(shù)版本控制系統(tǒng)形成了鮮明對比。
Git的分支是完全隔離的,而Subversion則沒有。分支本來就應(yīng)該是相對獨(dú)立的命名空間,一個提交一般只能發(fā)生在一個分支中。在Git中,其內(nèi)部的對象層級依賴關(guān)系或許和SVN類似,但是其工作樹的視圖表現(xiàn)形式和SVN完全不同。工作樹永遠(yuǎn)是一個完整的分支,不同的分支由不同的head索引去構(gòu)建,你不可能在工作樹中同時獲得多個分支的內(nèi)容。
Git使用的標(biāo)簽有兩種類型:輕量級的(lightweight)和含附注的(annotated)。① 輕量級標(biāo)簽就像是個不會變化的分支,實(shí)際上它就是個指向特定提交對象的引用。② 而含附注標(biāo)簽,實(shí)際上是存儲在倉庫中的一個獨(dú)立對象,它有自身的校驗(yàn)和信息,包含著標(biāo)簽的名字,電子郵件地址和日期,以及標(biāo)簽說明,標(biāo)簽本身也允許使用GNU Privacy Guard (GPG) 來簽署或驗(yàn)證。
Git的里程碑是只讀的,Git完全遵守歷史不可更改這一時空法則。用戶不能向git的里程碑中提交,否則里程碑就不是標(biāo)記,而成了一個分支。當(dāng)然Git允許用戶刪除里程碑再重新創(chuàng)建指定到不同歷史提交。
3.多分支間的切換
SVN中提供了一個功能switch,使用switch可以在同一個工作樹上,在不同的分支中進(jìn)行切換。
Git在分支中進(jìn)行切換使用的命令是checkout。
七、分支與合并
Git 和 Svn 的分支實(shí)現(xiàn)機(jī)制完全的不同,這也直接導(dǎo)致了 SVN 在分支合并中困難重重。盡管在 SVN 1.5 之后,通過 svn:mergeinfo 屬性引入了合并追蹤機(jī)制,但是在特定情況下,合并仍會出現(xiàn)很多困難。
1.SVN的分支合并
當(dāng)你在一個分支上工作數(shù)周或幾個月之后,主干的修改也同時在進(jìn)行著,兩條線的開發(fā)會區(qū)別巨大,當(dāng)你想合并分支回主干,可能因?yàn)樘鄾_突,已經(jīng)無法輕易合并你的分支和主干的修改。
另一個問題,Subversion不會記錄任何合并操作,當(dāng)你提交本地修改,版本庫并不能判斷出你是通過svn merge還是手工修改得到這些文件。所以你必須手工記錄這些信息(說明合并的特定版本號或是版本號的范圍)。
要解決以上的問題只有通過有規(guī)律的將主干合并到分支來避免,制定這樣一個政策:每周將上周的修改合并到分支,注意這樣做時需要小心,你必須手工記錄合并的過程,以避免重復(fù)的合并,你需要小心的撰寫合并的日志信息,精確的描述合并包括的范圍。這樣做看起來有點(diǎn)像是脅迫。
SVN 的版本號是連續(xù)的版本號。每一次新的提交都會版本號+1 ,而無論這個提交是在哪個分支中進(jìn)行的。SVN一個提交可以同時修改不同分支的不同文件,因?yàn)樘峤幻羁梢栽?/trunk, /branches, /tags 的上一級目錄執(zhí)行。
SVN 的提交是單線索的,每一個提交(最原始的提交0除外)都只有一個父節(jié)點(diǎn)(版本號小一個的提交節(jié)點(diǎn))
SVN 的提交鏈只有一條,僅從版本號和提交說明,我們無法獲得分支圖
SVN 的分支圖在某些工具(如烏龜SVN)可以提供,那是需要對提交內(nèi)容進(jìn)行檢查,對目錄拷貝動作視為分支,對 svn:mergeinfo 的改動視為合并,但這會由于目錄管理的靈活性,導(dǎo)致千奇百怪的分支圖表。
2.Git的分支合并
在 git 版本庫中創(chuàng)建分支的成本幾乎為零,所以,不必吝嗇多創(chuàng)建幾個分支。當(dāng)?shù)谝淮螆?zhí)行g(shù)it-init時,系統(tǒng)就會創(chuàng)建一個名為”master”的分支。 而其它分支則通過手工創(chuàng)建。下面列舉一些常見的分支策略。
① 創(chuàng)建一個屬于自己的個人工作分支,以避免對主分支 master 造成太多的干擾,也方便與他人交流協(xié)作。
② 當(dāng)進(jìn)行高風(fēng)險的工作時,創(chuàng)建一個試驗(yàn)性的分支,扔掉一個爛攤子總比收拾一個爛攤子好得多。
③ 合并別人修改的時候,最好創(chuàng)建一個臨時的分支用來合并,合并完成后再“fatch”到自己的分支。
Git分支相關(guān)的操作命令
八、撤消操作
1.提交的撤銷
在Subversion中一旦完成向服務(wù)器的數(shù)據(jù)提交,你就沒有辦法再從客戶端追回,只能在后續(xù)的提交中修正(回退或者修改)等。因?yàn)镾ubversion作為集中式的版本控制,不能允許個人對已提交的數(shù)據(jù)進(jìn)行篡改。Subversion具有一個非常重要的特性就是它的信息從不丟失,即使當(dāng)你刪除了文件或目錄,它也許從最新版本中消失了 ,但這個對象依然存在于歷史的早期版本中。
Git則不同,Git是分布式版本控制系統(tǒng),代碼庫是屬于個人,允許任意修改。Git通過對提交建立數(shù)字摘要來保證提交的唯一性和不可更改性,通過版本庫在多人之間的多份拷貝來保障數(shù)據(jù)的安全性。Git可以丟棄最新的一個或幾個提交,使用 git reset –hard命令可以永遠(yuǎn)丟棄最新的一個或者幾個提交。
2.提交說明的修改
提交后如果對提交說明不滿意,如何實(shí)現(xiàn)對提交說明的修改:
⑴ Git可以使用命令git commit –amend修改提交說明。
Git可以修改最后一次提交說明,并不是說不能修改歷史版本的提交說明,只是修改最后一個版本提交說明擁有最簡單的命令;
Git修改提交說明,會改變提交的commit-id。即修改提交說明后,將產(chǎn)生一個新的提交;
Git可以通過git reset -hard ,git commit –amend,git rebase onto 等命令來實(shí)現(xiàn)對歷史提交的修改;
使用stg工具可以更為簡單的修改歷史提交的提交說明,包括提交內(nèi)容;
⑵ Subversion也可以修改提交說明,是通過修改提交的svn:log版本屬性實(shí)現(xiàn)的:
不但可以修改最后一次提交的說明,并且可以修改歷史提交的提交說明;
Subversion修改提交說明是不可逆的操作,可能會造成說明被惡意修改;
Subversion缺省關(guān)閉修改提交說明的功能。管理員在設(shè)置了提交說明更改的郵件通知后,才可以打開該功能。
3.修改和重構(gòu)歷史提交
Git可以修改和重構(gòu)歷史提交:使用Git本身的reset以及 rebase 命令可以修改或者重整/重構(gòu)歷史提交,非常靈活。使用強(qiáng)大的 stg 可以使得歷史提交的重構(gòu)更為簡潔,如果您對 stg 或者 Hg/MQ 熟悉的話。
Subversion 修改歷史提交,只能由管理員完成。
Subversion 是集中式版本控制系統(tǒng),從客戶端一旦完成提交,就沒有辦法從客戶端撤銷提交。但是管理員可以在服務(wù)器端完成提交的撤銷和修改,但是操作過程和代價較大。
九、權(quán)限管理
Subversion通過對文件目錄授權(quán)來實(shí)現(xiàn)權(quán)限管理,子目錄默認(rèn)繼承父目錄的權(quán)限。但是也有缺憾,即權(quán)限不能在分支中繼承,不能對單個文件授權(quán)。例如為 /trunk及其子目錄的授權(quán),不能繼承到分支或者標(biāo)簽中相應(yīng)的目錄下。
Git 的授權(quán)做不到Subversion那樣精細(xì)。Git的授權(quán)模型只能實(shí)現(xiàn)非零即壹式的授權(quán),要么擁有全部的寫權(quán)限,要么沒有寫權(quán)限,要么擁有整個版本庫的讀權(quán)限,要么禁用。
從技術(shù)上將,Git可能永遠(yuǎn)也做不到類似SVN的路徑授權(quán)(讀授權(quán)):
如果允許按照路徑授權(quán),則各個克隆的關(guān)系將不再是平等的關(guān)系,有的內(nèi)容多,有的內(nèi)容少,分布式的理念被破壞
如果只有部分路徑可讀,則克隆出來的提交和原始提交的提交ID可能不同。因?yàn)樘峤籌D是和提交內(nèi)容有關(guān)的,克隆中提交的部分內(nèi)容被丟棄,勢必提交的ID也要重新計(jì)算
允許全部代碼可讀,只允許部分代碼可寫,在版本控制的管理下,是沒有多大實(shí)際意義的,而且導(dǎo)致了提交的邏輯上的不完整。
那么有什么辦法來解決授權(quán)的問題?
1.公司內(nèi)部代碼開放。即代碼在公司內(nèi)部,對項(xiàng)目組成員一視同仁的開放。
2.公司對代碼庫進(jìn)行合理分解,對每個代碼庫分別授權(quán)。即某個代碼庫對團(tuán)隊(duì)成員完全開放,對其它團(tuán)隊(duì)完全封閉。
3.公司使用Subversion做集中式的版本控制,個人和/或團(tuán)隊(duì)使用 Git-svn。這樣在無法改變公司版本控制策略時,程序員可以采用的變通之法。
4.Git服務(wù)器的部署實(shí)際上可以使用鉤子對分支和路徑進(jìn)行寫授權(quán),即可以控制誰能夠創(chuàng)建分支,能夠?qū)懱囟ㄎ募?/p>
十、優(yōu)缺點(diǎn)比較
1.SVN優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1、 管理方便,邏輯明確,符合一般人思維習(xí)慣。
2、 易于管理,集中式服務(wù)器更能保證安全性。
3、 代碼一致性非常高。
4、 適合開發(fā)人數(shù)不多的項(xiàng)目開發(fā)。
缺點(diǎn):
1、 服務(wù)器壓力太大,數(shù)據(jù)庫容量暴增。
2、 如果不能連接到服務(wù)器上,基本上不可以工作,看上面第二步,如果服務(wù)器不能連接上,就不能提交,還原,對比等等。
3、 不適合開源開發(fā)(開發(fā)人數(shù)非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明確的權(quán)限管理機(jī)制(例如分支訪問限制),可以實(shí)現(xiàn)分層管理,從而很好的解決開發(fā)人數(shù)眾多的問題。
2.Git優(yōu)缺點(diǎn)優(yōu)點(diǎn):
1、適合分布式開發(fā),強(qiáng)調(diào)個體。
2、公共服務(wù)器壓力和數(shù)據(jù)量都不會太大。
3、速度快、靈活。
4、任意兩個開發(fā)者之間可以很容易的解決沖突。
5、離線工作。
缺點(diǎn):
1、學(xué)習(xí)周期相對而言比較長。
2、不符合常規(guī)思維。
3、代碼保密性差,一旦開發(fā)者把整個庫克隆下來就可以完全公開所有代碼和版本信息。
以上就是SVN與Git版本控制的優(yōu)缺點(diǎn)差異全面分析的詳細(xì)內(nèi)容,更多關(guān)于SVN與Gi版本控制差異分析的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
http請求405錯誤方法不被允許的解決 (Method not allowed)
這篇文章主要介紹了http請求405錯誤方法不被允許的解決 (Method not allowed),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12微信應(yīng)用號(小程序)入門安裝教程及IDE(破解版)下載
這篇文章主要介紹了微信應(yīng)用號(小程序)入門安裝教程及IDE下載的相關(guān)資料,需要的朋友可以參考下2016-09-09JetPack開發(fā)中使用CameraX完成拍照和拍視頻功能
CameraX 是一個 Google 推出的 JetPack 組件。今天給大家分享JetPack之使用CameraX完成拍照和拍視頻,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2020-06-06spark通過kafka-appender指定日志輸出到kafka引發(fā)的死鎖問題
這篇文章主要介紹了spark通過kafka-appender指定日志輸出到kafka引發(fā)的死鎖,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05超好用的免費(fèi)內(nèi)網(wǎng)穿透工具【永久免費(fèi)不限制流量】
對于開發(fā)人員來講,演示內(nèi)網(wǎng)web站點(diǎn)、本地開發(fā)微信公眾號、小程序開發(fā)、調(diào)試第三方支付系統(tǒng)對接等開發(fā)環(huán)境,往往需要一個環(huán)境可以進(jìn)行調(diào)試,市面上內(nèi)網(wǎng)穿透工具有很多,這里推薦一款簡單又好用的cpolar,可以永久免費(fèi)使用,不限制流量,支持http/https/tcp協(xié)議2022-09-09