我有一些文件已从根文件夹移至lib/
文件夹。我还对这些文件进行了一些重大更改。
git历史记录显示旧文件已删除,新文件已添加。但是,即使文件之间存在很多差异,我仍然希望将它们视为同一文件。是否可以返回并告诉git该文件是移动文件,而不是删除和添加文件?
答案 0 :(得分:3)
Git不跟踪副本和重命名。相反,它查看文件内容并决定是重命名还是副本。
这有优点也有缺点,但是承认使用版本控制的人通常不会通过版本控制系统执行基本的Shell命令,例如mv或rm或cp。这也是因为Git stores file contents and their names separately(blob vs树对象)。因此,Git进行了猜测。这也是为什么没有git-cp
的原因。
幸运的是,Git认为复制或重命名的阈值是可配置的。 git-log
和git-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将清楚地看到连续性。 Use git rebase -i
to split up the commit。
在某些情况下,这很简单。在其他情况下,仅重命名将破坏需要更改同一提交以保持工作正常的代码。通常,您可以做一些最小的更改,例如只是重命名一个类以使其与新文件名匹配,Git会将其识别为同一文件,为下一次提交保留较大的更改。
如果文件太小,主要是文件名中附带的类名之类的东西,则可能表示code smell和重构的候选对象。