## git diff
最后,要查看兩個提交快照的絕對改動,你可以用?`git diff`?命令。 這在兩個主要情況中廣為使用 —— 查看兩個分支彼此之間的差值,和查看自發布或者某個舊歷史點之后都有啥變了。讓我們看看這倆情況。
你僅需執行?`git diff [version]`(或者你給該發布打的任何標簽)就可以查看自最近發布之后的改動。 例如,如果我們想要看看自 v0.9 發布之后我們的項目改變了啥,我們可以執行?`git diff v0.9`
~~~
$ git diff v0.9
diff --git a/README b/README
index d053cc8..d4173d5 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-Hello World Examples
+Many Hello World Lang Examples
======================
This project has examples of hello world in
diff --git a/ruby.rb b/ruby.rb
index bb86f00..192151c 100644
--- a/ruby.rb
+++ b/ruby.rb
@@ -1,7 +1,7 @@
-class HiWorld
+class HelloWorld
def self.hello
puts "Hello World from Ruby"
end
end
-HiWorld.hello
+HelloWorld.hello
~~~
正如?`git log`,你可以給它加上?`--stat`?參數。
~~~
$ git diff v0.9 --stat
README | 2 +-
ruby.rb | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
~~~
要比較兩個不同的分支,你可以執行類似?`git diff branchA branchB`?的命令。 不過它的問題在于它會完完全全按你說的作 —— 它會直接給你個補丁文件,該補丁能夠將甲分支的最新快照變成乙分支的最新快照的樣子。 這意味著如果兩個分支已經產生分歧 —— 奔往兩個不同方向了 —— 它會移除甲分支中引入的所有工作,然后累加乙分支中的所有工作。 這大概不是你要的吧 —— 你想要不在甲分支中的乙分支的改動。所以你真的需要的是兩個分支叉開去時,和最新的乙分支的差別。 所以,如果我們的歷史記錄看起來像這樣:
~~~
$ git log --graph --oneline --decorate --all
* 594f90b (HEAD, tag: v1.0, master) reverted to old class name
| * 1834130 (erlang) added haskell
| * ab5ab4c added erlang
|/
* 8d585ea Merge branch 'fix_readme'
...
~~~
并且,我們想要看“erlang”分支與主分支相比的查別。執行?`git diff master erlang`?會給我們錯誤的結果。
~~~
$ git diff --stat master erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
ruby.rb | 4 ++--
3 files changed, 11 insertions(+), 2 deletions(-)
~~~
你可以看到,它加上了 erlang 和 haskell 文件,這確實是我們在該分支中做的, 但是它同時恢復了我們在主分支中改動的 ruby 文件。我們真心想要的只是“erlang”分支中的改動(添加兩個文件)。 我們可以通過求兩個分支分歧時的共同提交與該分支的差值得到想要的結果:
~~~
$ git diff --stat 8d585ea erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
2 files changed, 9 insertions(+), 0 deletions(-)
~~~
這才是我們在找的,但是我們可不想要每次都要找出兩個分支分歧時的那次提交。 幸運的是,Git 為此提供了一個快捷方式。 如果你執行?`git diff master...erlang`(在分支名之間有三個半角的點), Git 就會自動找出兩個分支的共同提交(也被成為合并基礎),并求差值。
~~~
$ git diff --stat master erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
ruby.rb | 4 ++--
3 files changed, 11 insertions(+), 2 deletions(-)
$ git diff --stat master...erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
2 files changed, 9 insertions(+), 0 deletions(-)
~~~
幾乎每一次你要對比兩個分支的時候,你都會想用三個點的語法,因為它通常會給你你想要的。
順帶提一句,你還可以讓 Git 手工計算兩次提交的合并基礎(第一個共同的祖提交),即?`git merge-base`?命令:
~~~
$ git merge-base master erlang
8d585ea6faf99facd39b55d6f6a3b3f481ad0d3d
~~~
所以你執行下面這個也跟?`git diff master...erlang`?一樣:
~~~
$ git diff --stat $(git merge-base master erlang) erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
2 files changed, 9 insertions(+), 0 deletions(-)
~~~
當然,我會推薦簡單點的那個。
> **簡而言之**?使用?`git diff`?查看某一分支自它偏離出來起與過去某一點之間項目的改動。 總是使用?`git diff branchA...branchB`?來查看 branchB 與 branchA 的相對差值,這會讓事情簡單點。