1. 程式人生 > >git與svn的簡介與區別

git與svn的簡介與區別

  

目錄:

 

一、 集中式vs分散式

 

1. Subversion屬於集中式的版本控制系統
集中式的版本控制系統都有一個單一的集中管理的伺服器,儲存所有檔案的修訂版本,而協同工作的人們都通過客戶端連到這臺伺服器,取出最新的檔案或者提交更新。

 

 

Subversion的特點概括起來主要由以下幾條:

  •  每個版本庫有唯一的URL(官方地址),每個使用者都從這個地址獲取程式碼和資料;
  •  獲取程式碼的更新,也只能連線到這個唯一的版本庫,同步以取得最新資料;
  •  提交必須有網路連線(非本地版本庫);
  •  提交需要授權,如果沒有寫許可權,提交會失敗;
  •  提交併非每次都能夠成功。如果有其他人先於你提交,會提示“改動基於過時的版本,先更新再提交”… 諸如此類;
  •  衝突解決是一個提交速度的競賽:手快者,先提交,平安無事;手慢者,後提交,可能遇到麻煩的衝突解決。

 

好處:每個人都可以一定程度上看到專案中的其他人正在做些什麼。而管理員也可以輕鬆掌控每個開發者的許可權。

缺點:中央伺服器的單點故障。

若是宕機一小時,那麼在這一小時內,誰都無法提交更新、還原、對比等,也就無法協同工作。如果中央伺服器的磁碟發生故障,並且沒做過備份或者備份得不夠及時的話,還會有丟失資料的風險。最壞的情況是徹底丟失整個專案的所有歷史更改記錄,被客戶端提取出來的某些快照資料除外,但這樣的話依然是個問題,你不能保證所有的資料都已經有人提取出來。

 

Subversion原理上只關心檔案內容的具體差異。每次記錄有哪些檔案作了更新,以及都更新了哪些行的什麼內容。

 

2. Git屬於分散式的版本控制系統

 

Git記錄版本歷史只關心檔案資料的整體是否發生變化。Git 不儲存檔案內容前後變化的差異資料。

實際上,Git 更像是把變化的檔案作快照後,記錄在一個微型的檔案系統中。每次提交更新時,它會縱覽一遍所有檔案的指紋資訊並對檔案作一快照,然後儲存一個指向這次快照的索引。為提高效能,若檔案沒有變化,Git 不會再次儲存,而只對上次儲存的快照作一連線。

 

在分散式版本控制系統中,客戶端並不只提取最新版本的檔案快照,而是把原始的程式碼倉庫完整地映象下來。這麼一來,任何一處協同工作用的伺服器發生故障,事後都可以用任何一個映象出來的本地倉庫恢復。這類系統都可以指定和若干不同的遠端程式碼倉庫進行互動。籍此,你就可以在同一個專案中,分別和不同工作小組的人相互協作。你可以根據需要設定不同的協作流程。


另外,因為Git在本地磁碟上就儲存著所有有關當前專案的歷史更新,並且Git中的絕大多數操作都只需要訪問本地檔案和資源,不用連網,所以處理起來速度飛快。用SVN的話,沒有網路或者斷開VPN你就無法做任何事情。但用Git的話,就算你在飛機或者火車上,都可以非常愉快地頻繁提交更新,等到了有網路的時候再上傳到遠端的映象倉庫。換作其他版本控制系統,這麼做幾乎不可能,抑或是非常麻煩。

 

