使用Git diff来检测代码移动+如何使用diff选项 [英] Using Git diff to detect code movement + How to use diff options

查看:109
本文介绍了使用Git diff来检测代码移动+如何使用diff选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一个文件(1.c)包含三个函数和作者M和J所做的更改。如果有人运行 git blame 1.c ,他将得到下面的输出:

  ^ 869c699(M 2012年9月25日14时05分31秒-0600 1)
de24af82 (J 2012-09-25 14:23:52 -0600 2)
de24af82(J 2012-09-25 14:23:52 -0600 3)
de24af82(J 2012-09-25 14 :23:52 -0600 4)public int add(int x,int y){
de24af82(J 2012-09-25 14:23:52 -0600 5)int z = x + y;
de24af82(J 2012-09-25 14:23:52 -0600 6)return z;
de24af82(J 2012-09-25 14:23:52 -0600 7)}
de24af82(J 2012-09-25 14:23:52 -0600 8)
^ 869c699( M 2012-09-25 14:05:31 -0600 9)public int multiplication(int y,int z){
^ 869c699(M 2012-09-25 14:05:31 -0600 10)int result = y * z;
^ 869c699(M 2012-09-25 14:05:31 -0600 11)return temp;
^ 869c699(M 2012-09-25 14:05:31 -0600 12)}
^ 869c699(M 2012-09-25 14:05:31 -0600 13)
^ 869c699(M 2012-09-25 14:05:31 -0600 14)public void main(){
de24af82(J 2012-09-25 14:23:52 -0600 15)//这是一条评论
de24af82(J 2012-09-25 14:23:52 -0600 16)}

现在,如果作者A更改 multiplication() add()函数的位置并提交更改, git blame 可以检测代码移动。请参阅以下输出:

  $ git blame -C -M e4672cf82 1.c 
^ 869c699(M 2012-09 -25 14:05:31 -0600 1)
de24af82(J 2012-09-25 14:23:52 -0600 2)
de24af82(J 2012-09-25 14:23:52 - 0600 3)
e4672cf8(M 2012年9月25日14时26分39秒-0600 4)
de24af82(j 2012年9月25日14点23分52秒-0600 5)
^ 869c699(M 2012-09-25 14:05:31 -0600 6)public int multiplication(int y,int z){
^ 869c699(M 2012-09-25 14:05:31 -0600 7) int result = y * z;
^ 869c699(M 2012-09-25 14:05:31 -0600 8)return temp;
^ 869c699(M 2012-09-25 14:05:31 -0600 9)}
^ 869c699(M 2012-09-25 14:05:31 -0600 10)
^ 869c699(M 2012-09-25 14:05:31 -0600 11)public void main(){
de24af82(J 2012-09-25 14:23:52 -0600 12)//这是一条评论
e4672cf8(M 2012年9月25日14时26分39秒-0600 13)}
de24af82(j 2012年9月25日14点23分52秒-0600 14)公众诠释加载(INT X, int y){
de24af82(J 2012-09-25 14:23:52 -0600 15)int z = x + y;
de24af82(J 2012-09-25 14:23:52 -0600 16)return z;
e4672cf8(M 2012-09-25 14:26:39 -0600 17)}

然而,如果我试图在这两个修订版之间运行 git diff ,它不会检测到这些函数会改变它们的位置并给出以下输出:

  $ git diff -C -M de24af8..e4672cf82 1.c 

diff --git a / 1.cb / 1。 c
索引5b1fcba..56b4430 100644
--- a / 1.c
+++ b / 1.c
@@ -1,10 +1,7 @ @



- public int add(int x,int y){
- int z = x + y;
- return z;
- }
+

