1. 程式人生 > >Git之——Git工作區、版本庫和暫存區

Git之——Git工作區、版本庫和暫存區

Git暫存區(stage)是比較難理解的部分,也是Git的特色之一,那麼它和工作區與版本庫之間的聯絡又是怎樣的,在這之前,應該先記住如下點:

1、所說的版本庫就是隱藏的.git目錄。

2、檔案 .git/index是記錄了檔名、檔案的狀態資訊(時間戳、檔案長度等)等的檔案索引的目錄樹。

3、Git 物件庫(.git/objects)中儲存的是檔案索引中所指定的檔案實體。

下面的圖詳細展示了三者之間的關係(圖與相關說明均轉自http://www.worldhello.net/2010/11/30/2166.html,這部分知識也可以再蔣鑫的《Git 權威指南》中找到)

工作區、版本庫、暫存區原理圖

在這個圖中,我們可以看到部分 Git 命令是如何影響工作區和暫存區(stage, index)的。
  • 圖中左側為工作區,右側為版本庫。在版本庫中標記為 "index" 的區域是暫存區(stage, index),標記為 "master" 的是 master 分支所代表的目錄樹。
  • 圖中我們可以看出此時 "HEAD" 實際是指向 master 分支的一個“遊標”。所以圖示的命令中出現 HEAD 的地方可以用 master 來替換。
  • 圖中的 objects 標識的區域為 Git 的物件庫,實際位於 ".git/objects" 目錄下,我們會在後面的章節重點介紹。
  • 當對工作區修改(或新增)的檔案執行 "git add" 命令時,暫存區的目錄樹被更新,同時工作區修改(或新增)的檔案內容被寫入到物件庫中的一個新的物件中,而該物件的ID 被記錄在暫存區的檔案索引中。
  • 當執行提交操作(git commit)時,暫存區的目錄樹寫到版本庫(物件庫)中,master 分支會做相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。
  • 當執行 "git reset HEAD" 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。
  • 當執行 "git rm --cached <file>" 命令時,會直接從暫存區刪除檔案,工作區則不做出改變。
  • 當執行 "git checkout ." 或者 "git checkout -- <file>" 命令時,會用暫存區全部或指定的檔案替換工作區的檔案。這個操作很危險,會清除工作區中未新增到暫存區的改動。
  • 當執行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的全部或者部分檔案替換暫存區和以及工作區中的檔案。這個命令也是極具危險性的,因為不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改 動。

--------------------------------------------------------------我是分割線14.4.13---------------------------------------------------------------------------------------------

下面是最近又看這部分內容的一個補充(學而時習之,不亦說乎?):

1、git status -s 引數,等同於--short,對git status的簡化輸出。

2、檢視工作區、暫存區和版本庫的目錄樹的方式。

工作區:正常的ls命令即可。
暫存區:git ls-files -s
版本庫:git ls-tree HEAD


另一個很有用的命令:git clean -fd
(其中引數-f(force) -d(directory)),
作用:清除當前工作區中沒有新增到版本庫中的檔案和目錄。如
echo "test clean -fd" > test.txt
git status -s                       ---------> A test.txt
git clean -f                        ---------> Removing test.txt


3、.git/index與.git/objects

git status/git diff 等命令就是通過.git/index的記錄進行的判斷。index的內容是“包含檔案索引”的目錄樹。但是檔案的內容並沒有在其中,而是在.git/objects中,檔案索引建立了檔案和物件庫中物件實體之間的對應。

4、git中的有些操作只是操作了目錄樹,而沒有涉及到物件庫中的物件。

像git add 操作物件:目錄樹 + 物件庫
而git commit操作物件:只有目錄樹

5、注意點:

git commit 可以加上 -a 引數,可以直接對本地所有變更的檔案執行提交,簡化了git add操作,相當於跳過了Git最大好處“暫存區”,所以不要使用這個命令。