檔案狀態
你工作目錄下的每一個檔案只有兩種狀態: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