## git diff
最后,要查看兩個(gè)提交快照的絕對(duì)改動(dòng),你可以用?`git diff`?命令。 這在兩個(gè)主要情況中廣為使用 —— 查看兩個(gè)分支彼此之間的差值,和查看自發(fā)布或者某個(gè)舊歷史點(diǎn)之后都有啥變了。讓我們看看這倆情況。
你僅需執(zhí)行?`git diff [version]`(或者你給該發(fā)布打的任何標(biāo)簽)就可以查看自最近發(fā)布之后的改動(dòng)。 例如,如果我們想要看看自 v0.9 發(fā)布之后我們的項(xiàng)目改變了啥,我們可以執(zhí)行?`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`?參數(shù)。
~~~
$ git diff v0.9 --stat
README | 2 +-
ruby.rb | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
~~~
要比較兩個(gè)不同的分支,你可以執(zhí)行類似?`git diff branchA branchB`?的命令。 不過它的問題在于它會(huì)完完全全按你說的作 —— 它會(huì)直接給你個(gè)補(bǔ)丁文件,該補(bǔ)丁能夠?qū)⒓追种У淖钚驴煺兆兂梢曳种У淖钚驴煺盏臉幼印?這意味著如果兩個(gè)分支已經(jīng)產(chǎn)生分歧 —— 奔往兩個(gè)不同方向了 —— 它會(huì)移除甲分支中引入的所有工作,然后累加乙分支中的所有工作。 這大概不是你要的吧 —— 你想要不在甲分支中的乙分支的改動(dòng)。所以你真的需要的是兩個(gè)分支叉開去時(shí),和最新的乙分支的差別。 所以,如果我們的歷史記錄看起來像這樣:
~~~
$ 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”分支與主分支相比的查別。執(zhí)行?`git diff master erlang`?會(huì)給我們錯(cuò)誤的結(jié)果。
~~~
$ git diff --stat master erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
ruby.rb | 4 ++--
3 files changed, 11 insertions(+), 2 deletions(-)
~~~
你可以看到,它加上了 erlang 和 haskell 文件,這確實(shí)是我們?cè)谠摲种е凶龅模?但是它同時(shí)恢復(fù)了我們?cè)谥鞣种е懈膭?dòng)的 ruby 文件。我們真心想要的只是“erlang”分支中的改動(dòng)(添加兩個(gè)文件)。 我們可以通過求兩個(gè)分支分歧時(shí)的共同提交與該分支的差值得到想要的結(jié)果:
~~~
$ git diff --stat 8d585ea erlang
erlang_hw.erl | 5 +++++
haskell.hs | 4 ++++
2 files changed, 9 insertions(+), 0 deletions(-)
~~~
這才是我們?cè)谡业?,但是我們可不想要每次都要找出兩個(gè)分支分歧時(shí)的那次提交。 幸運(yùn)的是,Git 為此提供了一個(gè)快捷方式。 如果你執(zhí)行?`git diff master...erlang`(在分支名之間有三個(gè)半角的點(diǎn)), Git 就會(huì)自動(dòng)找出兩個(gè)分支的共同提交(也被成為合并基礎(chǔ)),并求差值。
~~~
$ 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(-)
~~~
幾乎每一次你要對(duì)比兩個(gè)分支的時(shí)候,你都會(huì)想用三個(gè)點(diǎn)的語法,因?yàn)樗ǔ?huì)給你你想要的。
順帶提一句,你還可以讓 Git 手工計(jì)算兩次提交的合并基礎(chǔ)(第一個(gè)共同的祖提交),即?`git merge-base`?命令:
~~~
$ git merge-base master erlang
8d585ea6faf99facd39b55d6f6a3b3f481ad0d3d
~~~
所以你執(zhí)行下面這個(gè)也跟?`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(-)
~~~
當(dāng)然,我會(huì)推薦簡(jiǎn)單點(diǎn)的那個(gè)。
> **簡(jiǎn)而言之**?使用?`git diff`?查看某一分支自它偏離出來起與過去某一點(diǎn)之間項(xiàng)目的改動(dòng)。 總是使用?`git diff branchA...branchB`?來查看 branchB 與 branchA 的相對(duì)差值,這會(huì)讓事情簡(jiǎn)單點(diǎn)。
