git diff 命令淺析

Gold_stein發表於2024-09-05

git diff 命令淺析

以下內容來自GPT的chat

請向我介紹git diff命令的用法

git diff 是 Git 中用於比較不同版本之間的改動的一個非常重要的命令。它可以比較工作區、暫存區和提交歷史中的差異,幫助開發者理解和檢視程式碼的變化情況。

git diff 的基本用法

  1. 比較工作區和暫存區
    當你對檔案進行修改但沒有將其新增到暫存區時,git diff 會顯示工作區中的改動與暫存區中的差異。

    git diff
    
    • 該命令會顯示當前檔案在工作區中的未暫存更改,和暫存區中已追蹤檔案的對比。
  2. 比較暫存區和最新的提交
    使用 git diff --stagedgit diff --cached 來檢視已經暫存的更改與最後一次提交之間的差異。

    git diff --staged
    git diff --cached
    
    • 該命令展示了已經暫存(已新增到 git add)但還沒有被提交的更改。
  3. 比較兩個提交之間的差異
    你可以指定兩個提交(commit)的雜湊值或標籤來比較它們之間的差異。

    git diff <commit1> <commit2>
    

    例如:

    git diff 1a2b3c4d 5f6g7h8i
    
    • 該命令會顯示 commit1commit2 之間的所有差異。
  4. 比較檔案在兩個提交之間的差異
    如果你只想檢視某個檔案在兩個提交之間的差異,可以在 git diff 後加上檔名。

    git diff <commit1> <commit2> -- <file>
    

    例如:

    git diff HEAD~1 HEAD -- myfile.txt
    
    • 該命令會顯示 myfile.txt 在最近的提交和前一次提交之間的差異。
  5. 比較分支之間的差異
    git diff 還可以用於比較不同分支之間的差異。

    git diff <branch1> <branch2>
    

    例如:

    git diff main feature-branch
    
    • 該命令會顯示 main 分支與 feature-branch 分支之間的差異。
  6. 比較檔案或目錄的差異
    你可以只檢視某個檔案或某個目錄的差異,而不是整個專案的差異。

    git diff <file_or_directory>
    

    例如:

    git diff src/
    
    • 這會顯示 src 目錄下的檔案的差異。
  7. 檢視統計資訊
    使用 --stat 引數,可以檢視差異的統計資訊,顯示各個檔案的修改行數等概況,而不顯示具體的程式碼更改。

    git diff --stat
    

    輸出示例:

    file1.txt | 10 +++++-----
    file2.txt | 5 ++++-
    2 files changed, 8 insertions(+), 7 deletions(-)
    
  8. 檢視簡短摘要
    使用 --summary 引數可以檢視簡短的摘要資訊,例如檔案的新增、刪除、重新命名等操作,而不顯示具體的程式碼差異。

    git diff --summary
    
  9. 忽略空白字元的變化
    如果你的更改只涉及空格、縮排等空白字元,可以透過 -w 引數忽略這些差異。

    git diff -w
    

    這對於檢視空白字元沒有實際影響的程式碼變化時非常有用。

git diff 的高階用法

  1. 比較遠端分支的差異
    你可以比較遠端分支和本地分支之間的差異。例如:

    git diff origin/main
    
    • 該命令會比較本地當前分支和遠端 main 分支的差異。
  2. 檢視具體檔案型別的差異
    使用 -- 來限定檔案的字尾或名稱,可以僅檢視某種型別檔案的差異。

    git diff HEAD -- '*.py'
    
    • 這個命令會檢視 .py 檔案(Python 檔案)的差異。
  3. 與指定的父提交比較
    對於合併提交,git diff 可以比較不同的父提交。預設情況下,git diff 比較的是當前提交和第一個父提交。你可以使用 git diff <commit>^1git diff <commit>^2 來分別檢視與第一個和第二個父提交的差異。

    例如:

    git diff HEAD^1
    
  4. 生成補丁檔案
    如果你想將差異儲存為一個補丁檔案,可以使用以下命令生成補丁:

    git diff > changes.patch
    

    這會將當前未提交的更改儲存到 changes.patch 檔案中,稍後你可以用 git apply changes.patch 來重新應用這些改動。

總結

  • git diff 可以比較工作區、暫存區、不同提交、分支或特定檔案之間的差異。
  • git diff --staged 檢視已暫存但未提交的更改。
  • 你可以透過指定兩個提交、分支或檔案來比較不同版本之間的差異。
  • 你還可以使用引數 --stat--summary-w 等選項檢視差異的統計資訊、忽略空白字元等。

git diff 是 Git 中非常強大的命令,透過靈活使用各種引數,你可以高效地追蹤和檢視專案中的變化。