Git具有以下特點:

  • Git中每個克隆(clone)的版本庫都是平等的。你可以從任何一個版本庫的克隆來建立屬於你自己的版本庫,同時你的版本庫也可以作為源提供給他人,只要你願意。

  • Git的每一次提取操作,實際上都是一次對程式碼倉庫的完整備份。

  • 提交完全在本地完成,無須別人給你授權,你的版本庫你作主,並且提交總是會成功。

  • 甚至基於舊版本的改動也可以成功提交,提交會基於舊的版本建立一個新的分支。

  • Git的提交不會被打斷,直到你的工作完全滿意了,PUSH給他人或者他人PULL你的版本庫,合併會發生在PULL和PUSH過程中,不能自動解決的衝突會提示您手工完成。

  • 衝突解決不再像是SVN一樣的提交競賽,而是在需要的時候才進行合併和衝突解決。

  • Git 也可以模擬集中式的工作模式

  • Git版本庫統一放在伺服器中

  • 可以為 Git 版本庫進行授權:誰能建立版本庫,誰能向版本庫PUSH,誰能夠讀取(克隆)版本庫

  • 團隊的成員先將伺服器的版本庫克隆到本地;並經常的從伺服器的版本庫拉(PULL)最新的更新;

  • 團隊的成員將自己的改動推(PUSH)到伺服器的版本庫中,當其他人和版本庫同步(PULL)時,會自動獲取改變

  • Git 的集中式工作模式非常靈活

  • 你完全可以在脫離Git伺服器所在網路的情況下,如移動辦公/出差時,照常使用程式碼庫

  • 你只需要在能夠接入Git伺服器所在網路時,PULL和PUSH即可完成和伺服器同步以及提交

  • Git提供 rebase 命令,可以讓你的改動看起來是基於最新的程式碼實現的改動

  • Git 有更多的工作模式可以選擇,遠非 Subversion可比

 

 

二、 版本庫與工作區

 

Subversion的工作區和版本庫是截然分開的,而Git的工作區和版本庫是如影隨形的。

 

1. SVN的版本庫和工作區是分離的
• Subversion 的工作區和版本庫物理上分開:Subversion的版本庫和工作區是儲存在不同路徑下,一般是在不同的主機中,Subversion的企業級部署中,版本庫在伺服器上,只能通過 https, http, svn 等協議訪問,而不能直接被使用者接觸到。
• Subversion的工作區是一份版本庫在某個歷史狀態下的快照,如:版本庫最新的資料檢出到工作區。
• Subversion的工作區中每一個目錄下都包含一個名為 .svn 的控制目錄(隱藏的目錄),該目錄的作用是:
① 標識工作區和版本庫的對應關係。
② 包含一份該子目錄下檢出檔案的原始拷貝。當檔案改動的差異比較或者本地改動的回退時,可以直接參考原始拷貝而無須通過網路訪問遠端版本庫。
• Subversion 的 .svn 控制目錄會引入很多麻煩:
① .svn 下的檔案原始考本,會導致在目錄下按照檔案內容搜尋時,多出一倍的搜尋時間和搜尋結果。
② .svn 很容易在整合時,引入產品中,尤其是 Web 應用,將 .svn 目錄帶入Web伺服器會導致安全隱患。因為一個不允許目錄瀏覽的Web目錄,可以通過 .svn/entries 檔案檢視到該目錄下可能存在的檔案。

 

2 .Git 的版本庫和工作區如影隨形

• Git 的版本庫和工作區在同一個目錄下,工作區的根目錄有一個.git的子目錄,這個名為 .git的目錄就是版本庫本身,它是Git 用來儲存元資料和物件資料庫的地方。該目錄非常重要,每次克隆映象倉庫的時候,實際拷貝的就是這個目錄裡面的資料。所以千萬要小心刪除這個檔案。
• 工作區中其他檔案為工作區檔案,可能是從 .git 中檢出的,或者是要檢入的,或者是執行產生的臨時檔案等。

• 版本庫可以脫離工作區而存在,成為 bare(赤裸)版本庫。可以用 –bare 引數來建立。但是工作區不能脫離版本庫而存在,即工作區的根目錄下必須有一個名為 .git 的版本庫克隆檔案。
• Git 的版本庫因為就在工作區中,能直接被使用者接觸到。
① 使用者可以編輯 .git/config 檔案,修改配置,增添新的源
② 使用者可以編輯 .git/info/exclude 檔案,建立本地忽略…

