git,确保在保留历史记录的同时移动/重命名文件的方法

xpt*_*xpt 16 git rename move

我知道有很多现有问题看起来很相似,所以让我在问我之前总结一下.

第一个答案,我不同意,因为我之前已经这样做了.第二个答案是我问这个问题的原因.也就是说,

我发现我一直在做git mv,但有时它被视为移动/重命名,有时它被视为删除+添加.因此,我想知道如何让它始终移动/重命名?

这一个为例,在底部,我们可以看到几个移动/重命名的情况,比如easygenapi/tf-varcaser.go ? tf-varcaser.go.请注意,这些移动是在文件夹之间/之间!即,我做到了!

但是还有很多其他案例git mv被视为删除+添加,显示在完全相同的更改日志中.再一次,我一直在做git mv.为什么git表现不一样?

在保留历史记录的同时,有没有可靠的方法来移动/重命名git文件?

Kev*_*ett 24

TL;博士; 没有

更长的版本:根据我的经验,只要文件未经修改,git就非常擅长检测移动/重命名.Git使用启发式方法来尝试和定位移动.如果文件太多相似,或者文件在移动过程中被修改过,导致它与原始文件太不相似,可能会被欺骗.

我发现这样做的最好方法是进行多阶段提交,将所有移动分成一个提交,然后将另一个提交分开.例如...

git mv foo.txt bar.txt
git commit

... modify bar.txt ...

git add bar.txt
git commit
Run Code Online (Sandbox Code Playgroud)

它不能保证您的移动被正确检测到,因为当有多个候选者时它仍然会混淆.然而,它对我来说非常有效,并且可以捕获大多数情况.

  • 谢谢。比其他答案指出的要有用得多,*“ Git不会跟踪重命名。句点。” *,它获得了五票,而这一票却没有。好。从现在开始,我将确保使用*多阶段提交*技巧。 (2认同)
  • 我已经尝试过了,尽管git在提交过程中将更改显示为重命名,但我*仍然*仍然丢失了文件的所有更改历史记录! (2认同)

Jör*_*tag 13

Git不跟踪重命名.期.它也不跟踪添加.或者删除.或差异.或补丁.或移动.或者任何改变,真的.

Git是基于快照的.每个提交都记录整个项目的快照.而已.这个快照是如何形成的,Git既不知道也不关心.

差异,补丁,添加,删除,移动,重命名等由各种可视化工具显示,这些工具在使用启发式(这是另一种说法"猜测")之后推断它们.有时候,他们可能会正确猜出你做了什么,有时他们却没有.然而,这并不重要,因为它只是可视化,它不是历史的任何方式,形状或形式的一部分.

大多数工具使用某种形式的相似性度量,并推断如果两个文件的相似度大于某个阈值,则会发生重命名.在某些工具中,此阈值是可配置的.在某些工具中,甚至算法也是可配置的.(稍微相关例子:git diff允许你推断的差异不同算法之间进行选择的文件.)

由于Git不记录更改,因此可以在可视化工具的更高版本中添加新的更改,这些更改可以推断在更新工具之前记录的旧更改的更改,这些新工具甚至可以编写新的更改类型.想象一下,例如,一个了解您正在使用的编程语言的语法和语义的工具.它可以将某个提交可视化,而不是作为一组文件,每个文件都有几行更改,但作为单个更改,它重命名子例程并更新每个调用点(即重命名方法重构).

重命名实际上是一个很好的例子.git log --follow例如,使用的重命名检测启发式和相似性度量被多次改进.IIRC,在开始时,根本没有推断重命名,后来增加了这种能力.如果Git记录了更改而不是快照,那么这根本不可能实现.

  • 从这个意义上说,Git 与其说是“愚蠢的内容跟踪器”,不如说是“愚蠢的内容”。 (2认同)