#### 查看工作區文件的改動
~~~
$ git diff 工作區與提交任務(提交暫存區,stage)中相比的差異
$ git diff HEAD 工作區和HEAD(當前工作分支)相比的差異
$ git diff --cached (或--staged)提交暫存區(提交任務,stage)和版本庫中文件的差異
$ git status 顯示狀態 -s表示用精簡方式
~~~ -b同時顯示當前工作分支的名稱
其中標識有兩列,拿狀態M來說
第一列含義是:版本庫中的文件與處于中間狀態——提交任務(提交暫存區,stage)中的文件相比有改動
第二列含義是:工作區當前的文件與處于中間狀態——提交任務(提交暫存區,stage)中的文件相比有改動
文件./git/index實際上是一個包含文件索引的目錄樹,像一個虛擬的工作區。在這個虛擬工作區的目錄樹中,記錄了文件名和文件的狀態信息(時間戳和文件長度等)。文件的內容并沒有存儲在其中,而是保存在Git對象庫.git/objects目錄中,文件索引建立了文件和對象庫中對象實體之間的對應。

圖中左側為工作區,右側為版本庫。在版本庫中標記為 "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 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。這個命令也是極具危險性的,因為不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改動。
### 目錄樹的瀏覽
$ git ls-tree -l HEAD 查看HEAD(版本庫中當前提交)指向的目錄樹 -l參數可以顯示文件大小
輸出的文件條目從左至右,第一個字段是文件的屬性,第二個字段(blob)說明是Git對象庫中的一個blob對象(文件),第三個字段是該文件在對象庫中對應的ID——一個40位的SHA1哈希值格式的ID,第四個字段是文件大小,第五個字段是文件名。
在瀏覽暫存區的目錄樹之前,首先清除工作區當前的改動。
$ git clean -fd 清除當前工作區中沒有加入版本庫的文件和目錄(非跟蹤文件和目錄),然后執行$ git checkout .命令,用暫存區內容刷新工作區。
$ git ls-files -s 顯示暫存區的目錄樹,其中第三個字段不是文件大小而是暫存區編號
若想針對暫存區的目錄樹使用git ls-tree命令,需要先將暫存區的目錄樹寫入Git對象庫,然后針對該目錄樹執行git ls-tree命令
$ git write-tree 輸出的就是寫入Git對象庫的TreeID,這個ID將作為下一條命令的輸入
5b873f747ccb268e4491f289eb37fc675ff5825b
$ git ls-tree -l 5b873f747 只需寫前幾位,只要不與其他對象的ID沖突即可
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad ? ? ?12test
可以看出到處都是40位的SHA1哈希值格式的ID,可以用于指代文件內容(blob)、目錄樹(tree)和提交。
$ git write-tree | xargs git ls-tree -l -r -t 遞歸顯示目錄內容使用-r參數,顯示遞歸過程中遇到的每棵樹而不是只顯示最終文件使用-t參數
### 不要使用git commit -a
帶上此參數,對本地所有變更的文件執行提交操作,包括對本地修改的文件和刪除的文件,但不包括未被版本庫跟蹤的文件。可以簡化一些操作,減少用git add命令標識變更文件的步驟,但是丟掉了對提交內容進行控制的能力。
### 保存當前工作進度
$ git stash 運行完此命令后再查看工作區狀態,會發現工作區尚未提交的改動(包括暫存區的改動)全都不見了