• Git 的工作區中只在工作區的根目錄下有一個 .git 目錄,此外再無任何控制目錄。Git 工作區下唯一的 .git 目錄是版本庫,並非 .svn 的等價物,如果刪除了 .git 目錄,而又沒有該版本庫的其他映象(克隆)的話,你破壞了整個歷史,版本庫也永遠的失去了。
• Git 在本地的 .git 版本庫,提供了完全的改動歷史。除了和其他人資料交換外,任何版本庫相關的操作都在本地完成,更多的本地操作,避免了冗長的網路延遲,大大節省了時間。例如:檢視 log,切換到任何歷史版本等操作都無須連線網路。

• Git如何保證安全:本地建立一個Git庫,因為工作區和庫是在同一個目錄中,如果工作區刪除了,或者所在的磁碟分割槽格式化了,資料不是全都沒有了麼?其實我們可以這樣做:
① 在一個磁碟分割槽中建立版本庫(最好是用 –bare 引數建立),然後在另外的磁碟分割槽中克隆一個新的作為工作區。在工作區的提交要不時的PUSH到另外分割槽的版本庫,這樣就實現了本地的資料映象。你甚至可以在本地建立更多的版本庫映象,安全性要比Subversion的一個庫加上一個工作區安全。
② 另一個辦法:把你的版本庫共享給他人,當他人克隆了你的版本庫時,你就擁有了一個異地備份。

 

 

三、 全域性版本號和全球版本號

 

SVN的全域性版本號和CVS的每個檔案都獨立維護一套版本號相比,是一個非常大的進步。在看似簡單的全域性版本號的背後,是Subversion提供對於事物處理的支援,每一個事物處理(即一次提交)都具有整個版本庫全域性唯一的版本號。

Git的版本號則更進一步,版本號是全球唯一的。Git 對於每一次提交,通過對檔案的內容或目錄的結構計算出一個SHA-1 雜湊值,得到一個40位的十六進位制字串,Git將此字串作為版本號。

 

1. SVN與Git版本號比較

• 所有儲存在Git 資料庫中的資料都是用此40位的雜湊值作索引的,而不是靠檔名。
• 使用雜湊值作版本號的好處就是對於一個分散式的版本控制系統,每個人每次提交後形成的版本號都不會出現重複。另一好處是保證資料的完整性,因為雜湊值是根據內容或目錄結構計算出來的,所以我們還可以據此來判斷資料內容是否被篡改。

• SVN 的版本號是連續的,可以預判下一個版本號,而 Git 的版本號則不是。

因為 subversion 是集中式版本控制,很容易實現版本號的連續性。Git 是分散式的版本控制系統,而且 Git 採用 40 位長的雜湊值作為版本號,每個人的提交都是各自獨立完成的,沒有先後之分(即使提交有先後之分,也由於PUSH/PULL的方向和時機而不同)。Git 的版本號雖然不連續,但是是有線索的,即每一個版本都有對應的父版本(一個或者兩個),進而可以形成一個複雜的提交鏈

• Git 的版本號簡化:Git 可以使用從左面開始任意長度的字串作為簡化版本號,只要該簡化的版本號不產生歧義。一般採用7位的短版本號(只要不會出現重複的,你也可以使用更短的版本號)。

 

 

四、 部分檢出

 

Subversion可以將整個庫檢出到工作區,也可以將某個目錄檢出到工作區。對於要使用一個龐大、臃腫的版本庫的使用者來說,部分檢出是非常方便和實際的。
但是Git只能全部檢出,不支援按照目錄進行的部分檢出。

 

1. SVN的部分檢出

• 在SVN中,從倉庫checkout的一個工作樹,每個子目錄下都維護著自己的.svn目錄,記錄著該目錄中檔案的修改情況以及和伺服器端倉庫的對應關係。所以SVN可以checkout部分路徑下的內容(部分檢出),而不用checkout整個版本庫或分支。

• Subversion 有一條命令:svn export ,可以將 subversion 版本庫的一個目錄下所有內容匯出到指定的目錄下。Subversion 需要 svn export 命令是因為該命令可以匯出一個乾淨的目錄,即不包含 .svn 目錄(包含配置檔案和檔案原始拷貝)。

 

2. Git的檢出

• Git 沒有部分檢出,這並不是說只有將整個庫克隆下來才能檢視檔案。有很多 git 工具,提供直接瀏覽git庫的功能,例如 gitweb, trac 的 git 版本庫瀏覽, redmine 的 git 版本庫瀏覽。

• Git-submodule 可以實現版本庫的模組化:Git 通過子模組處理這個問題。
子模組允許你將一個Git 倉庫當作另外一個Git倉庫的子目錄。這允許你克隆另外一個倉庫到你的專案中並且保持你的提交相對獨立。

• Git 為什麼沒有實現 svn export 的功能?由於git的本地倉庫資訊完全維護在project根目錄的.git目錄下,(不像svn一樣,每個子目錄下都有單獨的.svn目錄)。所以,只要clone,checkout然後刪除.git目錄就可以了。

 

五、 更新和提交


1.更新操作

在SVN中,因為只有一箇中心倉庫,所以所謂的遠端更新,也就是svn update ,通過此命令來使工作區和版本庫保持同步。
對於git來說,別人的改動是存在於遠端倉庫上的,所以git checkout命令儘管在某些功能上和svn中的update類似(例如取倉庫特定版本的內容),但是在遠端更新這一點上,還是不同的,不屬於git checkout的功能涵蓋範圍。 Git使用git fetch和git pull來完成遠端更新任務,fetch操作只是將遠端資料庫的object拷貝到本地,然後更新remotes head的refs,git pull 的操作則是在git fetch的基礎上對當前分支外加merge操作。

 

2.SVN中的commit命令

對於SVN來說,由於是中心式的倉庫管理形式,所以並不存在特殊的遠端提交的概念,所有的commit操作都可以認為是對遠端倉庫的更新動作。在工作區中對檔案進行新增、修改、刪除操作要同步到版本庫,必須使用 commit命令。
• add 命令,是將未標記為版本控制狀態的檔案標記為新增狀態,並在下次提交時入庫。
• delete命令,是通過SVN來刪除檔案,並在下次提交後有效。
• Subversion 有提交列表功能,即將某些檔案加入一個修改列表,提交可以只提交處於該列表的檔案。

 

3.Git中的暫存區域(stage)

Git 管理專案時,檔案在三個工作區域中流轉:Git 的本地資料目錄,工作目錄以及暫存區域。暫存區域(stage)是介於 workcopy 和 版本庫  HEAD 版本的一種中間狀態。所謂的暫存區域只不過是個簡單的檔案,一般都放在git 目錄中。有時候人們會把這個檔案叫做索引檔案,不過標準說法還是叫暫存區域。

要將一個檔案納入版本管理的範疇,首先是要用git  add將檔案納入stage的監控範圍,只有更新到stage中的內容才會在commit的時候被提交。另外,檔案本身的改動並不會自動更新到stage中,每次的任何修改都必須重新更新到stage中去才會被提交。對於工作區直接刪除的檔案,需要用 git rm 命令進行標記,在下次提交時,在版本庫中刪除。

• 工作區的檔案改動(新增檔案,修改檔案,刪除檔案),必須用 git add 或者 git rm 命令標識,使得改動進入 stage
• 提交只對加入 stage 的改動進行提交
• 如果一個檔案改動加入 stage 後再次改動,則後續改動不改變 stage。即該檔案的改動有兩個狀態,一個是標記到 stage 中並將在下次提交時入庫的改動,另外的後續改動則不被提交,除非再次使用 git add 命令將改動加入到 stage 中。
• Git的stag讓你在提交的時候清楚的知道git將要提交哪些改動。除非提交的時候使用 -a 引數(不建議使用)。

 

我們可以從檔案所處的位置來判斷其狀態:如果是git目錄中儲存著的特定版本檔案,就屬於已提交狀態;如果作了修改並已放入暫存區域,就屬於已暫存狀態;如果自上次取出後,作了修改但還沒有放到暫存區域,就是已修改狀態,如果取出後未進行修改則是未修改狀態。

