文件狀態
你工作目錄下的每一個文件只有兩種狀態:tracked 或 untracked
tracked
- 已跟蹤 tracked 的文件是指那些被納入了版本控制的文件
- 在上一次快照中有它們的記錄,在工作一段時間后, 它們的狀態可能是未修改unmodified、已修改modified 或已放入暫存區staged
- 簡單來說,已跟蹤 tracked 的文件就是 Git 知道的文件
untracked
- 工作目錄中除 tracked 文件外的其它所有文件都屬於 untracked 文件
- 它們既不存在於上次快照的記錄中,也沒有被放入暫存區
- 初次 clone 某個倉庫的時候,工作目錄中的所有文件都屬於 tracked 文件,並處於 unmodified
- 編輯文件后,Git 將它們標記為 modified 文件。 在工作時,你可以選擇性地將這些修改過的文件放入暫存區,然后提交所有已暫存的修改
文件的狀態變化周期
檢查當前文件狀態
可以用 git status 命令查看哪些文件處於什么狀態。 如果在克隆倉庫后立即使用此命令,會看到類似這樣的輸出:
git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean
可以獲取到的內容
- 所有 tracked 件在上次提交后都未被更改過
- 當前目錄下沒有出現任何 untracked 的新文件,否則 Git 會在這里列出來
- 還顯示了當前所在分支,並告訴你這個分支同遠程服務器上對應的分支沒有偏離,現在,分支名是“master”,這是默認的分支名
在項目下創建一個新的 README 文件,使用 git status 命令,將看到一個新的 untracked 文件
echo 'My Project' > README $ git status On branch master Your branch is up-to-date with 'origin/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)
可以獲取到的內容
-
README文件出現在Untracked files下面 - untracked 的文件意味着 Git 在之前的快照(提交)中沒有這些文件
如何跟蹤
git add 文件名
# 更新目錄下所有文件
git add .
后面會再詳細講這個命令
跟蹤新文件
使用命令 git add 開始跟蹤一個文件。 所以,要跟蹤 README 文件,運行:
git add README
此時再運行 git status 命令,會看到 README 文件已被跟蹤,並處於 staged
git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: README
可以獲取到的內容
- 只要在
Changes to be committed這行下面的,就說明是 staged 狀態 - 如果此時提交,那么該文件在你運行
git add時的版本將被留存在后續的歷史記錄中
暫存已修改的文件
如果修改了一個名為 CONTRIBUTING.md 的已被 tracked 的文件,然后運行 git status 命令,會看到下面內容
git status On branch master Your branch is up-to-date with 'origin/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: CONTRIBUTING.md
可以獲取到的內容
CONTRIBUTING.md出現在Changes not staged for commit這行下面,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區- 要暫存這次更新,需要運行
git add命令
再次運行 git add 命令
運行 git add 將“CONTRIBUTING.md”放到暫存區,然后再看看 git status 的輸出:
$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md
再次修改文件內容
編輯 CONTRIBUTING.md,再運行 git status 看看
$ vim CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md 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: CONTRIBUTING.md
可以獲取到的內容
CONTRIBUTING.md文件同時出現在暫存區和非暫存區- 實際上 Git 只不過暫存了運行
git add命令時的版本 - 如果你現在提交代碼,
CONTRIBUTING.md的版本是你最后一次運行git add命令時的那個版本,而不是當前版本 - 所以,運行了
git add之后又編輯了文件,需要再次git add把最新版本暫存
$ git add CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: README modified: CONTRIBUTING.md
真實的實際操作栗子
狀態簡述
git status命令的輸出十分詳細,但其用語有些繁瑣git status -s或git status --short,輸出結果更加簡潔
git status -s
M markers.py
M test.py
D test_func01.py
D test_login.py
?? text.txt
查看已暫存和未暫存的修改
修改 README 文件后暫存,然后編輯 CONTRIBUTING.md 文件后先不暫存, 運行 status 命令將會看到:
$ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: 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: CONTRIBUTING.md
初次使用 git diff
要查看尚未暫存的文件更新了哪些部分,不加參數直接輸入 git diff:
$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if your patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's
實際栗子

git diff 的作用
- 比較的是當前文件和暫存區快照之間的差異,也就是修改之后還沒有暫存起來的變化內容
- 若要查看已暫存且要添加到下次提交里的內容,可以用
git diff --staged命令 - 會比較已暫存文件與最后一次提交的文件差異
$ git diff --staged diff --git a/README b/README new file mode 100644 index 0000000..03902a1 --- /dev/null +++ b/README @@ -0,0 +1 @@ +My Project
git diff
git diff 本身只顯示尚未暫存的改動,而不是自上次提交以來所做的所有改動,所以有時候一下子暫存了所有更新過的文件,運行 git diff 后卻什么也沒有
像之前說的,暫存 CONTRIBUTING.md 后再編輯,可以使用 git status 查看已被暫存的修改或未被暫存的修改。 如果我們的環境(終端輸出)看起來如下:
$ git add CONTRIBUTING.md $ echo '# test line' >> CONTRIBUTING.md $ git status On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: CONTRIBUTING.md 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: CONTRIBUTING.md
現在運行 git diff 看暫存前后的變化:
$ git diff diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 643e24f..87f08c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,3 +119,4 @@ at the ## Starter Projects See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md). +# test line
然后用 git diff --cached 查看已經暫存起來的變化( --staged 和 --cached 是同義詞):
$ git diff --cached diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8ebb991..643e24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,8 @@ branch directly, things can get messy. Please include a nice description of your changes when you submit your PR; if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change -merged in. +merged in. Also, split your changes into comprehensive chunks if your patch is +longer than a dozen lines. If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's
實際栗子

提交更新
- 現在的暫存區已經准備就緒,可以提交了
- 在此之前,請務必確認還有什么已修改或新建的文件還沒有
git add過, 否則提交的時候不會記錄這些尚未暫存的變化 - 這些已修改但未暫存的文件只會保留在本地磁盤
- 所以,每次准備提交前,先用
git status看下,你所需要的文件是不是都已暫存起來了, 然后再運行提交命令git commit:
git commit -m "test"

可以獲取到的內容
- commit 之后 git status 可以看到本地是干凈的
- 提交后會顯示當前是在哪個分支(
master)提交的 - 本次提交的完整 SHA-1 校驗和是什么(
9a8c6b3) - 以及在本次提交中,有多少文件修訂過,多少行添加和刪改過
重點
- 提交時(git commit)記錄的是放在暫存區域的快照
- 每一次運行提交操作,都是對項目作一次快照,以后可以回到指定快照版本,或者進行比較
跳過使用暫存區域
- Git 提供了一個跳過使用暫存區域的方式
git commit加上-a選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一並提交,從而跳過git add步驟

-a 選項使本次提交包含了所有修改過的文件,但是要小心,有時這個選項會將不需要的文件添加到提交中
移除文件
兩種情況
- 直接刪除文件(從本地刪除):-f 參數
- 只是將文件從 Git 的暫存區移除,並不會刪除本地文件:--cached
直接看栗子

已跟蹤的文件(出現在暫存區)的文件被執行 git rm --cached 命令后,它會被移出暫存區,重新變成一個未跟蹤的文件
移動文件
在 Git 中對文件改名
$ git mv file_from file_to
查看狀態信息,也會看到關於重命名操作的說明

文件會自動提交到暫存區,且不需要手動執行 git add
其實,運行 git mv 就相當於運行了下面三條命令
$ mv README.md README $ git rm README.md $ git add README
