Git

.3 開始 - Git 基礎要點

Git 基礎要點

那麼,簡單地說,Git 是一個什麼樣的系統?這一章節是非常重要的。若讀者瞭解 Git 的本質以及運作的基礎,那麼使用起來就會很輕鬆且有效率。在學習之前,試著忘記以前所知道的其它版本控制系統,如:Subversion 及 Perforce。 這將會幫助讀者使用此工具時發生不必要的誤會。Git 儲存資料及運作它們的方式遠異於其它系統,即使它們的使用者介面是很相似的。瞭解這些差異會幫助讀者更準確的使用此工具。

記錄檔案快照,而不是差異的部份

Git 與其它版本控制系統 (包含 Subversion 以及與它相關的) 的差別是如何處理資料的方式。一般來說,大部份其它系統記錄資訊是一連串檔案更動的內容。如圖 1-4 所示。這些系統 (CVS, Subversion, Perforce, Bazaar 等等) 儲存一組基本的檔案以及對應這些檔案隨時間遞增的更動資料。


圖 1-4. 其它系統傾向儲存每個檔案更動的資料。

Git 並不以此種方式儲存資料。而是將其視為小型檔案系統的一組快照 (Snapshot)。每一次讀者提交更新時、或者儲存目前專案的狀態到 Git 時。基本上它為當時的資料做一組快照並記錄參考到該快照的參考點。為了講求效率,只要檔案沒有變更,Git 不會再度儲存該檔案,而是記錄到前一次的相同檔案的連結。Git 的工作方式如圖 1-5 所示。


圖 1-5. Git 儲存每次專案更新時的快照。

這是 Git 與所有其它版本控制系統最重要的區別。它完全顛覆傳統版本控制的作法。這使用 Git 更像一個上層具備更強大工具的小型檔案系統,而不只是版本控制系統。我們將會在第三章介紹分支時,提到採用此種作法的優點。

大部份的操作皆可在本地端完成

大部份 Git 的操作皆只需要本地端的檔案及資源即可完成。一般來說並需要到網路上其它電腦提取的資訊。若讀者使用集中式版本控制系統,大部份的動作皆包含網路延遲的成本。這項特點讓你覺得 Git 處理資料的速度飛快。因為整個專案的歷史皆存在你的硬碟中,大部份的運作看起來幾乎都是馬上完成。

例如:想要瀏覽專案的歷史時,Gi t不需要到伺服器下載歷史,而是從本地端的資料庫讀取並顯示即可。這意謂著讀者幾乎馬上就可以看到專案的歷史。若讀者想瞭解某個檔案一個月前的版本及現在版本的差別,Git 可在本地端找出一個月前的檔案並在比對兩者的差異,而不是要求遠端的伺服器執行這項工作,或者從伺服器取回舊版本的檔案並在本地端比對。

這意謂著即使讀者已離線,或者切斷 VPN 連線後,也很少有讀者無法執行的動作。若讀者在飛機或火車上,並想要做一些工作,讀者在取得可上傳的網路前仍可很快樂地提交更新。若讀者回到家且無法讓 VPN 連線程式正常運作,讀者仍然可繼續工作。在許多其它系統幾乎是無法做這些事或者必須付出很大代價。以 Perforce 為例,在無法連到伺服器時讀者做不了多少事。以 Subversion 及 CVS 為例,雖然讀者能編輯檔案,但因為資料庫此時是離線的,讀者無法提交更新到資料庫。這看起來可能還不是什麼大問題,但讀者可能驚訝 Git 有這麼大的不同。

Git能檢查完整性

在 Git 中所有的物件在儲存前都會被計算查核碼 (checksum) 並以查核碼檢索物件。這意謂著 Git 不可能不清楚任何檔案或目錄的內容已被更動。此功能內建在 Git 底層並整合到它的設計哲學。 Git 能夠馬上察覺傳輸時的遺失或是檔案的毀損。

Git 用來計算查核碼的機制稱為 SHA-1 雜湊法。它由 40 個十六進制的字母 (0–9 and a–f) 組成的字串組成,基於 Git 的檔案內容或者目錄結構計算。 查核碼看起來如下所示:

24b9da6552252987aa493b52f8696cd6d3b00373

讀者會 Git 中到處都看到雜湊值,因為它到處被使用。事實上 Git 以檔案內容的雜湊值定址出檔案在資料庫的位址,而不是以檔案的名稱定址。

Git 通常只增加資料

當讀者使用 Git,幾乎所有的動作只是增加資料到 Git 的資料庫。很難藉此讓做出讓系統無法復原或者清除資料的動作。在任何版本控制系統,讀者有可能會遺失或者搞混尚未提交的更新。但是在提交快照到 Git 後,很少會有遺失的情況,特別是讀者定期將資料庫更新到其它儲存庫。

這讓使用 Git 可輕鬆地像在玩一樣,因為我們知道我們可以進行任何實驗而不會破壞任何東西。在第九章的 “底層細節” 中,我們會進一步討論 Git 如何儲存資料,以及讀者如何復原看似遺失的資料。

三種狀態

現在,注意。 若讀者希望接下來的學習過程順利些,這是關於 Git 的重要且需記住的事項。Git 有三種表達檔案的狀態:已提交 (committed)、已修改 (modified) 及已暫存 (staged)。已提交意謂著資料己安全地存在讀者的本地端資料庫。己修改代表著讀者已修改檔案但尚未提交到資料庫。已暫存意謂著讀者標記已修改檔案目前的版本到下一次提供的快照。

這帶領我們到 Git 專案的三個主要區域:Git 目錄、工作目錄 (working directory) 以及暫存區域 (staging area)。


圖 1-6. 工作目錄、暫存區域及 Git 目錄。

Git 目錄是 Git 用來儲存讀者的專案的 metadata 及物件資料庫。這是 Git 最重要的部份,而且它是當讀者從其它電腦複製儲存庫時會複製過來的。

工作目錄是專案被取出的某一個版本。這些檔案從 Git 目錄內被壓縮過的資料庫中拉出來並放在磁碟機供讀者使用或修改。

暫存區域是一個單純的檔案,一般來說放在 Git 目錄,儲存關於下一個提交的資訊。有時稱為索引,但現在將它稱為暫存區域已開始成為標準。

基本 Git 工作流程大致如下:

  1. 讀者修改工作目錄內的檔案。
  2. 暫存檔案,將檔案的快照新增到暫存區域。
  3. 做提交的動作,這會讓存在暫存區域的檔案快照永久地儲存在 Git 目錄。

在 Git 目錄內特定版本的檔案被認定為已提交。若檔案被修改且被增加到暫存區域,稱為被暫存。若檔案被取出後有被修改,但未被暫存,稱為被修改。在第二章讀者會學到更多關於這些狀態以及如何利用它們的優點或者整個略過暫存步驟。