通过从其他人复制内容在git中创建的文件具有原始文件历史记录

时间:2016-07-12 23:52:17

标签: java git github

我的一个队友通过从另一个文件复制来创建一个java文件。猜猜看,新文件看起来像是对git存储库中原始文件的编辑。这两个文件是完全不同的,我希望新文件有自己的历史记录而不是复制历史记录。拉取请求显示文件已复制并具有与之关联的更改历史记录。有谁知道如何删除与复制相关的历史记录?通过git

完成了通缉行为

1 个答案:

答案 0 :(得分:2)

在Git中,文件没有历史记录。历史记录附加到提交:提交具有父提交,其中包含更多父项,依此类推。每个提交都有一个ID(“真名”SHA-1哈希),作者和提交者(名称,电子邮件,时间戳)和日志消息。

当然,每个人都希望看到文件历史记录。所以Git把它搞砸了:它将一个历史提交与另一个更新的提交进行比较,将每个提交中的所有文件区分开来。当它区分文件时,它可能会决定先前提交的dir/README.txt被复制或重命名为新提交的python/sourcefile.py。因此,它会告诉您python/sourcefile.py的“历史记录”之前是dir/README.txt

那段历史完全虚构,除非你不想要它,在这种情况下,它是完全,绝对真理!你决定是否要相信Git。

你也有一些控制旋钮:

  • diff.renames:如果true,请让Git检测重命名的文件。如果false,请让Git不要检测重命名。如果是copies,请让Git检测复制的文件以及重命名的文件。默认值现为true,但在较旧(2.9版之前)的Git版本中为false

  • diff.renameLimit:Git如何将许多文件视为重命名检测的候选对象。重命名和复制检测有点慢且内存密集,因此Git的默认值为500,然后是1000,然后是2000。将其设置为0意味着“与Git可以管理的一样多。”

  • diff.algorithm(以及许多外部差异驱动程序配置选项):请参阅the git config documentation

除此之外,还有相同项目的命令行开关,以及默认为“50%相似”的“匹配阈值”(-M)值:重命名至少“50%相似”的文件,小于“50%相似”的文件不是。

(请注意,某些命令,例如git merge,运行其内部git diff - s,其中一些设置的设置与默认设置不同。这些设置也有控件。)

如果文件具有相同的路径名

在你的情况下,听起来就像是:

  • 旧提交,称之为$OLD,文件为src/foo.java
  • 一路上某处src/foo.java被完全删除(并已提交或未提交,此处无关紧要。)
  • 后来有人写了一个新的,或者复制了其他东西,src/foo.java,然后承诺;请拨打此$NEW
  • 现在将$OLD$NEW进行比较,坚持要比较不相关的文件。

此处您陷入困境:Git认为,由于src/foo.javasrc/foo.java具有同名,因此应该比较其内容。但是,还有一个控制旋钮,如git diff has a -B switch

  

-B[<n>][/<m>], --break-rewrites[=[<n>][/<m>]]

     

将完全重写更改分为删除和创建对。              这有两个目的:

     

它会影响相当于完全重写a的更改方式              文件不是作为一系列删除和插入混合在一起的              很少的一行恰好在文本上与上下文匹配,但是              作为单个删除所有旧的后跟单个              插入所有新内容,数字 m 控制此方面              -B选项的默认值(默认为60%)。 -B/70%指定更少              超过30%的原始应保留在Git的结果中              认为它是一个完全重写(即否则产生的补丁              将一系列删除和插入混合在一起              上下文行)。

     

-M一起使用时,完全重写的文件也被视为              重命名的来源(通常-M只考虑一个文件              作为重命名的来源消失了,数字 n 控件              -B选项的这一方面(默认为50%)。 -B20%指定              添加和删​​除的变化与20%或更多相比              文件的大小有资格作为可能的选择              重命名源到另一个文件。

因此,通过提供-B并启用重命名和复制检测,您可以获得所需的输出。