为什么git-status会将一个更新了名称的二进制文件显示为重命名?

5
处理二进制文件时,Git似乎会将用修改后的文件替换原有文件视为重命名操作。例如,当用foo-1.0.3.jar替换foo-1.0.1.jar,或者遇到以下测试情况时,就会发生这种情况:
$ dd if=/dev/urandom of=test.dat bs=1024 count=10
$ md5sum test.dat
8073aef704e9df13b44818371ebbcc0b  test.dat
$ git add test.dat && git commit -m 'add binary file'
$ mv test.dat test2.dat
$ git rm test.dat
$ dd if=/dev/urandom of=test2.dat bs=1 count=1 conv=notrunc
$ md5sum test2.dat
21e1ac3ab9ba50c9dad9171f9de7232d  test2.dat
$ git add test2.dat

现在,我明确地拥有了一个新名称的文件和新内容(至少部分)。然而,在git状态中,Git认为这是一次重命名:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    test.dat -> test2.dat
  • 这是什么原因,例如这两个文件有多相似才会出现这种情况?如果test2.dat包含完全不同的数据,似乎不会发生这种情况。
  • 除了看起来有些尴尬之外,它还有什么缺点吗?实际数据似乎完全正常;当检查之前的版本时,我会得到正确的文件版本。
1个回答

4
Git实际上不会存储重命名,它只会存储一个新的树形结构,其中一个文件被删除,另一个文件被添加。比较树形结构的Git命令(git diffgit loggit status)是基于内容检测重命名的。
由于某些原因,重命名检测适用于您的文件。也许如果您在 /dev/urandom 中消耗了熵,它们的内容就会相似?
编辑:有关重命名检测的详细信息,请参见例如 How does git detect similar files, for its rename detection?

不,它并不总是能够成功处理二进制文件。test.dat被重命名为test2.dat,然后新内容被追加到其中。Git说它被重命名了,因为它确实被重命名了(并更新了)。 - jamessan
1
@jamessan:git不知道我使用了mv命令,据我所知它也不会检查inode号码。但是git不存储重命名操作是正确的。 - ThiefMaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接