git 用 diff 來檢查改動


用 diff 來檢查改動

項目的開發是由無數個微小的改動組成的。了解項目開發過程的關鍵就是要搞清楚每一個改動。
當然你可以使用 “git status” 命令或更簡單的 “git log” 命令來打印出項目的狀態和歷史記錄,但是這些命令僅僅只能為你提供一個非常簡單的信息概要,想要顯示一個詳細的修改信息就必須使用另外一個命令。

讀懂 Diffs

在版本控制系統中用來顯示兩個版本之間差別的操作我們稱之為 “diff”,或者 “patch”。現在就讓我們來詳細地學習一下這個操作吧!首先要學習如何讀懂 diff 信息。

比較文件 a/b

這個 diff 操作會對兩個對象進行相互比較。比如對象 A 和對象 B 。在大多數情況下 A 和 B 會是項目中的同一個文件,但它們是基於不同的版本。當然 diff 操作也可以比較兩個完全沒有關聯的文件,並顯示出它們之間的差別,但是這種操作並不會被經常使用到。
為了清楚地顯示比較信息, diff 操作總是會把要比較的文件定義成 “A” 和 “B”。

文件的元數據 (Metadata)

這所說的文件元數據是非常技術性的,在實踐中你可能永遠不需要搞明白它。最開始的兩串數字表示兩個文件的 hashes(簡單點說就是它們的 “ID”)。不僅僅是整個項目,Git 還會把每一個文件當作對象來保存。這個 hash ID 就代表了一個文件對象的特定版本。最后的一串數字代表了一個文件的模式(100644 代表它是一個普通的文件,100755 表示一個可執行文件,120000 僅僅是一符號鏈接)。

標記 a/b

繼續向下觀察這些輸出信息,A 與 B 的真正差別會被顯示在這里。為了區分它們,A 和 B 都被賦予了它們特有的符號:對於版本 A,它的符號是一個減號(“-”);而對於版本 B ,它會使用一個加號(“+”)。

區塊(Chunk)

diff 操作不會顯示完整的文件內容。如果兩個版本僅僅存在兩行代碼的差別,你也不會想要去逐行地審視這個擁有上萬行代碼的文件吧。因此,Git 在這里只會標記出那些實際上修改的部分,在這里一段連續的改動被稱之為區塊(chunk 或者 hunk)。除了包括實際更改的代碼行,一個區塊還包括一個特定的 “上下文環境”,例如那些改變之前和之后的差別,能讓你更容易地明白在特定的上下文環境中這個改變的具體含義。

區塊標頭(Chunk Header)

每個這樣的區塊都有一個標頭,它被顯示在兩個 “@@” 符號中。在這里 Git 會告訴你哪些行存在差異。在我們的例子里這些行被標記成為第一個改動區塊:

  • 來自文件 A (標記為 “-”),從第34行開始之后的6行代碼。
  • 來自文件 B (標記為 “+”),從第34行開始之后的8行代碼。

在那個 “@@” 結束符號之后的信息是用來表明上下文環境的,例如 Git 會嘗試着為這個區塊賦予一個方法名稱或是其他的上下文信息。然而 Git 不能支持所有的文件內容,這很大程度上都要取決於項目所使用的開發語言。

改動

在每一個被改動過的代碼行之前都會前置一個 “+” 或是 “-” 符號。就像前面所講到的,這些符號可以幫助你准確了解版本 A 和 版本 B 。例如前置了 “-” 符號的行就代表來自版本 A,反之帶有符號 “+” 的行就代表來自於版本 B。
大多數情況下,在 Git 中都使用 A 和 B 這樣的方式,你可以認為 A/- 代表老的內容,而 B/+ 代表新的內容。

現在就讓我們來看一下我們的例子:

  • 改動 #1 包括兩行 “+” ,而在相對應的版本 A 中卻不存在這些行(沒有任何被前置 “-” 的行),這就表示這兩行是新被添加的。
  • 改動 #2 則恰恰相反。在版本 A 中,可以看到有兩行被前置上了符號 “-”。然而版本 B 卻不存在對應的行(沒有 “+” 行),這就表明這兩行被刪除了。
  • 在改動 #3 中,這些代碼行發生了一些改動,前置上符號 “-” 的兩行被修改了,新的改動就是在它的下面被標記了符號 “+” 的內容。

現在我們知道了如何讀懂 diff 的輸出信息了,來做一些練習吧!

檢查本地改動

在之前的章節里,我們經常會使用 “git status” 命令來查看在本地副本(working copy)中有哪些文件被改動了。如果要想清楚地了解這些改動的細節,我們就必須使用 “ git diff” 命令:

$ git diff diff --git a/about.html b/about.html index d09ab79..0c20c33 100644 --- a/about.html +++ b/about.html @@ -19,7 +19,7 @@ </div> <div id="headerContainer"> - <h1>About&lt/h1> + <h1>About This Project&lt/h1> </div> <div id="contentContainer"> diff --git a/imprint.html b/imprint.html index 1932d95..d34d56a 100644 --- a/imprint.html +++ b/imprint.html @@ -19,7 +19,7 @@ </div> <div id="headerContainer"> - <h1>Imprint&lt/h1> + <h1>Imprint / Disclaimer&lt/h1> </div> <div id="contentContainer"> 

在不帶任何參數的情況下,“git diff” 會為我們給所有在本地副本中還未被打包(unstaged)的變化做個比較,並顯示出來。
如果你僅僅是想要查看那些對於已被打包的改動的比較結果,你可以選擇使用 “git diff --staged” 命令。

檢查已提交的改動

你已經學習過了 “git log” 命令,它會打印出那些最新提交的概要。但是它僅僅顯示一些最基礎的信息(hash,作者,時間,注釋)。如果你想要查看那些改動的細節,你就可以加上 “-p” 參數來得到一個更詳細的修改信息。

比較分支和版本

最后,你可能想要知道如何比較兩個分支,或是兩個特定項目版本。來讓我們看看在 “contact-form” 分支的哪些改動並不存在於 “master” 上:

$ git diff master..contact-form

相反,這些比較信息僅僅是在分支層面上的,你也可以比較任意的兩個項目版本之間的內容:

$ git diff 0023cdd..fcd6199


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM