我的一个队友通过从另一个文件复制来创建一个java文件。猜猜看,新文件看起来像是对git存储库中原始文件的编辑。这两个文件是完全不同的,我希望新文件有自己的历史记录而不是复制历史记录。拉取请求显示文件已复制并具有与之关联的更改历史记录。有谁知道如何删除与复制相关的历史记录?通过git
完成了通缉行为答案 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.java
和src/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
并启用重命名和复制检测,您可以获得所需的输出。