特點
分散式相比於集中式的最大區別在於開發者可以提交到本地,每個開發者通過克隆(gitclone),在本地機器上拷貝一個完整的Git倉庫。下圖是經典的git開發過程。
Git的功能特性:
從一般開發者的角度來看,git有以下功能:
1、從伺服器上克隆完整的Git倉庫(包括代碼和版本信息)到單機上。
2、在自己的機器上根據不同的開發目的,創建分支,修改代碼。
3、在單機上自己創建的分支上提交代碼。
4、在單機上合併分支。
5、把伺服器上最新版的代碼fetch下來,然後跟自己的主分支合併。
6、生成補丁(patch),把補丁傳送給主開發者。
7、看主開發者的反饋,如果主開發者發現兩個一般開發者之間有衝突(他們之間可以合作解決的衝突),就會要求他們先解決衝突,然後再由其中一個人提交。如果主開發者可以自己解決,或者沒有衝突,就通過。
8、一般開發者之間解決衝突的方法,開發者之間可以使用pull命令解決衝突,解決完衝突之後再向主開發者提交補丁。
從主開發者的角度(假設主開發者不用開發代碼)看,git有以下功能:
1、查看郵件或者通過其它方式查看一般開發者的提交狀態。
2、打上補丁,解決衝突(可以自己解決,也可以要求開發者之間解決以後再重新提交,如果是開源項目,還要決定哪些補丁有用,哪些不用)。
3、向公共伺服器提交結果,然後通知所有開發人員。
優點:
適合分散式開發,強調個體。
公共伺服器壓力和數據量都不會太大。
速度快、靈活。
任意兩個開發者之間可以很容易的解決衝突。
離線工作。
缺點:
資料少(起碼中文資料很少)。
學習周期相對而言比較長。
不符合常規思維。
代碼保密性差,一旦開發者把整個庫克隆下來就可以完全公開所有代碼和版本信息。
歷史
Git誕生於一個極富紛爭大舉創新的年代。Linux核心開源項目有著為數眾廣的參與者。絕大多數的Linux核心維護工作都花在了提交補丁和保存歸檔的繁瑣事務上(1991-2002年間)。到2002年,整個項目組開始啟用分散式版本控制系統BitKeeper來管理和維護代碼。
然而,到2005年的時候,開發BitKeeper的商業公司同Linux核心開源社區的合作關係結束,他們決定收回免費使用BitKeeper的權力。
這就迫使Linux開源社區(特別是Linux的締造者LinusTorvalds)不得不吸取教訓。只有開發一套屬於自己的版本控制系統才不至於重蹈覆轍。
他們對新的系統制定了若干目標:
*速度
*簡單的設計
*對非線性開發模式的強力支持(允許上千個並行開發的分支)
*完全分散式
*有能力高效管理類似Linux核心一樣的超大規模項目(速度和數據量)
2005年,Git誕生了。
簡介
Git 是 Linux Torvalds 為了幫助管理 Linux 核心開發而開發的一個開放源碼的分散式版本控制軟體,它不同於Subversion、CVS這樣的集中式版本控制系統。
在集中式版本控制系統中只有一個倉庫(repository),許多個工作目錄(working copy),而像Git這樣的分散式版本控制系統中(其他主要的分散式版本控制系統還有BitKeeper、Mercurial、GNU Arch、Bazaar、Darcs、SVK、Monotone等),每一個工作目錄都包含一個完整倉庫,它們可以支持離線工作,本地提交可以稍後提交到伺服器上。
分散式系統理論上也比集中式的單伺服器系統更健壯,單伺服器系統一旦伺服器出現問題整個系統就不能運行了,分散式系統通常不會因為一兩個節點而受到影響。
基礎要點
Git在保存和處理各種信息的時候,雖然操作起來的命令形式非常相近,但它與其他版本控制系統的做法頗為不同。
直接快照,而非比較差異
Git和其他版本控制系統的主要差別在於,Git只關心檔案數據的整體是否發生變化,而大多數其他系統則只關心檔案內容的具體差異。這類系統(CVS,Subversion,perforce,Bazaar等等)每次記錄有哪些檔案作了更新,以及都更新了哪些行的什麼內容。
Git並不保存這些前後變化的差異數據。實際上,Git更像是把變化的檔案作快照後,記錄在一個微型的檔案系統中。每次提交更新時,它會縱覽一遍所有檔案的指紋信息並對檔案作一快照,然後保存一個指向這次快照的索引。為提高性能,若檔案沒有變化,Git不會再次保存,而只對上次保存的快照作一連線。
這是Git同其他系統的重要區別。它完全顛覆了傳統版本控制的套路,並對各個環節的實現方式作了新的設計。Git更像是個小型的檔案系統,但它同時還提供了許多以此為基礎的超強工具,而不只是一個簡單的VCS。稍後在第三章討論Git分支管理的時候,我們會再看看這樣的設計究竟會帶來哪些好處。
幾乎所有操作都可本地執行
在Git中的絕大多數操作都只需要訪問本地檔案和資源,不用連網。但如果用CVCS的話,差不多所有操作都需要連線網路。因為Git在本地磁碟上就保存著所有有關當前項目的歷史更新,所以處理起來速度飛快。
舉個例子,如果要瀏覽項目的歷史更新摘要,Git不用跑到外面的伺服器上去取數據回來,而直接從本地資料庫讀取後展示給你看。所以任何時候你都可以馬上翻閱,無需等待。如果想要看當前版本的檔案和一個月前的版本之間有何差異,Git會取出一個月前的快照和當前檔案作一次差異運算,而不用請求遠程伺服器來做這件事,或是把老版本的檔案拉到本地來作比較。
用CVCS的話,沒有網路或者斷開VPN你就無法做任何事情。但用Git的話,就算你在飛機或者火車上,都可以非常愉快地頻繁提交更新,等到了有網路的時候再上傳到遠程的鏡像倉庫。同樣,在回家的路上,不用連線VPN你也可以繼續工作。換作其他版本控制系統,這么做幾乎不可能,抑或非常麻煩。比如Perforce,如果不連到伺服器,幾乎什麼都做不了(譯註:實際上手工修改檔案許可權改為可寫之後是可以編輯檔案的,只是其他開發者無法通過Perforce知道你正在對此檔案進行修改。);如果是Subversion或CVS,雖然可以編輯檔案,但無法提交更新,因為資料庫在網路上。看上去好像這些都不是什麼大問題,但在實際體驗過之後,你就會驚喜地發現,這其實是會帶來很大不同的。
時刻保持數據完整性
在保存到Git之前,所有數據都要進行內容的校驗和(checksum)計算,並將此結果作為數據的唯一標識和索引。換句話說,不可能在你修改了檔案或目錄之後,Git一無所知。這項特性作為Git的設計哲學,建在整體架構的最底層。所以如果檔案在傳輸時變得不完整,或者磁碟損壞導致檔案數據缺失,Git都能立即察覺。
Git使用SHA-1算法計算數據的校驗和,通過對檔案的內容或目錄的結構計算出一個SHA-1哈希值,作為指紋字元串。
該字串由40個十六進制字元(0-9及a-f)組成,看起來就像是:
24b9da6552252987aa493b52f8696cd6d3b00373
Git的工作完全依賴於這類指紋字串,所以你會經常看到這樣的哈希值。實際上,所有保存在Git資料庫中的東西都是用此哈希值來作索引的,而不是靠檔案名稱。
多數操作僅添加數據
常用的Git操作大多僅僅是把數據添加到資料庫。因為任何一種不可逆的操作,比如刪除數據,要回退或重現都會非常困難。在別的VCS中,若還未提交更新,就有可能丟失或者混淆一些修改的內容,但在Git里,一旦提交快照之後就完全不用擔心丟失數據,特別是在養成了定期推送至其他鏡像倉庫的習慣的話。
這種高可靠性令我們的開發工作安心不少,儘管去做各種試驗性的嘗試好了,再怎樣也不會弄丟數據。至於Git內部究竟是如何保存和恢複數據的,我們會在第九章的“幕後細節”部分再作詳述。
三種狀態
對於任何一個檔案,在Git內都只有三種狀態:已提交(committed),已修改(modified)和已暫存(staged)。已提交表示該檔案已經被安全地保存在本地資料庫中了;已修改表示修改了某個檔案,但還沒有提交保存;已暫存表示把已修改的檔案放在下次提交時要保存的清單中。
每個項目都有一個git目錄,它是Git用來保存元數據和對象資料庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄裡面的數據。
從項目中取出某個版本的所有檔案和目錄,用以開始後續工作的叫做工作目錄。這些檔案實際上都是從git目錄中的壓縮對象資料庫中提取出來的,接下來就可以在工作目錄中對這些檔案進行編輯。
所謂的暫存區域只不過是個簡單的檔案,一般都放在git目錄中。有時候人們會把這個檔案叫做索引檔案,不過標準說法還是叫暫存區域。
基本的Git工作流程如下所示:
1.在工作目錄中修改某些檔案。2.對這些修改了的檔案作快照,並保存到暫存區域。3.提交更新,將保存在暫存區域的檔案快照轉儲到git目錄中。
所以,我們可以從檔案所處的位置來判斷狀態:如果是git目錄中保存著的特定版本檔案,就屬於已提交狀態;如果作了修改並已放入暫存區域,就屬於已暫存狀態;如果自上次取出後,作了修改但還沒有放到暫存區域,就是已修改狀態。到第二章的時候,我們會進一步了解箇中細節,並學會如何善用這些狀態,以及如何跳過暫存環節。
安裝
Git 有許多安裝方式,概括起來主要有兩種,一種是通過編譯原始碼來安裝;另一種是使用為特定平台預編譯好的安裝包。
從原始碼安裝
從原始碼安裝有很多好處,Git的每個版本都在不斷嘗試改進用戶體驗,所以能通過原始碼自己編譯安裝最新的版本是最好的選擇。
Git的工作需要調用curl,zlib,openssl,expat,libiconv等庫的代碼,所以需要先安裝這些依賴工具。
在有Yum的系統上(比如 Red Hat 和 Fedora)或者有apt-get的系統上(比如Debian體系的),可以用下面的命令安裝:
#yuminstallcurl-develexpat-develgettext-developenssl-develzlib-devel
# apt-getinstallcurl-develexpat-develgettext-developenssl-develzlib-devel
之後,然後編譯並安裝:
$tar-zxfgit-1.6.0.5.tar.gz
$cdgit-1.6.0.5
$makeprefix=/usr/localall
$sudomakeprefix=/usr/localinstall
現在已經可以用git命令了,用git把Git項目倉庫克隆到本地,以便日後隨時更新:
$gitclonegit://git.kernel.org/pub/scm/git/git.git
在 Linux 上安裝
如果要在Linux上安裝預編譯好的Git二進制安裝包,可以直接用系統提供的包管理工具。
在Fedora上用yum安裝:
# yuminstallgit-core
在Ubuntu這類Debian體系的系統上,可以用apt-get安裝:
#apt-getinstalgit-core
在 Mac 上安裝
在Mac上安裝Git有兩種方式。最容易的當屬使用圖形化的Git安裝工具,另一種是通過MacPorts(http://www.macports.org)安裝。如果已經裝好了MacPorts,用下面的命令安裝Git:
$sudoportinstallgit-core+SVN+doc+bash_completion+gitweb
這種方式就不需要再自己安裝依賴庫了,Macports會幫你搞定這些麻煩事。
在 Windows 上安裝
在Windows上安裝Git同樣輕鬆,有個叫做msysgit的項目提供了安裝包,可以從GoogleCode的頁面上下載安裝檔案(.exe):
完成安裝之後,就可以使用命令行的git工具(已經自帶了ssh客戶端)了,另外還有一個圖形界面的Git項目管理工具。