Git之——Git工作區、版本庫和暫存區
阿新 • • 發佈:2019-02-14
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操作物件:只有目錄樹