Skip to main content
 首页 » 编程设计

git中为什么 git 有时会显示文件已更改,但实际上并未更改

2024年09月07日67Renyi-Fan

DragonFly BSD 使用 git 作为其 SCM,为内核和整个用户空间提供一个存储库和分支。

2011 年 11 月 26 日,有人进行了一次提交,以某种方式触及了存储库中的每个文件,尽管大多数文件根本没有更改。

这是 2011 年 11 月 26 日的违规提交:
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/86d7f5d305c6adaa56ff4582ece9859d73106103
https://github.com/DragonFlyBSD/DragonFlyBSD/commit/86d7f5d305c6adaa56ff4582ece9859d73106103

从那时起,使用某些工具,如果您查看存储库中任何位置的任何文件的文件历史记录,您可以看到它在 2011 年 11 月 26 日通过该提交进行了更改,但它仅在某些工具中显示,并且其他人中未显示。

例如,使用以下工具不会显示伪造的 2011-11-26 提交:

但是,虚假提交错误地显示,并显示以下内容:

  • git Whatchanged --pretty=%at sys/sys/sensors.h

    1322296064 
     
    :000000 100644 0000000... 554cfc2... A  sys/sys/sensors.h 
    1191329821 
     
    :000000 100644 0000000... 554cfc2... A  sys/sys/sensors.h 
    

    1322296064 时间是伪造的,请注意该文件是如何添加而没有被删除的,并且 dst sha1 是相同的。另一个更具代表性的示例,它表明在此类虚假提交中,src sha1 始终为 0000000...,尽管当您认为该文件从未存在时,它没有什么意义。删除后仍然具有相同的dst sha1:

    % git whatchanged --pretty=%at sys/sys/sysctl.h | head -9 
    1322296064 
     
    :000000 100644 0000000... 6659977... A  sys/sys/sysctl.h 
    1296826445 
     
    :100644 100644 94b8d96... 6659977... M  sys/sys/sysctl.h 
    1292413105 
     
    :100644 100644 8c9deaa... 94b8d96... M  sys/sys/sysctl.h 
    
  • http://gitweb.dragonflybsd.org/dragonfly.git/history/HEAD:/sys/sys/sensors.h

我的问题如下:

  • 如何在不首先删除文件的情况下添加文件?允许这样的事情是/是 git 中的一个错误吗?

  • 为什么有些工具会压缩此类虚假提交(并向用户 stash 它们),而有些工具则不然?

  • 有没有办法让 git-whatchangedgitweb 忽略对未实际修改的文件的此类虚假提交,就像 git 一样-loggithub 做什么?

请您参考如下方法:

我查看了有问题的提交并找到了答案:

这是一个“根提交”——它没有任何父提交。通常,存储库中唯一具有此属性的提交是有史以来的第一次提交。

所以这次提交中的每个文件确实都是新的,因为不存在旧版本。

git log 过滤掉此提交,因为它不是 merge 点的第一个父提交。我不知道导致 git log 相信首先有一些东西需要忽略的逻辑。

不,没有办法让其他工具忽略此类提交,因为它们只是在做自己的工作。

这里的问题是,这个提交永远不应该在没有父级的情况下创建,如果有人创建这样的提交,它永远不应该在任何地方 merge 。