1. 程式人生 > >git學習(四):理解git暫存區(stage)

git學習(四):理解git暫存區(stage)

可能 revert 版本 RM stat 文件的時間 文件替換 方法 TE

與一般的版本管理不同的是,git在提交之前要將更改通過git add 添加到暫存區才能提交(git commit)。即使是已經交給了git來管理的文件也是如此。這裏繼續學習git的暫存區。

通過git checkout撤銷工作區更改

在版本庫.git目錄下有一個index文件。

首先執行git checkout命令,撤銷工作區中welcome.txt文件尚未提交的修改。

技術分享圖片

原來可以通過這種方法來撤銷修改,媽呀,我還是菜啊。之前使用IDEA的時候只知道用revert。

git status和git diff原理

小實驗:修改一個文件的時間戳,然後對應觀察.git/index的時間戳。

結論:執行git status或者git diff掃描工作區改動時,

  1. 先根據.git/index文件中記錄(用於跟蹤工作區文件的)時間戳、長度等信息判斷工作區文件是否改變。
  2. 如果工作區文件的時間戳改變了,說明文件的內容可能改變了,需要打開文件,讀取文件的內容,與更改前的原始文件進行比較,判斷文件內容是否被更改。
  3. 如果文件內容沒有改變,則將文件新的時間戳記錄到.git/index文件中。
  4. 因為如果判斷文件是否更改,使用時間戳、文件長度等信息比較要比通過文件內容快得多。

技術分享圖片

.git/index

.git/index:

  • 包含了文件索引的目錄樹,像一個虛擬的工作區。
  • 目錄樹種記錄了文件名和文件的狀態信息(時間戳和文件長度等)。
  • 並不存儲文件內容(內容在.git/objects中)。

工作區,暫存區和版本庫說明

技術分享圖片

  • 左側為工作區,右側為版本庫。在版本庫中標記為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分支的全部或部分文件替換暫存區和工作區中的文件,比較危險。

git學習(四):理解git暫存區(stage)