章節 ▾ 第二版

1.3 上手 - Git 是什麼?

什麼是 Git?

那麼,簡單來說 Git 是什麼?這是一個需要吸收的重要章節,因為如果你理解了 Git 是什麼以及它是如何工作的基本原理,那麼有效使用 Git 可能會對你來說容易得多。在學習 Git 時,儘量拋開你可能瞭解的其他版本控制系統(如 CVS、Subversion 或 Perforce)的知識——這樣做將有助於你避免在使用該工具時產生細微的混淆。儘管 Git 的使用者介面與其他這些版本控制系統相當相似,但 Git 儲存和思考資訊的方式卻大相徑庭,理解這些差異將有助於你在使用它時避免感到困惑。

快照,而非差異

Git 與任何其他版本控制系統(包括 Subversion 及其“朋友們”)之間的主要區別在於 Git 思考其資料的方式。從概念上講,大多數其他系統將資訊儲存為基於檔案的更改列表。這些其他系統(CVS、Subversion、Perforce 等)將其儲存的資訊視為一組檔案以及隨著時間推移對每個檔案所做的更改(這通常被稱為基於增量的版本控制)。

Storing data as changes to a base version of each file
圖 4. 將資料儲存為每個檔案基礎版本的更改

Git 不以這種方式思考或儲存其資料。相反,Git 更像是一個微型檔案系統的系列快照。在使用 Git 時,每次你提交或儲存專案狀態時,Git 基本上都會拍下你所有檔案在那一刻的樣子,並存儲對該快照的引用。為了提高效率,如果檔案沒有更改,Git 不會再次儲存該檔案,而只是連結到它已儲存的先前相同檔案。Git 更多地將其資料視為快照流

Git stores data as snapshots of the project over time
圖 5. 將資料儲存為專案隨時間變化的快照

這是 Git 與幾乎所有其他版本控制系統之間的重要區別。它使得 Git 重新思考了大多數其他系統從上一代複製的版本控制的幾乎所有方面。這使得 Git 更像一個帶有強大工具的迷你檔案系統,而不僅僅是一個版本控制系統。當我們講到 Git 分支時,我們將探討以這種方式思考資料所帶來的一些好處。

幾乎所有操作都是本地的

Git 中的大多數操作只需要本地檔案和資源即可執行——通常不需要來自網路上另一臺計算機的資訊。如果你習慣了大多數操作都有網路延遲開銷的集中式版本控制系統(CVCS),那麼 Git 的這一方面會讓你覺得速度之神賦予了 Git 超凡的力量。因為你的本地磁碟上就存有專案的完整歷史,所以大多數操作看起來幾乎是即時的。

例如,要瀏覽專案的歷史記錄,Git 不需要連線到伺服器來獲取歷史記錄併為你顯示——它只是直接從你的本地資料庫中讀取。這意味著你可以幾乎立即看到專案歷史。如果你想檢視檔案當前版本和一個月前檔案之間的更改,Git 可以查詢一個月前的檔案並進行本地差異計算,而不是不得不請求遠端伺服器進行或從遠端伺服器拉取舊版本檔案到本地進行。

這也意味著,如果你處於離線狀態或沒有 VPN 連線,幾乎沒有什麼事情是你不能做的。如果你乘坐飛機或火車,想要做一些工作,你可以愉快地提交(記住,是提交到你的本地副本),直到你獲得網路連線以進行上傳。如果你回家後無法使 VPN 客戶端正常工作,你仍然可以繼續工作。在許多其他系統中,這樣做要麼不可能,要麼非常痛苦。例如,在 Perforce 中,當你未連線到伺服器時,你無法做太多事情;在 Subversion 和 CVS 中,你可以編輯檔案,但無法將更改提交到你的資料庫(因為你的資料庫處於離線狀態)。這可能看起來不是什麼大問題,但它能帶來多大的不同可能會讓你感到驚訝。

Git 具有完整性

Git 中的一切在儲存之前都會進行校驗和計算,然後透過該校驗和進行引用。這意味著在 Git 不知情的情況下,不可能更改任何檔案或目錄的內容。此功能內置於 Git 的最低層,是其理念的組成部分。你不會在傳輸過程中丟失資訊或遇到檔案損壞而 Git 無法檢測到。

Git 用於校驗和的機制稱為 SHA-1 雜湊。這是一個由十六進位制字元(0-9 和 a-f)組成的 40 個字元的字串,根據 Git 中檔案或目錄結構的內容計算得出。SHA-1 雜湊值看起來像這樣

24b9da6552252987aa493b52f8696cd6d3b00373

你會在 Git 中隨處看到這些雜湊值,因為它使用它們非常頻繁。事實上,Git 在其資料庫中儲存所有內容都不是透過檔名,而是透過其內容的雜湊值。

Git 通常只新增資料

當你在 Git 中執行操作時,幾乎所有操作都只會向 Git 資料庫新增資料。很難讓系統執行任何不可撤銷或以任何方式擦除資料的操作。與任何版本控制系統一樣,你可能會丟失或搞砸尚未提交的更改,但一旦你將快照提交到 Git 中,就很難丟失,特別是如果你定期將資料庫推送到另一個倉庫。

這使得使用 Git 成為一種樂趣,因為我們知道我們可以放心地進行實驗,而無需擔心嚴重搞砸。要更深入地瞭解 Git 如何儲存其資料以及如何恢復看似丟失的資料,請參閱 撤銷操作

三種狀態

現在請注意——如果你想讓接下來的學習過程順利進行,這是關於 Git 最需要記住的關鍵點。Git 有三種檔案可能存在的主要狀態:已修改 (modified)已暫存 (staged)已提交 (committed)

  • 已修改 (modified) 意味著你已更改檔案,但尚未將其提交到資料庫。

  • 已暫存 (staged) 意味著你已將檔案的當前修改版本標記為要納入下一次提交快照。

  • 已提交 (committed) 意味著資料已安全地儲存在你的本地資料庫中。

這引出了 Git 專案的三個主要組成部分:工作區 (working tree)、暫存區 (staging area) 和 Git 目錄 (Git directory)。

Working tree, staging area, and Git directory
圖 6. 工作區、暫存區和 Git 目錄

工作區 (working tree) 是專案某個版本的單次檢出。這些檔案從 Git 目錄中的壓縮資料庫中提取出來,並放置在磁碟上供你使用或修改。

暫存區 (staging area) 是一個檔案,通常包含在你的 Git 目錄中,它儲存著關於下一次提交中將包含什麼資訊。它在 Git 術語中的技術名稱是“索引 (index)”,但“暫存區”這個短語也同樣適用。

Git 目錄 (Git directory) 是 Git 儲存專案元資料和物件資料庫的地方。這是 Git 最重要的部分,當你從另一臺計算機克隆 (clone) 倉庫時,它就是被複制的內容。

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

  1. 你在工作區中修改檔案。

  2. 你選擇性地暫存你希望包含在下一次提交中的更改,這會將僅有這些更改新增到暫存區。

  3. 你執行提交,這會將暫存區中的檔案原樣取出,並將該快照永久儲存到你的 Git 目錄中。

如果檔案的特定版本在 Git 目錄中,則它被認為是已提交 (committed)。如果它已修改並已新增到暫存區,則它處於已暫存 (staged) 狀態。如果它自檢出後已更改但尚未暫存,則它處於已修改 (modified) 狀態。在 Git 基礎中,你將瞭解更多關於這些狀態的資訊,以及如何利用它們或完全跳過暫存部分。

scroll-to-top