git diff -M如何工作?

时间:2015-01-21 21:18:09

标签: git diff

我目前正在试图弄清git diff -M<limit>的工作原理。

我发现,git diff通过计算相似性得分来检查两个文件(例如修订版1中的fileA,修订版2中的fileC)的相似程度。如果相似性得分为&gt; = limit,则fileA已重命名为fileC,可能已被修改(如果得分<100%)。

然后我问自己,如果目录中有更多带有相同sha1-hash的文件怎么办? git如何知道哪一个是重命名(和更改)的版本?

为了解决这个问题,我尝试了以下方法:

首先,我用7行创建了两个文件(“a”,“b”,“c”,“d”,“e”,“f”,“g”)

vi fileA
vi fileB

然后我将它们添加到存储库并提交:

git add fileA fileB
git commit -m "Added fileA and fileB"

    [master ffc8964] Added fileA and fileB
     2 files changed, 6 insertions(+)
     create mode 100644 tests/fileA
     create mode 100644 tests/fileB

接下来,我使用fileAfileC重命名为git mv,并删除fileBfileC中的第一行。之后我提交了更改

git mv fileA fileC
vi fileB
vi fileC
git commit -a -m "Renamed and changed files"

    [master 57ff82a] Renamed and changed filed
     2 files changed, 2 deletions(-)
     rename tests/{fileA => fileC} (85%)

fileBfileC现在看起来像这样:

b
c
d
e
f
g

我现在所期望的是fileBfileC的校验和相等:

git hash-object fileB fileC
    9fbb6235d2d7eb798268d4537acebea297321241
    9fbb6235d2d7eb798268d4537acebea297321241

确实他们是: - )

那么git diff现在应该如何知道重命名的文件是什么?由于fileC已更改,commit已生成新的blob,fileCfileA的校验和也不同(显然)。

我试过了:

git diff -M80% HEAD master~1

然而输出让我困惑: - (

diff --git a/tests/fileC b/tests/fileA
similarity index 85%
rename from tests/fileC
rename to tests/fileA
index 9fbb623..f9d9a01 100644
--- a/tests/fileC
+++ b/tests/fileA
@@ -1,3 +1,4 @@
+a
 b
 c
 d
diff --git a/tests/fileB b/tests/fileB
index 9fbb623..f9d9a01 100644
--- a/tests/fileB
+++ b/tests/fileB
@@ -1,3 +1,4 @@
+a
 b
 c
 d

显然git diff DID发现fileA已重命名为fileC

但是怎么样? git是否在fileAfileC之间保留了某种联系?

1 个答案:

答案 0 :(得分:2)

没有保存此类连接。删除一个文件时可以检测到重命名,另一个文件被添加。 Git看到新添加了fileC,并浏览了所有已删除的文件以查看它是否可能是重命名。在这里,唯一删除的文件是fileA,所以这是一个相当快速的检查。

注意:它只需要浏览已删除的文件,因为否则您将无法重命名,您将拥有副本。也可以检测到副本,它的工作方式大致相同,但它们由单独的选项(-C)覆盖。

相关问题