能夠認爲使用Git時,咱們會遇到3個空間:工做目錄、索引、版本庫。咱們關心的,就是在新建、修改等操做時,這三者之間發生了怎樣的變化。git
籠統的講,就是在工做目錄下編輯,在索引中積累修改,而後把索引中累計的修改做爲一次性的變動提交給版本庫。shell
這就意味着,能夠在最終提交前添加、刪除、移動或者重複編輯文件,只有在提交後纔會在版本庫裏實現累計的變動。bash
本章將介紹如何管理索引和文件。測試
Git的索引不包含任何文件內容,它僅僅追蹤你想要提交的那些內容。這一點,咱們能夠在後面的圖示中看到。當git commit時,會經過檢查索引而不是工做目錄來找到提交的內容。spa
在暫存的過程當中,git diff將會是一個很是有用的命令。命令行
git diff 顯示仍留在工做目錄中且爲暫存的變動。code
git diff –cached 顯示已經暫存而且要在下一次提交的變動。對象
Git將全部的文件分爲3類:已追蹤的、被忽略的、未追蹤的。blog
這裏經過建立一個全新的工做目錄並處理一下文件來看一下這些不一樣類別的文件。索引
在工做目錄中常常會產生一下臨時文件,在版本庫中這些文件一般是不該該被當作源文件追蹤的。
爲了讓Git忽略這些文件,只須要將該文件名添加到一個特殊的文件.gitignore中就能夠了
上圖中的步驟中咱們看到了這種變化。須要注意的是,雖然.gitignore對於Git是個特殊的文件,可是也須要手動的添加到索引中。
git add將暫存一個文件。看看例子就行了。
[root@flower1 my_stuff]# git status # On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # .gitignore # data nothing added to commit but untracked files present (use "git add" to track) [root@flower1 my_stuff]# git add data .gitignore [root@flower1 my_stuff]# git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitignore # new file: data #
[root@flower1 my_stuff]# git ls-files --stage
上面的這個實驗蠻有意思。當咱們修改了data這個文件後,文件自己的SHA1散列碼已經改變,可是git ls-files –stage沒有發生變化。只有到使用git add命令後才發生變化。這是由於,索引以後指向已經存在於對象庫中的blob對象。
git commit -a或者-all選項會致使執行提交前自動暫存全部未暫存的和未追蹤的文件變化,包括從工做副本中刪除已追蹤的文件。
作個試驗來驗證一下。這裏就不截圖了。
試驗的結果是:上面的說法感受有歧義。所謂的自動暫存,是有前提的,前提是這些文件自己就已經在版本庫中或者已經在索引中。(這是我測試的結果,不知是否真的正確)
Git能夠在索引中或者同時在索引和工做目錄中刪除一個文件,可是不能刪除該文件在版本庫中的歷史記錄。
git rm -f file1會從索引和工做目錄中同時刪除
git rm –cached file2 僅刪除索引中的文件
下面驗證一下:
[root@flower1 committest]# ls newfile notyet.txt ready.txt [root@flower1 committest]# rm newfile rm: remove regular file `newfile'? y [root@flower1 committest]# ls notyet.txt ready.txt [root@flower1 committest]# echo "new file" > newfile [root@flower1 committest]# ls newfile notyet.txt ready.txt [root@flower1 committest]# git add newfile [root@flower1 committest]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: newfile # [root@flower1 committest]# git rm --cached newfile rm 'newfile' [root@flower1 committest]# git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # newfile nothing added to commit but untracked files present (use "git add" to track) [root@flower1 committest]# ls newfile notyet.txt ready.txt
上面的試驗,使用了—cached參數,工做目錄中的文件沒有刪除。
[root@flower1 committest]# git add newfile [root@flower1 committest]# git rm -f newfile rm 'newfile' [root@flower1 committest]# ls notyet.txt ready.txt
想要移除一個已經提交的文件,經過git rm和git commit的組合命令便可實現。
這裏僅用命令行說明一下吧 。
[root@flower1 committest]# ls notyet.txt ready.txt [root@flower1 committest]# git mv ready.txt ready.txt.bak [root@flower1 committest]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: ready.txt -> ready.txt.bak # [root@flower1 committest]# git commit -m "new data ty" [master 2a9b527] new data ty 1 files changed, 0 insertions(+), 0 deletions(-) rename ready.txt => ready.txt.bak (100%) [root@flower1 committest]# git log ready.txt.bak commit 2a9b52785b94c45852276c4febb4e05d9e25de1f Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:16:59 2015 +0800 new data ty [root@flower1 committest]# get log --follow ready.txt.bak -bash: get: command not found [root@flower1 committest]# git log --follow ready.txt.bak commit 2a9b52785b94c45852276c4febb4e05d9e25de1f Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:16:59 2015 +0800 new data ty commit 1e5f4c75d4b1c6055fe68392fe0a431d9039870a Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:01:09 2015 +0800 yes [root@flower1 committest]# ls notyet.txt ready.txt.bak
略。
這個文件中的內容能夠比較靈活,格式以下:
當有多個層次的目錄都有.gitignore文件時,優先級從高到低以下:
這一節主要經過幾張圖來講明各類變化。
下面這張圖展現的是提交了2個文件的版本庫視圖。工做目錄、索引以及對象庫都是同步和一致的。
接着咱們在工做目錄裏對file1進行編輯,如今它的內容包含「quux.」
而後使用git add命令,將file1內容提交到對象庫中:
最後,執行git commit命令: