那麼,簡單地說,git 究竟是怎樣的乙個系統呢?請注意,接下來的內容非常重要,若是理解了 git 的思想和基本工作原理,用起來就會知其所以然,游刃有餘。
在開始學習 git 的時候,請不要嘗試把各種概念和其他版本控制系統(諸如 subversion 和 perforce 等)相比擬,否則容易混淆每個操作的實際意義。git 在儲存和處理各種資訊的時候,雖然操作起來的命令形式非常相近,但它與其他版本控制系統的做法頗為不同。理解這些差異將有助於你準確地使用 git 提供的各種工具。
直接記錄快照,而非差異比較
git 和其他版本控制系統的主要差別在於,git 只關心檔案資料的整體是否發生變化,而大多數其他系統則只關心檔案內容的具體差異。這類系統(cvs,subversion,perforce,bazaar 等等)每次記錄有哪些檔案作了更新,以及都更新了哪些行的什麼內容:
其他系統在每個版本中記錄著各個檔案的具體差異
git 並不儲存這些前後變化的差異資料。實際上,git 更像是把變化的檔案作快照後,記錄在乙個微型的檔案系統中。每次提交更新時,它會縱覽一遍所有檔案的指紋資訊並對檔案作一快照,然後儲存乙個指向這次快照的索引。為提高效能,若檔案沒有變化,git 不會再次儲存,而只對上次儲存的快照作一鏈結。git 的工作方式就如下圖所示。
git 儲存每次更新時的檔案快照
這是 git 同其他系統的重要區別。它完全顛覆了傳統版本控制的套路,並對各個環節的實現方式作了新的設計。git 更像是個小型的檔案系統,但它同時還提供了許多以此為基礎的超強工具,而不只是乙個簡單的 vcs。稍後會討論 git 分支管理的時候,我們會再看看這樣的設計究竟會帶來哪些好處。
近乎所有操作都是本地執行
在 git 中的絕大多數操作都只需要訪問本地檔案和資源,不用連網。但如果用 cvcs 的話,差不多所有操作都需要連線網路。因為 git 在本地磁碟上就儲存著所有當前專案的歷史更新,所以處理起來速度飛快。
舉個例子,如果要瀏覽專案的歷史更新摘要,git 不用跑到外面的伺服器上去取資料回來,而直接從本地資料庫讀取後展示給你看。所以任何時候你都可以馬上翻閱,無需等待。如果想要看當前版本的檔案和乙個月前的版本之間有何差異,git 會取出乙個月前的快照和當前檔案作一次差異運算,而不用請求遠端伺服器來做這件事,或是把老版本的檔案拉到本地來作比較。
用 cvcs 的話,沒有網路或者斷開 vpn 你就無法做任何事情。但用 git 的話,就算你在飛機或者火車上,都可以非常愉快地頻繁提交更新,等到了有網路的時候再上傳到遠端倉庫。同樣,在回家的路上,不用連線 vpn 你也可以繼續工作。換作其他版本控制系統,這麼做幾乎不可能,抑或非常麻煩。比如 perforce,如果不連到伺服器,幾乎什麼都做不了(預設無法發出命令 p4 edit file 開始編輯檔案,因為 perforce 需要聯網通知系統宣告該檔案正在被誰修訂。但實際上手工修改檔案許可權可以繞過這個限制,只是完成後還是無法提交更新。);如果是 subversion 或 cvs,雖然可以編輯檔案,但無法提交更新,因為資料庫在網路上。看上去好像這些都不是什麼大問題,但實際體驗過之後,你就會驚喜地發現,這其實是會帶來很大不同的。
時刻保持資料完整性
在儲存到 git 之前,所有資料都要進行內容的校驗和(checksum)計算,並將此結果作為資料的唯一標識和索引。換句話說,不可能在你修改了檔案或目錄之後,git 一無所知。這項特性作為 git 的設計哲學,建在整體架構的最底層。所以如果檔案在傳輸時變得不完整,或者磁碟損壞導致檔案資料缺失,git 都能立即察覺。
git 使用 sha-1 演算法計算資料的校驗和,通過對檔案的內容或目錄的結構計算出乙個 sha-1 雜湊值,作為指紋字串。該字串由 40 個十六進製制字元(0-9 及 a-f)組成,看起來就像是:
1
24b9da6552252987aa493b52f8696cd6d3b00373
git 的工作完全依賴於這類指紋字串,所以你會經常看到這樣的雜湊值。實際上,所有儲存在 git 資料庫中的東西都是用此雜湊值來作索引的,而不是靠檔名。
多數操作僅新增資料
常用的 git 操作大多僅僅是把資料新增到資料庫。因為任何一種不可逆的操作,比如刪除資料,都會使回退或重現歷史版本變得困難重重。在別的 vcs 中,若還未提交更新,就有可能丟失或者混淆一些修改的內容,但在 git 裡,一旦提交快照之後就完全不用擔心丟失資料,特別是養成定期推送到其他倉庫的習慣的話。
這種高可靠性令我們的開發工作安心不少,儘管去做各種試驗性的嘗試好了,再怎樣也不會弄丟資料。至於 git 內部究竟是如何儲存和恢復資料的,我們會在後面討論 git 內部原理時再作詳述。
檔案的三種狀態
好,現在請注意,接下來要講的概念非常重要。對於任何乙個檔案,在 git 內都只有三種狀態:已提交(committed),已修改(modified)和已暫存(staged)。已提交表示該檔案已經被安全地儲存在本地資料庫中了;已修改表示修改了某個檔案,但還沒有提交儲存;已暫存表示把已修改的檔案放在下次提交時要儲存的清單中。
由此我們看到 git 管理專案時,檔案流轉的三個工作區域:git 的工作目錄,暫存區域,以及本地倉庫。
工作目錄,暫存區域,以及本地倉庫
每個專案都有乙個 git 目錄(如果 git clone 出來的話,就是其中 .git 的目錄;如果 git clone --bare 的話,新建的目錄本身就是 git 目錄。),它是 git 用來儲存元資料和物件資料庫的地方。該目錄非常重要,每次轉殖映象倉庫的時候,實際拷貝的就是這個目錄裡面的資料。
從專案中取出某個版本的所有檔案和目錄,用以開始後續工作的叫做工作目錄。這些檔案實際上都是從 git 目錄中的壓縮物件資料庫中提取出來的,接下來就可以在工作目錄中對這些檔案進行編輯。
所謂的暫存區域只不過是個簡單的檔案,一般都放在 git 目錄中。有時候人們會把這個檔案叫做索引檔案,不過標準說法還是叫暫存區域。
基本的 git 工作流程如下:
在工作目錄中修改某些檔案。
對修改後的檔案進行快照,然後儲存到暫存區域。
提交更新,將儲存在暫存區域的檔案快照永久轉儲到 git 目錄中。
所以,我們可以從檔案所處的位置來判斷狀態:如果是 git 目錄中儲存著的特定版本檔案,就屬於已提交狀態;如果作了修改並已放入暫存區域,就屬於已暫存狀態;如果自上次取出後,作了修改但還沒有放到暫存區域,就是已修改狀態。
**
Git的思想和基本工作原理
那麼,簡單地說,git 究竟是怎樣的乙個系統呢?請注意,接下來的內容非常重要,若是理解了 git 的思想和基本工作原理,用起來就會知其所以然,游刃有餘。在開始學習 git 的時候,請不要嘗試把各種概念和其他版本控制系統 諸如 subversion 和 perforce 等 相比擬,否則容易混淆每個操...
Git的思想和基本工作原理
那麼,簡單地說,git 究竟是怎樣的乙個系統呢?請注意,接下來的內容非常重要,若是理解了 git 的思想和基本工作原理,用起來就會知其所以然,游刃有餘。在開始學習 git 的時候,請不要嘗試把各種概念和其他版本控制系統 諸如 subversion 和 perforce 等 相比擬,否則容易混淆每個操...
Git的思想和基本工作原理
那麼,簡單地說,git 究竟是怎樣的乙個系統呢?請注意,接下來的內容非常重要,若是理解了 git 的思想和基本工作原理,用起來就會知其所以然,游刃有餘。在開始學習 git 的時候,請不要嘗試把各種概念和其他版本控制系統 諸如 subversion 和 perforce 等 相比擬,否則容易混淆每個操...