Git 系列教程(5)- 記錄每次更新到倉庫

小菠蘿測試筆記發表於2021-05-15

檔案狀態

你工作目錄下的每一個檔案只有兩種狀態:tracked 或 untracked

 

tracked

  • 已跟蹤 tracked 的檔案是指那些被納入了版本控制的檔案
  • 在上一次快照中有它們的記錄,在工作一段時間後, 它們的狀態可能是未修改unmodified、已修改modified 或已放入暫存區staged
  • 簡單來說,已跟蹤 tracked 的檔案就是 Git 知道的檔案

 

untracked

  • 工作目錄中除 tracked 檔案外的其它所有檔案都屬於 untracked 檔案
  • 它們既不存在於上次快照的記錄中,也沒有被放入暫存區
  • 初次 clone 某個倉庫的時候,工作目錄中的所有檔案都屬於 tracked 檔案,並處於 unmodified
  • 編輯檔案後,Git 將它們標記為 modified 檔案。 在工作時,你可以選擇性地將這些修改過的檔案放入暫存區,然後提交所有已暫存的修改

 

檔案的狀態變化週期

Git 下檔案生命週期圖。
 

檢查當前檔案狀態

可以用 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

 

相關文章