GIT和SVN之間的差別及基本操作對比
2011-07-21 11:50:23| 分類: linux | 标簽:版本控制 git svn |舉報|字号 訂閱
1. GIT和SVN之間的五個基本差別
1)GIT是分布式的,SVN不是:
這是GIT和其它非分布式的版本控制系統,例如SVN,CVS等,最核心的差別。如果你能了解這個概念,那麼你就已經上手一半了。需要做一點聲明,GIT并不是目前第一個或唯一的分布式版本控制系統。還有一些系統,例如Bitkeeper, Mercurial等,也是運作在分布式模式上的。但GIT在這方面做的更好,而且有更多強大的功能特征。
GIT跟SVN一樣有自己的集中式版本庫或伺服器。但,GIT更傾向于被使用于分布式模式,也就是每個開發人員從中心版本庫/伺服器上chect out代碼後會在自己的機器上克隆一個自己的版本庫。可以這樣說,如果你被困在一個不能連接配接網絡的地方時,你仍然能夠送出檔案,檢視曆史版本記錄,建立項目分支等。
2)GIT把内容按中繼資料方式存儲,而SVN是按檔案:
所有的資源控制系統都是把檔案的元資訊隐藏在一個類似.svn,.cvs等的檔案夾裡。如果你把.git目錄的體積大小跟.svn比較,你會發現它們差距很大。因為,.git目錄是處于你的機器上的一個克隆版的版本庫,它擁有中心版本庫上所有的東西,例如标簽,分支,版本記錄等。
3)GIT分支和SVN的分支不同:
分支在SVN中一點不特别,就是版本庫中的另外的一個目錄。如果你想知道是否合并了一個分支,你需要手工運作像這樣的指令svn propget svn:mergeinfo,來确認代碼是否被合并。
然而,處理GIT的分支卻是相當的簡單和有趣。你可以從同一個工作目錄下快速的在幾個分支間切換。你很容易發現未被合并的分支,你能簡單而快捷的合并這些檔案。
4)GIT沒有一個全局的版本号,而SVN有:
目前為止這是跟SVN相比GIT缺少的最大的一個特征。
5)GIT的内容完整性要優于SVN:
GIT的内容存儲使用的是SHA-1雜湊演算法。這能確定代碼内容的完整性,確定在遇到磁盤故障和網絡問題時降低對版本庫的破壞。
2、SVN和GIT基本操作對比
1)倉庫建立初始化
在SVN中,倉庫本身的管理和日常應用,使用的是兩套不同的指令。倉庫的建立和備份維護等使用的指令是 svnadmin, 使用svnadmin create來建立一個新的倉庫
在git中,建立一個新的倉庫,可以在一個空目錄下,使用git init來實作,它将建立一個.git目錄用來維護倉庫資料。
在SVN中,建立倉庫的地方并不是你日常使用的倉庫的地方,你需要在别的地方checkout出特定的倉庫路徑作為你的日常工作的目錄。在git中,倉庫所在的目錄也就是你的日常工作目錄,沒有伺服器端和用戶端之分。(嚴格的說 .git目錄才是倉庫,.git目錄外的地方是你的工作目錄,對于bare project來說,隻有git目錄下的内容,工作目錄離得内容還是要checkout出來的)
2)Checkout倉庫
在SVN中,使用SVN checkout(co)來checkout本地或遠端倉庫的代碼
而對于git來說,盡管也有checkout指令,但是由于你需要在本地擁有倉庫,是以通常從伺服器上checkout代碼的第一步是使用git clone來擷取一個倉庫的拷貝,預設的git clone操作同時還會checkout一份遠端倉庫上目前active的分支
在SVN中,其倉庫的管理形式決定了你可以隻checkout倉庫中特定路徑/分支下的子目錄,而不是整個倉庫,而git隻能checkout整個分支。
3)将檔案納入版本管理
在SVN中,使用SVN add,這樣在以後的commit過程中,每次在送出資料之前,svn都會自動根據這些add過的對象的修改情況,建構一個commit tree。
在git中,因為存在index的概念,要将一個檔案納入版本管理的範疇,首先是要用git-update-index –-add将檔案納入index的監控範圍,隻有更新到index中的内容才會在commit的時候被送出。另外,檔案本身的改動并不會自動更新到index中,每次的任何修改都必須重新更新到index中去才會被送出。 當然,通常會用git add這樣的封裝腳本來調用git-update-index
4)檢查目前狀态
SVN Status 可以顯示目前working tree的檔案修改狀态
在git中 git status 指令顯示目前index的狀态和working tree的狀态。
5)送出檔案
Git commit操作在git指令中屬于相對簡單的,需要注意的一點就是上面提到的,隻有index中的内容才會比送出。
6)删除檔案
在使用Svn rm删除一個目錄的時候,因為每個目錄下都存在.svn目錄,記錄了這個目錄于伺服器端倉庫相關的資訊,是以在commit之前,目錄裡的其它檔案會被删除,但是目錄及其子目錄并不會被真正删除,隻有commit以後,目錄才會被删除。
在git中,同樣,使用git rm 删除檔案。但是git對目錄的處理有些奇怪,如果某個目錄下的所有檔案都被删除以後,該目錄就會被自動删除,也就是說你無法保留一個空的目錄。你也無法添加一個空目錄到倉庫裡。也就是說git 自動忽略空目錄,不知道這樣做的目的是什麼?
7)檢視log
svn log指令基本上就是用來檢視版本送出時的所填寫的log資訊
git log可以做的事情會多很多,畢竟git log是對底層核心指令的再包裝,通過它,不僅可以檢視log資訊,還可以輸出特定版本的具體變更内容等等資訊。
8)版本回溯
在SVN中,不提供任何從倉庫中删除對象的機制,任何的修改都會導緻版本的遞增,是以,如果想丢棄一個修改,你需要做的事是反向diff你的修改,再送出一個新的版本。
在git中提供了重置committed tree對象索引的機制,是以,你可以通過例如git-reset這樣的操作将目前分支的版本恢複到以前的某個狀态。經常看見的例子就是回溯一個版本,然後修改内容,再次送出。不過這樣做搞不好很容易出問題。包括在git-push之類的操作時會被reject,需要強行push之類的。
如果隻是想放棄一個修改,git的文檔推薦使用git-revert操作,這個操作基本上和SVN的思路是一樣的了,就是送出一個新的版本将需要revert的版本的内容再反向修改回去,版本會遞增,不影響之前送出的内容。
9)放棄目前修改
在SVN中,使用SVN revert對目錄或檔案操作都可以将目前工作樹上特定路徑的修改恢複到伺服器上的版本,放棄目前的修改。
Git中,對特定檔案使用不帶其它參數的git checkout指令可以将檔案恢複到index中的狀态,如果你想恢複的特定的版本,那麼類似: git checkout HEAD file這樣的操作,将檔案恢複到HEAD tree即最近一次送出的狀态。
不過git checkout有個問題,不知道是否是故意這樣設計的,就是即使用git rm删除的内容,如果沒有送出,git checkout以後也會恢複,包括它在index中的狀态。這點有些不了解。 理論上index上已經記錄這個删除操作,不應該恢複才對。
Git中還有一種辦法,可以快速徹底的放棄自從上次commit以來的所有變更,git reset –hard HEAD
10)代碼合并
git merge能夠自動記住以前merge過的位置和狀态,這個比較容易了解,因為通過每個分支的head commit可以跟蹤它的對象索引關系。另外,因為其對象管理機制的原因,隻能以commit為機關,merge整個分支的所有修改。不能有選擇的merge部分路徑下的修改。Merge的時候要求index和HEAD是一緻的,如果merge成功,内容會直接commit,而工作樹上的修改仍會保持。(如果失敗,會在工作樹上将需要merge的内容和你已有的修改合并,大概不是你所希望的,是以最好不要這樣做)
merge特定分支的特定版本之前的所有修改,可以通過merge那個版本對應的rev來實作,merge某一段版本區間的修改,考慮到commit需要完整的代碼樹關系,估計靠git merge來做是沒有辦法了,需要自己diff / patch代碼來實作
SVN的Merge操作不會記住它的merge曆史,換句話說,你可以多次merge同一份代碼,但是他的好處是你可以自由的選擇merge哪一部分、哪一段版本之間的代碼,應該說他基本等同于是diff和patch的組合。不過因為SVN沒有index的概念,是以merge的操作會和目前working tree上的修改合并在一起。
關于曆史資訊方面,因為svn的merge實際是patch檔案内容本身,是以,不同分支上的曆史資訊不會在merge以後的主幹上展現出來,而git的merge,如果沒有沖突的話,實際是merge commit樹的繼承關系,是以,所有的曆史資訊在merge以後的commit中都能夠被索引到。
11)擷取單純的代碼
在svn中,如果不需要任何曆史資訊,隻想要某個版本純粹的代碼(經常會有這種需求,這樣做本地資料比較小) 那麼,使用svn export指令即可以實作。
在git中,似乎沒有這樣的指令,不過,由于git的本地倉庫資訊完全維護在project根目錄的.git目錄下,(不像svn一樣,每個子目錄下都有單獨的.svn目錄)。是以,隻要clone,checkout然後删除.git目錄就可以了。
參考文章:
對比SVN學習GIT版本管理工具 http://blog.csdn.net/colorant/article/details/3193820
GIT和SVN之間的五個基本差別 http://www.aqee.net/2010/10/20/5-fundamental-differences-between-git-svn/
原文出處 http://wuzhangshu927.blog.163.com/blog/static/1142246872011621113641834/