那么,簡單地說,Git 究竟是怎樣的一個系統呢? 請注意接下來的內容非常重要,若你理解了 Git 的思想和基本工作原理,用起來就會知其所以然,游刃有余。 在開始學習 Git 的時候,請努力分清你對其它版本管理系統的已有認識,如 Subversion 和 Perforce 等;這么做能幫助你使用工具時避免發生混淆。 Git 在保存和對待各種信息的時候與其它版本控制系統有很大差異,盡管操作起來的命令形式非常相近,理解這些差異將有助于防止你使用中的困惑。
[toc]
## 直接記錄快照,而非差異比較
Git 和其它版本控制系統(包括 Subversion 和近似工具)的主要差別在于 Git 對待數據的方法。 概念上來區分,其它大部分系統以文件變更列表的方式存儲信息。 這類系統(CVS、Subversion、Perforce、Bazaar 等等)將它們保存的信息看作是一組基本文件和每個文件隨時間逐步累積的差異。

Git 不按照以上方式對待或保存數據。 反之,Git 更像是把數據看作是對小型文件系統的一組快照。 每次你提交更新,或在 Git 中保存項目狀態時,它主要對當時的全部文件制作一個快照并保存這個快照的索引。 為了高效,如果文件沒有修改,Git 不再重新存儲該文件,而是只保留一個鏈接指向之前存儲的文件。 Git 對待數據更像是一個 快照流。

這是 Git 與幾乎所有其它版本控制系統的重要區別。 因此 Git 重新考慮了以前每一代版本控制系統延續下來的諸多方面。 Git 更像是一個小型的文件系統,提供了許多以此為基礎構建的超強工具,而不只是一個簡單的 VCS。 稍后我們在Git 分支討論 Git 分支管理時,將探究這種方式對待數據所能獲得的益處。
## 近乎所有操作都是本地執行
在 Git 中的絕大多數操作都只需要訪問本地文件和資源,一般不需要來自網絡上其它計算機的信息。 如果你習慣于所有操作都有網絡延時開銷的集中式版本控制系統,Git 在這方面會讓你感到速度之神賜給了 Git 超凡的能量。 因為你在本地磁盤上就有項目的完整歷史,所以大部分操作看起來瞬間完成。
舉個例子,要瀏覽項目的歷史,Git 不需外連到服務器去獲取歷史,然后再顯示出來——它只需直接從本地數據庫中讀取。 你能立即看到項目歷史。 如果你想查看當前版本與一個月前的版本之間引入的修改,Git 會查找到一個月前的文件做一次本地的差異計算,而不是由遠程服務器處理或從遠程服務器拉回舊版本文件再來本地處理。
這也意味著你離線或者沒有 VPN 時,幾乎可以進行任何操作。 如你在飛機或火車上想做些工作,你能愉快地提交,直到有網絡連接時再上傳。 如你回家后 VPN 客戶端不正常,你仍能工作。 使用其它系統,做到如此是不可能或很費力的。 比如,用 Perforce,你沒有連接服務器時幾乎不能做什么事;用 Subversion 和 CVS,你能修改文件,但不能向數據庫提交修改(因為你的本地數據庫離線了)。 這看起來不是大問題,但是你可能會驚喜地發現它帶來的巨大的不同。
## Git 保證完整性
Git 中所有數據在存儲前都計算校驗和,然后以校驗和來引用。 這意味著不可能在 Git 不知情時更改任何文件內容或目錄內容。 這個功能建構在 Git 底層,是構成 Git 哲學不可或缺的部分。 若你在傳送過程中丟失信息或損壞文件,Git 就能發現。
Git 用以計算校驗和的機制叫做 SHA-1 散列(hash,哈希)。 這是一個由 40 個十六進制字符(0-9 和 a-f)組成字符串,基于 Git 中文件的內容或目錄結構計算出來。 SHA-1 哈希看起來是這樣:
24b9da6552252987aa493b52f8696cd6d3b00373
Git 中使用這種哈希值的情況很多,你將經常看到這種哈希值。 實際上,Git 數據庫中保存的信息都是以文件內容的哈希值來索引,而不是文件名。
## Git 一般只添加數據
你執行的 Git 操作,幾乎只往 Git 數據庫中增加數據。 很難讓 Git 執行任何不可逆操作,或者讓它以任何方式清除數據。 同別的 VCS 一樣,未提交更新時有可能丟失或弄亂修改的內容;但是一旦你提交快照到 Git 中,就難以再丟失數據,特別是如果你定期的推送數據庫到其它倉庫的話。
這使得我們使用 Git 成為一個安心愉悅的過程,因為我們深知可以盡情做各種嘗試,而沒有把事情弄糟的危險。 更深度探討 Git 如何保存數據及恢復丟失數據的話題,請參考撤消操作。
## 三種狀態和三個工作區域
好,請注意。 如果你希望后面的學習更順利,記住下面這些關于 Git 的概念。 Git 有三種狀態,你的文件(確切的說是工作目錄中的文件)可能處于其中之一:**已提交(committed)、已修改(modified)和已暫存(staged)**。 已提交表示數據已經安全的保存在本地數據庫中。 已修改表示修改了文件,但還沒保存到數據庫中。 已暫存表示對一個已修改文件的當前版本做了標記,使之包含在下次提交的快照中。
由此引入 Git 項目的三個工作區域的概念:**Git 倉庫、工作目錄以及暫存區域。**

