常見名詞解釋:
倉庫(repository)
開始或停止跟蹤(track)文件
暫存(stage)
提交(commit)更改
請(qǐng)記住,你工作目錄下的每一個(gè)文件都不外乎這兩種狀態(tài):已跟蹤 或 未跟蹤。 已跟蹤的文件是指那些被納入了版本控制的文件,在上一次快照中有它們的記錄,在工作一段時(shí)間后, 它們的狀態(tài)可能是未修改,已修改或已放入暫存區(qū)。簡而言之,已跟蹤的文件就是 Git 已經(jīng)知道的文件。
工作目錄中除已跟蹤文件外的其它所有文件都屬于未跟蹤文件,它們既不存在于上次快照的記錄中,也沒有被放入暫存區(qū)。 初次克隆某個(gè)倉庫的時(shí)候,工作目錄中的所有文件都屬于已跟蹤文件,并處于未修改狀態(tài),因?yàn)?Git 剛剛檢出了它們, 而你尚未編輯過它們。
編輯過某些文件之后,由于自上次提交后你對(duì)它們做了修改,Git 將它們標(biāo)記為已修改文件。 在工作時(shí),你可以選擇性地將這些修改過的文件放入暫存區(qū),然后提交所有已暫存的修改,如此反復(fù)。

檢查當(dāng)前文件狀態(tài)
test@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
nothing to commit, working tree clean
這說明你現(xiàn)在的工作目錄相當(dāng)干凈。換句話說,所有已跟蹤文件在上次提交后都未被更改過。 此外,上面的信息還表明,當(dāng)前目錄下沒有出現(xiàn)任何處于未跟蹤狀態(tài)的新文件,否則 Git 會(huì)在這里列出來。
現(xiàn)在,讓我們?cè)陧?xiàng)目下創(chuàng)建一個(gè)新的 README 文件。 如果之前并不存在這個(gè)文件,使用 git status 命令,你將看到一個(gè)新的未跟蹤文件:
work@MacintoshdeMacBook-Pro-2:~/Git$ echo 'My Project' > README
work@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
在狀態(tài)報(bào)告中可以看到新建的 README 文件出現(xiàn)在Untracked files下面。 未跟蹤的文件意味著 Git 在之前的快照(提交)中沒有這些文件;Git 不會(huì)自動(dòng)將之納入跟蹤范圍,除非你明明白白地告訴它“我需要跟蹤該文件”。 這樣的處理讓你不必?fù)?dān)心將生成的二進(jìn)制文件或其它不想被跟蹤的文件包含進(jìn)來。 不過現(xiàn)在的例子中,我們確實(shí)想要跟蹤管理 README 這個(gè)文件。
跟蹤新文件
使用命令git add開始跟蹤一個(gè)文件。 所以,要跟蹤 README 文件,運(yùn)行:
work@MacintoshdeMacBook-Pro-2:~/Git$ ls -al
total 8
drwxr-xr-x 8 work staff 256 9 29 18:49 .
drwxr-xr-x+ 43 work staff 1376 9 29 18:41 ..
drwxr-xr-x 12 work staff 384 9 29 18:49 .git
-rw-r--r-- 1 work staff 0 9 29 18:38 LICENSE
-rw-r--r-- 1 work staff 11 9 29 18:49 README
-rw-r--r-- 1 work staff 0 9 29 18:35 testGit1.cpp
-rw-r--r-- 1 work staff 0 9 29 18:35 testGit2.cpp
-rw-r--r-- 1 work staff 0 9 29 18:35 testGit3.cpp
work@MacintoshdeMacBook-Pro-2:~/Git$ git add README
work@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
針對(duì)一個(gè)評(píng)審的總評(píng)論(區(qū)別于行間評(píng)論)尚未被計(jì)入
暫存已修改的文件
現(xiàn)在我們來修改一個(gè)已被跟蹤的文件。 如果你修改了一個(gè)名為 testGit1.cpp 的已被跟蹤的文件,然后運(yùn)行 git status 命令,會(huì)看到下面內(nèi)容:
work@MacintoshdeMacBook-Pro-2:~/Git$ vi testGit1.cpp
work@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: testGit1.cpp 針對(duì)一個(gè)評(píng)審的總評(píng)論(區(qū)別于行間評(píng)論)尚未被計(jì)入
文件 testGit1.cpp 出現(xiàn)在 Changes not staged for commit 這行下面,說明已跟蹤文件的內(nèi)容發(fā)生了變化,但還沒有放到暫存區(qū)。
現(xiàn)在讓我們運(yùn)行 git add將“testGit1.cpp”放到暫存區(qū),然后再看看 git status 的輸出:
chenshanshan05@MacintoshdeMacBook-Pro-2:~/Git$ git add testGit1.cpp
chenshanshan05@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: testGit1.cpp
現(xiàn)在兩個(gè)文件都已暫存,下次提交時(shí)就會(huì)一并記錄到倉庫。 假設(shè)此時(shí),你想要在 testGit1.cpp 里再加條注釋。 重新編輯存盤后,準(zhǔn)備好提交。 不過且慢,再運(yùn)行git status 看看:
work@MacintoshdeMacBook-Pro-2:~/Git$ vi testGit1.cpp
work@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: testGit1.cpp
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: testGit1.cpp modified: testGit1.cpp 針對(duì)一個(gè)評(píng)審的總評(píng)論(區(qū)別于行間評(píng)論)尚未被計(jì)入
怎么回事? 現(xiàn)在 testGit1.cpp文件同時(shí)出現(xiàn)在暫存區(qū)和非暫存區(qū)。 這怎么可能呢? 好吧,實(shí)際上 Git 只不過暫存了你運(yùn)行 git add 命令時(shí)的版本。 如果你現(xiàn)在提交,testGit1.cpp 的版本是你最后一次運(yùn)行 git add命令時(shí)的那個(gè)版本,而不是你運(yùn)行 git commit 時(shí),在工作目錄中的當(dāng)前版本。 所以,運(yùn)行了 git add 之后又作了修訂的文件,需要重新運(yùn)行 git add 把最新版本重新暫存起來
work@MacintoshdeMacBook-Pro-2:~/Git$ git add testGit1.cpp
work@MacintoshdeMacBook-Pro-2:~/Git$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: testGit1.cpp
狀態(tài)簡覽
git status 命令的輸出十分詳細(xì),但其用語有些繁瑣。 Git 有一個(gè)選項(xiàng)可以幫你縮短狀態(tài)命令的輸出,這樣可以以簡潔的方式查看更改。 如果你使用git status -s 命令或 git status --short 命令,你將得到一種格式更為緊湊的輸出。
work@MacintoshdeMacBook-Pro-2:~/Git$ touch LICENSE.txt
work@MacintoshdeMacBook-Pro-2:~/Git$ git status -s
A README
M testGit1.cpp
?? LICENSE.txt
- 新添加的未跟蹤文件前面有 ?? 標(biāo)記
- 新添加到暫存區(qū)中的文件前面有 A 標(biāo)記
- 修改過的文件前面有 M 標(biāo)記
忽略文件
一般我們總會(huì)有些文件無需納入 Git 的管理,也不希望它們總出現(xiàn)在未跟蹤文件列表。 通常都是些自動(dòng)生成的文件,比如日志文件,或者編譯過程中創(chuàng)建的臨時(shí)文件等。 在這種情況下,我們可以創(chuàng)建一個(gè)名為 .gitignore 的文件,列出要忽略的文件的模式。 來看一個(gè)實(shí)際的.gitignore 例子:
work@MacintoshdeMacBook-Pro-2:~/Git$ cat .gitignore
*.[oa]
*~
第一行告訴 Git 忽略所有以.o或.a結(jié)尾的文件。一般這類對(duì)象文件和存檔文件都是編譯過程中出現(xiàn)的。 第二行告訴 Git 忽略所有名字以波浪符(~)結(jié)尾的文件,許多文本編輯軟件(比如 Emacs)都用這樣的文件名保存副本。 此外,你可能還需要忽略 log,tmp 或者 pid 目錄,以及自動(dòng)生成的文檔等等。 要養(yǎng)成一開始就為你的新倉庫設(shè)置好 .gitignore 文件的習(xí)慣,以免將來誤提交這類無用的文件。
文件 .gitignore 的格式規(guī)范如下:
- 所有空行或者以 # 開頭的行都會(huì)被 Git 忽略。
- 可以使用標(biāo)準(zhǔn)的 glob 模式匹配,它會(huì)遞歸地應(yīng)用在整個(gè)工作區(qū)中。
- 匹配模式可以以(/)開頭防止遞歸。
- 匹配模式可以以(/)結(jié)尾指定目錄。
- 要忽略指定模式以外的文件或目錄,可以在模式前加上嘆號(hào)(!)取反。
gitHub 有一個(gè)十分詳細(xì)的針對(duì)數(shù)十種項(xiàng)目及語言的 .gitignore 文件列表: https://github.com/github/gitignore
查看已暫存和未暫存的修改
git diff此命令比較的是工作目錄中當(dāng)前文件和暫存區(qū)域快照之間的差異。 也就是修改之后還沒有暫存起來的變化內(nèi)容。
提交更新
現(xiàn)在的暫存區(qū)已經(jīng)準(zhǔn)備就緒,可以提交了。 在此之前,請(qǐng)務(wù)必確認(rèn)還有什么已修改或新建的文件還沒有 git add 過, 否則提交的時(shí)候不會(huì)記錄這些尚未暫存的變化。 這些已修改但未暫存的文件只會(huì)保留在本地磁盤。 所以,每次準(zhǔn)備提交前,先用 git status 看下,你所需要的文件是不是都已暫存起來了, 然后再運(yùn)行提交命令 git commit:
git commit
移出文件
要從 Git 中移除某個(gè)文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區(qū)域移除),然后提交。 可以用 git rm 命令完成此項(xiàng)工作,并連帶從工作目錄中刪除指定的文件,這樣以后就不會(huì)出現(xiàn)在未跟蹤文件清單中了。
如果只是簡單地從工作目錄中手工刪除文件,運(yùn)行 git status 時(shí)就會(huì)在 “Changes not staged for commit” 部分(也就是 未暫存清單)