2011-12-20 60 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

相关问题