2011-12-20 115 views
18

有沒有方法可以測試兩個差異或補丁是否相等?有沒有辦法比較兩個差異或補丁?

比方說,你有以下git的承諾的歷史,這裏擁有F和G是乾淨rebaseable到E:在我國目前的部署過程

 G 
    /
A--B--C--D--E 
\ 
    F 

由於限制,我們有以下幾點,有點關係圖(它不是版本控制)

   G' 
      /
------------E' 
      \ 
       F' 

F「和G」將最終施加到頭部E」,在一些被確定的順序,所以它最終會像

------------E'--G'--F' 

有沒有一種方法來測試從E'到G'的差異是否與由G的git提交產生的​​補丁相同?

我完全認識到,在理想的世界中,修訂控制可以解決這個問題,而且我們已經到了那裏,但那不是我們目前的狀況。

你基本上可以在單獨的結帳中播放這兩個補丁並比較輸出,但這看起來有點笨拙。比較差異本身,我假設,行不通,因爲行號可能會改變。即使G'和F'被重新定位爲E',F'的補丁最終也會應用到G',從而使補丁的不同背景變得不同。

+2

你嘗試差異比較? – Geoffroy 2011-12-20 01:35:52

+0

Gnu diff有一個命令行開關,用於在生成diff時指定要忽略的行的正則表達式。 – holygeek 2011-12-20 01:37:15

+0

對於批處理,'git patch-id'和'git cherry'(也可以參見'--cherry *'git log選項)可能被用作快速回答,但它太嚴格了,可以考慮一些重要的小改動。差異比較是您需要某些答案時的方法 – max630 2016-08-11 09:18:27

回答

1

我只想讓git試一試,看看:

git checkout E -b FG 
git cherry-pick F' G' 
git checkout E -b GF 
git cherry-pick G' F' 
git diff FG GF 
git branch -D FG GF 
+0

「主要」提交不在版本控制中。它們實際上不是提交,它們是基於真實提交E和F的補丁。但它們可能會或可能未被其他一些數據污染(這是我測試的內容)。 – 2011-12-20 03:03:20

+0

你可以申請補丁嗎?區別不是區分,但git真的很擅長。也許是錘子/釘子的情況,但我相信它會起作用。 :) – dahlbyk 2011-12-20 12:59:53

+0

你是什麼意思「只應用補丁」?我有兩個差異,我只想申請補丁,如果他們是相同的。如果不是,則補丁不應該被應用。 – 2011-12-20 15:44:11

23
diff <(git show COMMIT1SHA) <(git show COMMIT2SHA) 
+2

你可以添加一些關於如何回答這個問題的上下文嗎? – Chrismas007 2015-01-23 19:48:32

+1

它比較(差異)兩個差異(在這種情況下兩個不同承諾的差異)。 – mrbrdo 2015-02-20 20:21:08

+1

它會對提交的實際更改以及提交的元數據(sha,作者,日期,提交消息等)進行差異化。 我已經使用這個來檢查在不同分支中的兩個提交是否引入了相同的更改,以確保我可以使用它們中的任何一個來進行櫻桃選擇。 – 2015-07-03 07:15:35

0

爲了讀者的利益,這裏是一個更新the answer of @mrbrdo一個小的調整:

  • 添加git sdiff別名爲了方便訪問這個。 sdiff代表show diff
  • 使用^{}後綴忽略帶註釋的標籤標題。
  • 允許使用像每一個您使用git帳戶的-u

運行這個曾經diff選擇:

git config --global alias.sdiff '!'"bash -c 'O=(); A=(); while x=\"\$1\"; shift; do case \$x in -*) O+=(\"\$x\");; *) A+=(\"\$x^{}\");; esac; done; g(){ git show \"\${A[\$1]}\" && return; echo FAIL \${A[\$1]}; git show \"\${A[\$2]}\"; }; diff \"\${O[@]}\" <(g 0 1) <(g 1 0)' --" 

之後,您可以使用此:

git sdiff F G 

請注意,這需要bash版本3或更高版本。

解釋:

  • git config --global alias.sdiff添加一個名爲git sdiff到全球~/.gitconfig的別名。

  • !運行別名shell命令

  • bash -c我們需要bash(或ksh),爲<(..)dash(又名。/bin/sh)工作。

  • O=(); A=(); while x="$1"; shift; do case $x in -*) O+=("$x");; *) A+=("$x^{}");; esac; done;分隔選項(-something)和參數(其他所有內容)。選項在數組O中,而參數在數組A中。請注意,所有參數也都附有^{},這些參數可以在註釋上使用(例如可以使用帶註釋的標籤)。

  • g(){ git show "${A[$1]}" && return; echo FAIL ${A[$1]}; git show "${A[$2]}"; };創建一個輔助函數,它爲第一個參數提供git show。如果失敗,則輸出「FAIL first-argument」,然後輸出第二個參數。這是減少發生故障時的開銷的一個技巧。 (正確的錯誤同治將太多。)

  • diff "${O[@]}" <(g 0 1) <(g 1 0)運行diff與反對的第一個參數,第二個參數給定的選項(與所述FAIL錯誤退回到另一說法,以減少diff)。

  • --允許將diff -options(-something)傳遞給此別名/腳本。

錯誤:未選中

  • 參數數目。第二個參數後面的所有內容都會被忽略,如果你給它太少,你只會看到FAIL或者什麼也沒有。

  • 錯誤的行爲有點奇怪,混亂的輸出。如果你不喜歡這個,用2>/dev/null(或適當地改變腳本)運行它。

  • 它不會在出現問題時返回錯誤。

  • 您可能希望默認情況下將其傳送到尋呼機。

請注意,很容易定義像一些多個別名:

git config --global alias.udiff '!git sdiff -u' 
git config --global alias.bdiff '!git sdiff -b' 

git config --global alias.pager '!pager() { cd "$GIT_PREFIX" && git -c color.status=always -c color.ui=always "[email protected]" 2>&1 | less -XFR; }; pager' 
git config --global alias.ddiff '!git pager udiff' 

我希望這不會需要進一步解釋。

對於更多像這樣的別名,也許看看my GitHub repo

相關問題