Git 思想和工做原理

從根本上來說,Git是一個內容尋址文件系統,並在此之上提供了一個版本控制系統的用戶界面,它是一個很是強大且易用的工具,理解Git的工做原理,可以幫助咱們更容易學習和使用Git。git

本文不會像書籍裏那樣,一條條討論checkout、branch、remote等諸如此類動詞形式的高層命令和底層命令,本文主要從宏觀方向傳達Git的思想和工做原理,可以使初學者更加理解,更利於學習。數據庫


git

直接記錄快照,而非差別比較

Git 和其餘版本控制系統的主要差異在於,Git 只關心文件數據的總體是否發生變化,而大多數其餘系統則只關心文件內容的具體差別。這類系統(CVS,Subversion,Perforce,Bazaar 等等)每次記錄有哪些文件做了更新,以及都更新了哪些行的什麼內容:安全


其餘系統在每一個版本中記錄着各個文化的具體差別

Git 並不保存這些先後變化的差別數據。實際上,Git 更像是把變化的文件做快照後,記錄在一個微型的文件系統中。每次提交更新時,它會縱覽一遍全部文件的指紋信息並對文件做一快照,而後保存一個指向此次快照的索引。爲提升性能,若文件沒有變化,Git 不會再次保存,而只對上次保存的快照做一連接。Git 的工做方式就以下圖所示。工具


Git保存每次更新時的文件快照

這是 Git 同其餘系統的重要區別。它徹底顛覆了傳統版本控制的套路,並對各個環節的實現方式做了新的設計。Git 更像是個小型的文件系統,但它同時還提供了許多以此爲基礎的超強工具,而不僅是一個簡單的 VCS。性能

工做區和暫存區

Git 和其餘版本控制系統的一個不一樣之處就是有暫存區的概念。學習

工做區(Working Directory)

在電腦中能看到的目錄,好比我創建的gittest就是一個工做區設計


工做區
版本庫(Repository)

工做區中的隱藏目錄.git,就是Git的版本庫。3d


工做區和版本庫

Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。版本控制

回憶在我上一篇博客中提到的將文件添加到版本庫的流程圖:指針


將文件添加到版本庫

經過以上兩幅圖不難看出,須要提交的文件通過add後先都放到暫存區index(或者叫stage)中,而後通過commit指令,一次性提交暫存區的全部修改到head。一旦提交後,暫存區清空,同時若對工做區沒有作任何修改,那麼工做區就是乾淨的(working directory clean)

文件的三種狀態

對任何一個文件,在Git內都有三種狀態:

  • 已提交(committed):表示該文件已經被安全的保存在本地數據庫中了
  • 已修改(modified):表示修改了某個文件,但尚未提交保存
  • 已暫存(staged):表示把已修改的文件放在下次提交時要保存的清單中

文件流轉圖

所謂的暫存區域只不過是個簡單的文件,通常都放在 Git 目錄中。有時候人們會把這個文件叫作索引文件,不過標準說法仍是叫暫存區域。

咱們能夠從文件所處的位置來判斷狀態:

  • Git 目錄中保存着的特定版本文件----->已提交狀態
  • 做了修改並已放入暫存區域----->已暫存狀態
  • 自上次取出後,做了修改但尚未放到暫存區域----->已修改狀態

重要的 .git 目錄

當一個新目錄或已有目錄執行git init時,Git會建立一個.git目錄。這個目錄包含了幾乎全部Git存儲和操做的對象。若想備份或複製一個版本庫,只需把這個目錄拷貝至另外一處便可。對於一個全新的版本庫,該目錄結構以下所示:


目錄結構圖
  • description文件:僅供GitWeb程序使用
  • config文件:包含項目特有的配置選項
  • info目錄:包含一個全局性排除(global exclude)文件,用以放置那些不但願被記錄在 .gitignore文件中的忽略模式(ignored patterns)
  • hooks目錄:包含客戶端或服務端的鉤子腳本(hook scripts)
  • HEAD文件:指示目前被檢出的分支
  • index文件:保存暫存區信息
  • objects目錄:存儲全部數據內容
  • refs 目錄:存儲指向數據(分支)的提交對象的指針

關於Git底層命令和高層命令的原理討論,很大一部分都在這個目錄中,要想了解具體的原理,能夠看這本書,這裏僅僅列出了每部分的功能,有個大致瞭解。

基本的 Git 工做流程

  1. 在工做目錄中修改某些文件。
  2. 對修改後的文件進行快照,而後保存到暫存區域。
  3. 提交更新,將保存在暫存區域的文件快照永久轉儲到 Git 目錄中。

分析 Git 命令

有了上述介紹,咱們能夠對 Git 的命令有更深的理解,這裏以將文件添加到代碼庫爲例進行分析:咱們都知道須要兩步,第一步add,第二步commit,但爲何要分兩步呢?每一步都作了什麼呢?


 

(1)git commit -a:至關於運行 git add 把全部當前目錄下的文件加入暫存區域再運行 git commit
(2)git commit <file_name>:進行一次包含最後一次提交加上工做目錄中文件快照的提交,而且文件被添加到暫存區域
(3)git checkout HEAD -- <file_name>:回滾到複製最後一次提交

做者:sunnyaxin連接:http://www.jianshu.com/p/619122f8747b來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索