在git中,因為有本地倉庫和remote倉庫之分,所以也就區別於commit 操作,存在額外的push命令,用於將本地倉庫的資料更新到遠端倉庫中去。git push 可以選擇需要提交的、更新的分支以及制定該分支在遠端倉庫上的名字。

 

六、 分支和里程碑的實現

 

幾乎每一種版本控制系統都以某種形式支援分支。使用分支意味著你可以從開發主線上分離開來,然後在不影響主線的同時繼續工作。在很多版本控制系統中,這是個昂貴的過程,常常需要建立一個原始碼目錄的完整副本,對大型專案來說會花費很長時間。

輕量級分支/里程碑的含義是,建立分支/里程碑的複雜度是o(1),不會因為版本庫的愈加龐大而變得緩慢。在CVS中,建立分支的複雜度是o(n)的,導致大的版本庫的的分支建立非常緩慢。

 

1.Subversion的分支/里程碑

Subversion輕量級分支和里程碑的實現是通過svn cp命令,即帶歷史的拷貝就是建立快速建立分支和里程碑的祕籍。Subversion的版本庫有特殊的設計,當你複製一個目錄,你不需要擔心版本庫會變得十分巨大—Subversion並不是拷貝所有的資料,相反,它只是建立了一個已存在目錄樹的入口。這種“廉價的拷貝”就是建立分支/里程碑是輕量級的原因。
由於Svn的分支和標籤是來自目錄拷貝,約定俗成是拷貝在 branches/和tags/目錄下。所謂分支,tag等概念都只是倉庫中不同路徑上的一個物件或索引而已,和普通的路徑並沒有什麼本質的區別,誰也不能阻止在一個提交中同時修改不同分支中的資料。
里程碑是對某個歷史提交所起的一個別名,作為歷史的標記,是不應該被更改的。svn的里程碑要建立到 tags/目錄下,要求不要在tags/下的里程碑目錄下進行提交。但是誰也阻止不了對未進行許可權控制的里程碑的篡改。

 

2.Git 的輕量級分支和里程碑

Git中的分支實際上僅是一個包含所指物件校驗和(40個字元長度SHA-1 雜湊值)的檔案,所以建立和銷燬一個分支就變得非常廉價。說白了,新建一個分支就是向一個檔案寫入41個位元組(版本號外加一個換行符)那麼簡單,自然速度就很快了。 Git的實現與專案複雜度無關,它永遠可以在幾毫秒的時間內完成分支的建立和切換。這和大多數版本控制系統形成了鮮明對比。

Git的分支是完全隔離的,而Subversion則沒有。分支本來就應該是相對獨立的名稱空間,一個提交一般只能發生在一個分支中。在Git中,其內部的物件層級依賴關係或許和SVN類似,但是其工作樹的視圖表現形式和SVN完全不同。工作樹永遠是一個完整的分支,不同的分支由不同的head索引去構建,你不可能在工作樹中同時獲得多個分支的內容。

Git使用的標籤有兩種型別:輕量級的(lightweight)和含附註的(annotated)。① 輕量級標籤就像是個不會變化的分支,實際上它就是個指向特定提交物件的引用。② 而含附註標籤,實際上是儲存在倉庫中的一個獨立物件,它有自身的校驗和資訊,包含著標籤的名字,電子郵件地址和日期,以及標籤說明,標籤本身也允許使用GNU Privacy Guard (GPG) 來簽署或驗證。

Git的里程碑是隻讀的,Git完全遵守歷史不可更改這一時空法則。使用者不能向git的里程碑中提交,否則里程碑就不是標記,而成了一個分支。當然Git允許使用者刪除里程碑再重新建立指定到不同歷史提交。

 

3.多分支間的切換

SVN中提供了一個功能switch,使用switch可以在同一個工作樹上,在不同的分支中進行切換。
Git在分支中進行切換使用的命令是checkout。

 

 

七、 分支與合併

 

Git 和 Svn 的分支實現機制完全的不同,這也直接導致了 SVN 在分支合併中困難重重。儘管在 SVN 1.5 之後,通過 svn:mergeinfo 屬性引入了合併追蹤機制,但是在特定情況下,合併仍會出現很多困難。

 

