git:将已删除和新文件标记为移动而非复制

4

我有一些文件,从根目录移动到了lib/文件夹中。同时我也对这些文件进行了重大更改。

Git历史记录显示旧文件已被删除,新文件已添加。但即使文件存在大量差异,我仍希望它们被视为同一文件。有没有可能回头告诉Git这个文件是移动的,而不是删除和添加?


这不是你能决定的,“移动”在内部无论如何都是一个删除和添加。 - Mad Physicist
@MadPhysicist 除此之外,在删除和添加文件时,文件历史记录会丢失,而使用移动文件可以保留文件的历史记录。 - ewok
在您的提交消息中添加一条注释。旧文件的历史记录不会丢失。 - Mad Physicist
1
可能是重复的问题:如何让Git将删除的文件和新文件标记为文件移动? - Mad Physicist
看起来你需要将提交拆分,这可以通过交互式变基或类似方法实现。 - Mad Physicist
1个回答

9

Git不跟踪复制和重命名。相反,它查看文件内容并决定是重命名还是复制。

这有优点和缺点,但承认使用版本控制的人通常不会通过版本控制系统执行基本的shell命令,如mv、rm或cp。这也是因为Git将文件内容和名称分别存储(blob vs tree对象)。所以Git猜测。这也是为什么没有git-cp的原因。

幸运的是,Git认为是复制或重命名的阈值是可配置的。git-loggit-diff都接受-M

  -M[<n>], --find-renames[=<n>]
      If generating diffs, detect and report renames for each commit. For following
       files across renames while traversing history, see --follow. If n is specified,
       it is a threshold on the similarity index (i.e. amount of addition/deletions
       compared to the file's size). For example, -M90% means Git should consider a
       delete/add pair to be a rename if more than 90% of the file hasn't changed.
       Without a % sign, the number is to be read as a fraction, with a decimal point
       before it. I.e., -M5 becomes 0.5, and is thus the same as -M50%. Similarly,
       -M05 is the same as -M5%. To limit detection to exact renames, use -M100%. The
       default similarity index is 50%.

不幸的是,这会影响所有文件,没有办法将其作为存储库的一部分保存。


即使这些文件有很多不同之处,我仍希望它们被视为相同的文件。是否可以回到过去并告诉git这个文件是移动而不是删除和添加? 是的。将其拆分为两个提交,而不是一个重命名和做出大更改的大提交。一个用于重命名文件,另一个用于更改内容。然后Git将清楚地看到连续性。 使用git rebase -i来拆分提交。 在某些情况下,这很简单。在其他情况下,仅重命名就会破坏代码,需要在同一提交中进行更改以保持正常工作。通常,您可以进行最小更改,例如仅将类重命名以匹配新的文件名,Git将识别为相同的文件,留下更大的更改以供下一次提交。如果您的文件太小,主要是附加到文件名的类名之类的东西,那可能表明存在代码异味,并且是重构的候选对象。

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