我知道被git add新增的改動屬於暫存區,已經被commit的改動是否屬於暫存區?

已經被 git commit 的改動不再屬於暫存區,而是被永久記錄到版本歷史中。暫存區用於暫時存放已準備好提交的更改,而一旦執行了 git commit,這些更改就會從暫存區轉移到 Git 的版本歷史記錄中,成為提交(commit)的一部分。

Git 的三個主要區域:

  1. 工作區(Working Directory):這是你實際編輯檔案的地方。當你修改檔案後,改動會首先體現在工作區中。

  2. 暫存區(Staging Area):透過 git add 命令,你將工作區的改動(檔案的修改、新增或刪除)放入暫存區,準備提交。暫存區是一箇中間狀態,儲存著即將提交的更改。

  3. 版本庫(Repository/Commit History):執行 git commit 後,暫存區的內容會被提交到 Git 的版本庫(commit history)中,這些更改成為一個新的提交,並從暫存區中移除。

工作流程示例:

  1. 修改檔案後,改動會出現在工作區中。
  2. 透過 git add 命令將更改新增到暫存區。
  3. 執行 git commit 後,這些改動被提交到 Git 歷史記錄中,成為不可更改的一個提交。

總結

  • 暫存區:是用來臨時存放已經透過 git add 準備好提交的改動。
  • 提交後的改動:提交後,改動會從暫存區轉移到版本庫(歷史記錄)中,暫存區此時為空,等待新的改動進入。

進一步解釋

你提到的輸出與 Git 的工作區、暫存區和提交歷史的工作原理有關。我們來逐步分析。

1. 背景

在教程中的例子中,執行了以下操作:

  1. 建立了一個新的 Git 倉庫,並新增了檔案 diff_test.txt
  2. 提交了初始檔案內容 "this is a git diff test example"
  3. 然後透過 echo 修改了 diff_test.txt,將其內容改為 "this is a diff example"

2. git diff 輸出的含義

當你執行 git diff 時,它會顯示工作區與暫存區的差異。這個差異是在工作區中的修改內容(即最新更改的內容)與暫存區中的內容(即最近一次 git addgit commit 後的內容)進行比較。

此時,你還沒有執行 git add,所以:

  • 暫存區(Staging Area):暫存區仍然包含上一次提交的內容,即 "this is a git diff test example"
  • 工作區(Working Directory):工作區已經更新,內容變為 "this is a diff example"

3. 為什麼暫存區不是空的?

暫存區在這個階段並不是“空”的,因為它仍然包含上一次提交的狀態。當你提交了檔案之後,Git 會將檔案的當前狀態儲存在版本庫中,同時它也會把這個狀態同步到暫存區。因此,暫存區儲存的是你最新一次提交的內容,即 "this is a git diff test example"

  • 工作區的更改(修改後的內容)是 "this is a diff example"
  • 暫存區的內容 是上一次提交的內容,即 "this is a git diff test example"

因此,git diff 的輸出是工作區與暫存區的差異,它顯示了兩者之間的不同。

4. git diff 輸出解釋

當你執行 git diff 後,輸出顯示了工作區和暫存區之間的差異:

diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

這個輸出表示:

  • --- a/diff_test.txt 表示暫存區中的檔案版本(即上次提交的狀態)。
  • +++ b/diff_test.txt 表示工作區中的檔案版本(當前修改的檔案內容)。
  • - 表示檔案中被刪除的行,即 "this is a git diff test example"(暫存區的內容)。
  • + 表示檔案中被新增的行,即 "this is a diff example"(工作區的內容)。

5. 暫存區與工作區的區別

  • 工作區 是你當前編輯檔案的地方,包含所有未提交的修改。
  • 暫存區 是一箇中間層,包含你透過 git add 新增的更改,準備提交的狀態。
  • 提交歷史 則是已經提交到 Git 倉庫的檔案狀態。

在這個例子中:

  • 暫存區的內容是 "this is a git diff test example",這是你上一次提交的檔案內容。
  • 工作區的內容是 "this is a diff example",這是你剛剛修改後的內容,但還沒有新增到暫存區。

git diff 顯示的是工作區和暫存區之間的差異。

6. 如何清空暫存區?

暫存區的內容通常是上一次提交或透過 git add 命令新增的更改。如果你要清空暫存區,可以透過 git reset 來將暫存區恢復到上一次提交的狀態,從而使暫存區與最新提交保持一致。

總結

  • 暫存區不是空的:因為它儲存了上一次提交的內容。
  • git diff 顯示的是工作區(你當前修改的檔案)和暫存區(上一次提交的檔案內容)之間的差異。

易錯點

在commit之後,暫存區不會被清空,暫存區仍會保持上次add時的狀態;
reset命令可以清空暫存區。