1. SVN的分支合併

當你在一個分支上工作數週或幾個月之後,主幹的修改也同時在進行著,兩條線的開發會區別巨大,當你想合併分支回主幹,可能因為太多衝突,已經無法輕易合併你的分支和主幹的修改。

另一個問題,Subversion不會記錄任何合併操作,當你提交本地修改,版本庫並不能判斷出你是通過svn merge還是手工修改得到這些檔案。所以你必須手工記錄這些資訊(說明合併的特定版本號或是版本號的範圍)。

要解決以上的問題只有通過有規律的將主幹合併到分支來避免,制定這樣一個政策:每週將上週的修改合併到分支,注意這樣做時需要小心,你必須手工記錄合併的過程,以避免重複的合併,你需要小心的撰寫合併的日誌資訊,精確的描述合併包括的範圍。這樣做看起來有點像是脅迫。

SVN 的版本號是連續的版本號。每一次新的提交都會版本號+1 ,而無論這個提交是在哪個分支中進行的。SVN一個提交可以同時修改不同分支的不同檔案,因為提交命令可以在 /trunk, /branches, /tags 的上一級目錄執行。

• SVN 的提交是單線索的,每一個提交(最原始的提交0除外)都只有一個父節點(版本號小一個的提交節點)
• SVN 的提交鏈只有一條,僅從版本號和提交說明,我們無法獲得分支圖
• SVN 的分支圖在某些工具(如烏龜SVN)可以提供,那是需要對提交內容進行檢查,對目錄拷貝動作視為分支,對 svn:mergeinfo 的改動視為合併,但這會由於目錄管理的靈活性,導致千奇百怪的分支圖表。

 

2.Git的分支合併

在 git 版本庫中建立分支的成本幾乎為零,所以,不必吝嗇多建立幾個分支。當第一次執行git-init時,系統就會建立一個名為”master”的分支。 而其它分支則通過手工建立。下面列舉一些常見的分支策略。 

① 建立一個屬於自己的個人工作分支,以避免對主分支 master 造成太多的干擾,也方便與他人交流協作。 
② 當進行高風險的工作時,建立一個試驗性的分支,扔掉一個爛攤子總比收拾一個爛攤子好得多。 
③ 合併別人修改的時候,最好建立一個臨時的分支用來合併,合併完成後再“fatch”到自己的分支。

Git分支相關的操作命令

 

 

八、 撤消操作


1.提交的撤銷

在Subversion中一旦完成向伺服器的資料提交,你就沒有辦法再從客戶端追回,只能在後續的提交中修正(回退或者修改)等。因為Subversion作為集中式的版本控制,不能允許個人對已提交的資料進行篡改。Subversion具有一個非常重要的特性就是它的資訊從不丟失,即使當你刪除了檔案或目錄,它也許從最新版本中消失了 ,但這個物件依然存在於歷史的早期版本中。
Git則不同,Git是分散式版本控制系統,程式碼庫是屬於個人,允許任意修改。Git通過對提交建立數字摘要來保證提交的唯一性和不可更改性,通過版本庫在多人之間的多份拷貝來保障資料的安全性。Git可以丟棄最新的一個或幾個提交,使用 git reset –hard命令可以永遠丟棄最新的一個或者幾個提交。

 

2.提交說明的修改

提交後如果對提交說明不滿意,如何實現對提交說明的修改:
⑴ Git可以使用命令git commit –amend修改提交說明。
• Git可以修改最後一次提交說明,並不是說不能修改歷史版本的提交說明,只是修改最後一個版本提交說明擁有最簡單的命令;
• Git修改提交說明,會改變提交的commit-id。即修改提交說明後,將產生一個新的提交;
• Git可以通過git reset –hard ,git commit –amend,git rebase onto 等命令來實現對歷史提交的修改;
• 使用stg工具可以更為簡單的修改歷史提交的提交說明,包括提交內容;
⑵ Subversion也可以修改提交說明,是通過修改提交的svn:log版本屬性實現的:
• 不但可以修改最後一次提交的說明,並且可以修改歷史提交的提交說明;
• Subversion修改提交說明是不可逆的操作,可能會造成說明被惡意修改;
• Subversion預設關閉修改提交說明的功能。管理員在設定了提交說明更改的郵件通知後,才可以開啟該功能。

 

