1. 程式人生 > >一篇文章說清GIT的“分散式”是什麼意思?

一篇文章說清GIT的“分散式”是什麼意思?

1、Git簡介

Git簡單的來說,是一種分散式的版本管理工具,其具有以下優點:
1、速度快
2、簡單的設計
3、對非線性開發模式的強力支援(可以同時允許幾千個分支同時進行開發和切換)
4、完全分散式(防止集中式版本管理工具所出現的單點故障問題)

Linus花了兩個星期用C語言寫出了一套Git的原型程式碼,在Linux數千開發者的努力與完善之下,形成了目前的Git這一套版本管理工具。

2、如何分散式

Git是分散式的,並沒有服務端跟客戶端之分,所謂的服務端安裝的其實也是Git。
Git支援四種協議,file,ssh,git,http。ssh是使用較多的,下面使用ssh搭建一個免密碼登入的服務端。

Git與SVN是目前大多數企業所選擇的版本管理工具,兩者也代表了版本管理的兩個主要的設計模式和理念。SVN是集中式版本管理系統的代表,中央程式碼庫儲存著所有程式碼提交者的程式碼,而每個專案的參與者只負責程式碼的提交,中央程式碼庫則儲存著完整版的所有程式碼。但這也造成了一系列的問題:

1、中央程式碼庫單點故障所帶來的專案風險,並且一旦發生,程式碼則無法恢復。

2、提交程式碼時由於網路頻寬問題所帶來時間上的延遲,影響開發人員的工作效率。

3、對於中央程式碼庫而言,其伺服器壓力過大,資料庫容量暴增。

Git則是建立在本地庫基礎之上的分散式版本管理工具,最終可以使得任何程式碼的提交者都可以成為“中央程式碼庫”。Git的根本思想和基本工作原理主要是在本地複製一個“程式碼庫”,每次提交的程式碼均是推送到原生代碼庫中,節約了由於網路頻寬所帶來的限制,不至於出現提交5MB的程式碼而需等待20分鐘的情況。另一方面,一旦中央程式碼庫的伺服器出現“崩潰”,那麼任何“本地庫”均可以還原中央程式碼庫。

Linus是如何通過Git來實現這個目標的呢?

Git的核心思想在於,每次程式碼版本的更迭和變化,Git都會記錄資料檔案的整體是否發生變化,而大多數其他系統則只關心檔案內容的具體差異變化,這類系統每次記錄有哪些檔案作了更新,以及都更新了哪些行的什麼內容。

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

總的來說,Git是一個儲存著整個程式碼快照或者程式碼快照連結的小型檔案系統,所以在每次程式碼修改之後都能夠保持整個程式碼庫的“風貌”,而不是像其他版本管理系統一樣,只記錄修改的檔案和具體的修改內容。要復原整個程式碼庫的話,還需藉助“原始材料”。

3、Git的基本設計理念

3.1 近乎所有操作都是本地執行

在Git中的絕大多數操作都只需要訪問本地檔案和資源,不用聯網。如檢視提交記錄、修改內容資訊、版本更新、建立分支、切換分支等等。因為Git在本地磁碟上就儲存著所有當前專案的歷史更新,所以處理起來速度飛快。例如,你如果想要檢視現在的程式碼和一個月前的版本有何差異,那麼Git會取出一個月前的程式碼快照和此時的程式碼做一次對比,而不用請求遠端伺服器來做這件事,或者是把老版本的程式碼拉到本地作比較。

如果是SVN的話,那麼你必須在有網路的情況下才能夠提交程式碼,而此時你現在在火車上,那麼你無法做任何事情,然而如果你正在使用Git,那麼你可以隨時的提交已經測試通過的程式碼模組,等到有網路的時候再上傳到遠端倉庫即可。

3.2 時刻保持資料的完整性

Git通過對管理起來的每個檔案計算Hash值,從而得到每個資料的唯一標識和索引。在Git中也全靠這些Hash值來唯一識別檔案,而不是檔名。該“指紋”Hash值是一個由40位16進位制字串組成的,任何檔案的損壞或者資料缺失都會被Git通過Hash值校驗輕鬆識別到。

3.3 Git的三個檔案區域

對任何一被Git管理的檔案而言,其只具有三種可能的狀態,分別是“已提交”,“已修改”和“已暫存”。已提交表示該檔案已經被安全儲存在本地資料庫中了;已修改表示此檔案修改了,但沒有提交儲存;已暫存表示已經把修改後的檔案提交到了暫存區域但還沒有提交。

4、Git的精髓——分支

分支是Git的核心所在,猶如作業系統的核心對於作業系統而言至關重要,也是Git能夠支援上千個分支併發處理的關鍵所在。為了要理解Git分支的本質思想,我們需要結合Git的儲存資料的方式來仔細講解,Git儲存的不是檔案差異或者變化量,而只是一系列檔案快照,理解這點很關鍵。

在Git提交時,會儲存一個提交(commit)物件,這個commit物件包含著以下內容:

1、指向暫存內容快照的指標。

2、本次提交的作者等相關附屬資訊。

3、零個或多個指向該提交物件的父物件指標(普通提交只有一個父親,如果從多個分支合併而來則有多個父親)。

講完這些之後,我們再回過頭來談Git的分支。Git中的分支,其實本質上僅僅是指向commit提交物件的可變指標,它在每次提交的時候,都會自動向前移動。新建一個新的分支只是在當前commit物件上再建立一個新的可變指標;Git會儲存一個名為HEAD的特別指標,指向分支的可變指標,HEAD表示當前分支。

5、分支合併,變基

分支合併不是簡單地把分支指標右移,而是對三方合併後的結果重新做一個新的快照,並自動建立一個指向它的提交物件。這個提交物件。這個提交物件比較特殊,它有兩個祖先。在分支合併的時候,可能會導致衝突的發生,需要人工解決衝突才能夠重新提交程式碼。

分支變基指的是回到兩個分支最近的共同祖先,根據當前分支後續的歷次提交物件,生成一系列的檔案補丁,然後在基底分支的基礎之上,逐個應用之前準備好的補丁檔案,最後會生成一個新的合併提交物件。切勿對已釋出版本的程式碼進行變基操作。

參考:
Git(分散式版本控制系統)
git分散式的理解----簡單服務端搭建