public int multiplication(int y,int z){
int result = y * z;
@@ -13,4 +10,8 @@ public int multiplication(int y,int z){

public void main(){
//这是一个注释
- }
\不在文件末尾换行
+}
+ public int add(int x,int y){
+ int z = x + Y;
+ return z;
+}
\在文件结尾没有新行

我的问题是:


  1. 如何在获取差异输出时强制检测代码移动?它甚至有可能吗?


  2. Git diff可以应用于多个选项。例如 - 最小 - 耐心。我如何在这里应用这些选项?我尝试了一个,但得到以下错误:

      $ git diff --minimal de24af8..e4672cf82 1.c 
    usage:git diff< options> < rev> {0,2} - <路径> *


任何人都可以提示/举例说明如何正确添加这些选项?

解决方案

在这里跑来跑去的是Git基本上不会像这样高级差异化。 Git允许配置外部差异和合并工具是有原因的:你会在没有他们协助的情况下疯狂。作为一个例子,Beyond Compare和Araxis Merge都会接受这个动作。



您要解决的一般问题类是结构化合并:两个java源文件的结构差异



git-diff 相比, git-format-patch 在这种情况下,因为前者提供了更多的提交信息,包括作者和提交信息,并且还为您指定的范围内的每个提交生成补丁文件。来源:是什么混帐格式之间的差异-patch和'git diff'?



如果您正在寻找有关检测代码移动的提示,有趣的是请注意,代码移动的检测是明确地不是全能镐的目标。看到这个有趣的交流: http://gitster.livejournal.com/35628.html



如果您想检测交换订单的人,看起来您唯一的选择就是执行类似以下操作:

  git log -S'public int multiplication(int y,int z){
int result = y * z;
return temp;

$ b $ public void main(){
//这是一个注释
}
public int add(int x,int y){
int z = x + y;
return z;
}'

你要找的是 git blame -M< NUM> -n ,它与你所要求的相似:

  -M |< ; NUM> | 
检测文件中移动或复制的行。当一个提交动作或者
复制一行代码块时(例如,原始文件有A然后B,
并且提交将它改变为B然后A),传统的责任
算法通知只有一半的动作,并且通常将b线移动到父母的位置(即B),并将b $ b责备分配给向下移动的线(即A)到子女
承诺。有了这个选项,通过运行额外的检查通过,这两组线都被归咎于
父母。

< num>是可选的,但它是
字母数字字符的数量的下限,git必须在文件中检测到移动/复制
,以便将这些行与父
提交相关联。默认值为20.

-n,--show-number
在原始提交中显示行号(默认值:off)。


Consider that a file (1.c) contains three functions and changes made by authors M and J. If someone runs git blame 1.c, he will get the following output:

^869c699 (M 2012-09-25 14:05:31 -0600  1) 
de24af82 (J 2012-09-25 14:23:52 -0600  2) 
de24af82 (J 2012-09-25 14:23:52 -0600  3) 
de24af82 (J 2012-09-25 14:23:52 -0600  4) public int add(int x, int y)  {
de24af82 (J 2012-09-25 14:23:52 -0600  5)    int z = x+y;
de24af82 (J 2012-09-25 14:23:52 -0600  6)    return z;
de24af82 (J 2012-09-25 14:23:52 -0600  7) }  
de24af82 (J 2012-09-25 14:23:52 -0600  8) 
^869c699 (M 2012-09-25 14:05:31 -0600  9) public int multiplication(int y, int z){
^869c699 (M 2012-09-25 14:05:31 -0600 10)    int result = y*z;
^869c699 (M 2012-09-25 14:05:31 -0600 11)    return temp;
^869c699 (M 2012-09-25 14:05:31 -0600 12) }
^869c699 (M 2012-09-25 14:05:31 -0600 13) 
^869c699 (M 2012-09-25 14:05:31 -0600 14) public void main(){
de24af82 (J 2012-09-25 14:23:52 -0600 15)    //this is a comment
de24af82 (J 2012-09-25 14:23:52 -0600 16) }

Now, if author A changes the position of the multiplication() and add() functions and commits the changes, git blame can detect the code movement. See following output:

$ git blame  -C -M e4672cf82 1.c
^869c699 (M 2012-09-25 14:05:31 -0600  1) 
de24af82 (J 2012-09-25 14:23:52 -0600  2) 
de24af82 (J 2012-09-25 14:23:52 -0600  3) 
e4672cf8 (M 2012-09-25 14:26:39 -0600  4) 
de24af82 (J 2012-09-25 14:23:52 -0600  5) 
^869c699 (M 2012-09-25 14:05:31 -0600  6) public int multiplication(int y, int z){
^869c699 (M 2012-09-25 14:05:31 -0600  7)    int result = y*z;
^869c699 (M 2012-09-25 14:05:31 -0600  8)    return temp;
^869c699 (M 2012-09-25 14:05:31 -0600  9) }
^869c699 (M 2012-09-25 14:05:31 -0600 10) 
^869c699 (M 2012-09-25 14:05:31 -0600 11) public void main(){
de24af82 (J 2012-09-25 14:23:52 -0600 12)    //this is a comment
e4672cf8 (M 2012-09-25 14:26:39 -0600 13) }
de24af82 (J 2012-09-25 14:23:52 -0600 14) public int add(int x, int y){
de24af82 (J 2012-09-25 14:23:52 -0600 15)    int z = x+y;
de24af82 (J 2012-09-25 14:23:52 -0600 16)    return z;
e4672cf8 (M 2012-09-25 14:26:39 -0600 17) }

However, if I try to run git diff between these two revisions, it cannot detect that functions change their location and gives the following output:

$ git diff -C -M de24af8..e4672cf82 1.c

diff --git a/1.c b/1.c
index 5b1fcba..56b4430 100644
--- a/1.c
+++ b/1.c
@@ -1,10 +1,7 @@



-public int add(int x, int y){
-       int z = x+y;
-       return z;
-}      
+

public int multiplication(int y, int z){
    int result = y*z;
@@ -13,4 +10,8 @@ public int multiplication(int y, int z){

 public void main(){
    //this is a comment
-}
\ No newline at end of file
+}
+public int add(int x, int y){
+       int z = x+y;
+       return z;
+}      
\ No newline at end of file

My questions are:

  1. How can I enforce detecting code movement in getting diff output? Is it even possible?

  2. Git diff can be applied with several options. For example --minimal, --patience. How can I apply those options here? I tried with one, but get the following error:

    $ git diff --minimal de24af8..e4672cf82 1.c
    usage: git diff <options> <rev>{0,2} -- <path>*
    

Can anyone suggest/give sample example how to add these options correctly?

解决方案

What you're running up against here is that Git largely stays out of advanced diffing like this. There's a reason Git allows configuration of external diff and merge tools: you'd go insane without their assistance. Beyond Compare and Araxis Merge would both catch this movement, as an example.

The general class of problem you're looking to solve is a "structured merge": Structural Diff of two java source files

You might have a bit more luck with git-format-patch than with git-diff in this case because the former provides more commit info, including author and commit message and also generates a patch file for each commit in the range you specify. Source: What is the difference between 'git format-patch and 'git diff'?

If you're looking for tips on detecting code moves generally, it's interesting to note that detection of code movement is explicitly not a goal of the all-powerful pickaxe. See this interesting exchange: http://gitster.livejournal.com/35628.html

If you wanted to detect who swapped the order, it seems your only option would be to do something like:

 git log -S'public int multiplication(int y, int z){
    int result = y*z;
    return temp;
 }

 public void main(){
    //this is a comment
 }
 public int add(int x, int y)  {
    int z = x+y;
    return z;
 }'

What you're looking for is git blame -M<num> -n, which does something pretty similar to what you're asking:

-M|<num>|
       Detect moved or copied lines within a file. When a commit moves or
       copies a block of lines (e.g. the original file has A and then B,
       and the commit changes it to B and then A), the traditional blame
       algorithm notices only half of the movement and typically blames
       the lines that were moved up (i.e. B) to the parent and assigns
       blame to the lines that were moved down (i.e. A) to the child
       commit. With this option, both groups of lines are blamed on the
       parent by running extra passes of inspection.

       <num> is optional but it is the lower bound on the number of
       alphanumeric characters that git must detect as moving/copying
       within a file for it to associate those lines with the parent
       commit. The default value is 20.

-n, --show-number
       Show the line number in the original commit (Default: off).

这篇关于使用Git diff来检测代码移动+如何使用diff选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