Git:检测移动块期间所做的更改(删除已移除的块和添加的块)

时间:2017-01-13 20:20:25

标签: git diff

想象一下,您正在审核代码更改。一个人将一个函数从一个文件移动到另一个文件。提交显示两个文件,一个删除了块,另一个添加了块。

如何使用Git对两个块进行差异化以查看在该代码块中所做的更改?

简化,最小差异示例:

+++ a/modules/foo.js
--- b/modules/foo.js
@@ -314,15 +314,12


-function foo() {
-   returns 42;
-}


+++ a/modules/bar.js
--- b/modules/bar.js
@@ -271,82 +271,85


+function foo() {
+   returns 43;
+}

有一点变化。我想比较两个块来看这个:

 function foo() {
-   returns 42;
+   returns 43;
 }

我不想检测是否已移动但我希望看到移动块中的差异(您已经识别为移动)。

目前,我从旧文件和新文件中分割出有趣的代码块,将它们存储在临时文件中并手动比较它们,但我想用工具代替它。

到目前为止,我会创建自己的程序或脚本来自动执行此操作,但我想知道Git是否可以实现这一点。

1 个答案:

答案 0 :(得分:0)

此答案并未完全解决您的预期输出/工作流程,但它将解决跟踪变动以及变动的要求。

它利用-C中的复制检测(git blame)。与-M相比,此开关将检测到稍有变化的副本。

记住这段历史:

9f3c95c Moved isApplicable() from Foo => Bar
cff47ee Added bar.js
e0efec3 Added foo.js

isApplicable()移动了,它产生了这个责任(只显示相关的行):

$ git blame -C 9f3c95c3 -- bar.js
cff47ee4 bar.js (John Doe 2017-01-13 20:28:51 +0100 36)           },
cff47ee4 bar.js (John Doe 2017-01-13 20:28:51 +0100 37) 
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 38)           isApplicable: function(){
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 39)                   if (!this._depends) {
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 40)                           // no depends expression defined, default to "yes, it's applicable"
9f3c95c3 bar.js (John Doe 2017-01-13 20:26:47 +0100 41)                           return false;
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 42)                   }
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 43) 
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 44)                   // pass the survey model and the expression
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 45)                   return Evaluator.evaluate(this.model.toJSON(), this._depends);
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 46)           },
e0efec3b foo.js (John Doe 2017-01-13 20:18:51 +0100 47) 
cff47ee4 bar.js (John Doe 2017-01-13 20:28:51 +0100 48)           render: function(){

移动提交仅显示在第41行,因为return true;随着移动一起更改为return false;。与isApplicable()相关的其他行标有提交e0efec3b,这是最初引入它们的那个(文件名列也指定原始文件名)。

另一方面,纯blame看起来像这样(只显示相关的行):

$ git blame 9f3c95c3 -- bar.js
cff47ee4 (John Doe 2017-01-13 20:28:51 +0100 36)          },
cff47ee4 (John Doe 2017-01-13 20:28:51 +0100 37) 
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 38)          isApplicable: function(){
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 39)                  if (!this._depends) {
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 40)                          // no depends expression defined, default to "yes, it's applicable"
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 41)                          return false;
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 42)                  }
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 43) 
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 44)                  // pass the survey model and the expression
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 45)                  return Evaluator.evaluate(this.model.toJSON(), this._depends);
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 46)          },
9f3c95c3 (John Doe 2017-01-13 20:26:47 +0100 47) 
cff47ee4 (John Doe 2017-01-13 20:28:51 +0100 48)          render: function(){

移动提交显示为一个块,因为Git将其视为9f3c95c3中的添加。

git blame -C <REV> -- <FILE>也可用于一个文件中的移动。

可以多次指定-C开关,以将跟踪扩展到该提交中的所有文件或找到的所有提交。该手册页说:

  

-C|<num>|
  除了-M之外,还检测从同一提交中修改的其他文件移动或复制的行。当您重新组织程序并跨文件移动代码时,这非常有用。 当此选项被提供两次时,该命令还会在创建文件的提交中查找其他文件的副本。如果此选项被指定三次,则该命令还会在任何提交中查找其他文件中的副本。

(强调我的。)