3.修改和重構歷史提交

Git可以修改和重構歷史提交:使用Git本身的reset以及 rebase 命令可以修改或者重整/重構歷史提交,非常靈活。使用強大的 stg 可以使得歷史提交的重構更為簡潔,如果您對 stg 或者 Hg/MQ 熟悉的話。
Subversion 修改歷史提交,只能由管理員完成。
Subversion 是集中式版本控制系統,從客戶端一旦完成提交,就沒有辦法從客戶端撤銷提交。但是管理員可以在伺服器端完成提交的撤銷和修改,但是操作過程和代價較大。

 

九、 許可權管理

 

Subversion通過對檔案目錄授權來實現許可權管理,子目錄預設繼承父目錄的許可權。但是也有缺憾,即許可權不能在分支中繼承,不能對單個檔案授權。例如為 /trunk及其子目錄的授權,不能繼承到分支或者標籤中相應的目錄下。

Git 的授權做不到Subversion那樣精細。Git的授權模型只能實現非零即壹式的授權,要麼擁有全部的寫許可權,要麼沒有寫許可權,要麼擁有整個版本庫的讀許可權,要麼禁用。


從技術上將,Git可能永遠也做不到類似SVN的路徑授權(讀授權):

• 如果允許按照路徑授權,則各個克隆的關係將不再是平等的關係,有的內容多,有的內容少,分散式的理念被破壞

• 如果只有部分路徑可讀,則克隆出來的提交和原始提交的提交ID可能不同。因為提交ID是和提交內容有關的,克隆中提交的部分內容被丟棄,勢必提交的ID也要重新計算

• 允許全部程式碼可讀,只允許部分程式碼可寫,在版本控制的管理下,是沒有多大實際意義的,而且導致了提交的邏輯上的不完整。

那麼有什麼辦法來解決授權的問題?

1. 公司內部程式碼開放。即程式碼在公司內部,對專案組成員一視同仁的開放。

2. 公司對程式碼庫進行合理分解,對每個程式碼庫分別授權。即某個程式碼庫對團隊成員完全開放,對其它團隊完全封閉。

3. 公司使用Subversion做集中式的版本控制,個人和/或團隊使用 Git-svn。這樣在無法改變公司版本控制策略時,程式設計師可以採用的變通之法。

4. Git伺服器的部署實際上可以使用鉤子對分支和路徑進行寫授權,即可以控制誰能夠建立分支,能夠寫特定檔案。

 

 

十、優缺點比較

 

1.SVN優缺點

優點: 

1、 管理方便,邏輯明確,符合一般人思維習慣。 

2、 易於管理,集中式伺服器更能保證安全性。 

3、 程式碼一致性非常高。 

4、 適合開發人數不多的專案開發。 

缺點: 

1、 伺服器壓力太大,資料庫容量暴增。 

2、 如果不能連線到伺服器上,基本上不可以工作,看上面第二步,如果伺服器不能連線上,就不能提交,還原,對比等等。 

3、 不適合開源開發(開發人數非常非常多,但是Google app engine就是用svn的)。但是一般集中式管理的有非常明確的許可權管理機制(例如分支訪問限制),可以實現分層管理,從而很好的解決開發人數眾多的問題。

 

2.Git優缺點
優點: 

1、適合分散式開發,強調個體。 

2、公共伺服器壓力和資料量都不會太大。 

3、速度快、靈活。 

4、任意兩個開發者之間可以很容易的解決衝突。 

5、離線工作。 

缺點: 

1、學習週期相對而言比較長。 

2、不符合常規思維。 

3、程式碼保密性差,一旦開發者把整個庫克隆下來就可以完全公開所有程式碼和版本資訊。