Git 倉庫目錄是 Git 用來保存項目的元數據和對象數據庫的地方。 這是 Git 中最重要的部分,從其它計算機克隆倉庫時,拷貝的就是這里的數據。
工作目錄是對項目的某個版本獨立提取出來的內容。 這些從 Git 倉庫的壓縮數據庫中提取出來的文件,放在磁盤上供你使用或修改。
暫存區域是一個文件,保存了下次將提交的文件列表信息,一般在 Git 倉庫目錄中。 有時候也被稱作'索引',不過一般說法還是叫暫存區域。
基本的 Git 工作流程如下:
1. 在工作目錄中修改文件。
2. 暫存文件,將文件的快照放入暫存區域。
3. 提交更新,找到暫存區域的文件,將快照永久性存儲到 Git 倉庫目錄。
如果 Git 目錄中保存著的特定版本文件,就屬于已提交狀態。 如果作了修改并已放入暫存區域,就屬于已暫存狀態。 如果自上次取出后,作了修改但還沒有放到暫存區域,就是已修改狀態。 在**Git 基礎**一章,你會進一步了解這些狀態的細節,并學會如何根據文件狀態實施后續操作,以及怎樣跳過暫存直接提交。
- 第一章 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 命令行
- 1.5 安裝 Git
- 1.6 初次運行 Git 前的配置
- 1.7 獲取幫助
- 1.8 總結
- 第二章 Git基礎
- 2.1 獲取 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 Git 別名
- 2.8 總結
- 第三章 Git分支
- 3.1 分支簡介
- 3.2 分支的新建與合并
- 3.3 分支管理
- 3.4 分支開發工作流
- 3.5 遠程分支
- 3.6 變基
- 3.7 總結
- 第四章 服務器上Git
- 4.1 協議
- 4.2 在服務器上搭建 Git
- 4.3 生成 SSH 公鑰
- 4.4 配置服務器
- 4.5 Git 守護進程 TODO
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管的選擇
- 4.10 總結
- 第五章 分布式Git
- 5.1 分布式工作流程
- 第六章 GitHub
- 第七章 Git工具
- 第八章 自定義Git
- 第九章 Git于其他系統
- 第十章 Git內部原理
- 附錄A 其他環境中的Git
- A1.1 圖形界面 TODO
- A1.2 Visual Studio 中的 Git TODO
- A1.3 Eclipse 中的 Git
- 附錄B 將Git嵌入你的應用
- 附錄C Git命令
- 附錄D 常用命令
- D.1 配置和設置
- D.2 幫助
- D.3 創建和獲取倉庫
- D.4 文件狀態
- D.5 查看日志