Git - 将文件标记为新文件而不是移动/复制

not*_*eek 9 git

有没有办法强制 git 将文件视为新文件而不是移动/复制?

用例:

  1. 我有一个大文件, index.js
  2. 我正在将该文件中的一个小类分解为Helper.js(仅 10% 的index.js)并重命名index.js为MyLib.js. MyLib.js将有一些与从Helper.js.
  3. 我需要重新创建index.js一个新的,2行的文件,只有从转口贸易符号Helper.js和MyLib.js。

我想提交历史记录重新命名index.js,以MyLib.js和治疗2行index.js如新,但代替的git对待MyLib.js作为全新的,并index.js为失去其内容的99%,下降到只有2行。

LeG*_*GEC 8

简短的回答是:不,git不允许您存储有关文件如何移动的信息。

git跟踪内容,而不是差异。

当git显示的信息:

$ git diff --name-status HEAD^ HEAD
M    fileA          # fileA has been modified
R    oldB -> fileB  # fileB has been renamed
A    fileC          # fileC has been created
Run Code Online (Sandbox Code Playgroud)

它实际上是通过比较两次提交的内容来计算这些信息的。它没有存储信息:“实际上 fileC 是从 fileA 复制的,而 fileA 被重新创建为一个新文件”。

如果两个文件在两次提交中具有相同的名称,git diff将始终计算“此文件已被修改”。


选项 1:保留您拥有的历史,并与之共存。

选项 2:您可以尝试在两次提交中完成

  • 创建第一次提交,其中唯一的操作是将文件重命名index.js为MyLib.js,

    • 如果您需要代码“工作”——例如以便单元测试或集成测试可以在这个提交上运行——更新其他模块,以便它们导入MyLib.js而不是index.js
  • 创建第二次提交,在其中应用您实际想要查看的修改

    • 从MyLib.jsto 中提取一个小类Helper.js,
    • 创建一个index.js包含两行和导出符号的新文件,
    • 如果您在第一次提交中修改了导入,请在第二次提交中再次修改它们。

对于选项2,一些git命令(git rebase或git log --follow例如)将检测回购历史上的重命名的一步,因为他们总是检查一次一个提交历史。

其他一些命令,不查看每个提交差异的提交,而是查看“全局”差异,仍将作为选项 1。

例如:如果你打开一个合并请求(想想github,gitlab,Azure Devops...),合并请求接口仍然会为你展示:

  • 文件index.js已被修改,
  • 文件MyLib.js是一个全新的文件


Álv*_* P. -1

Git 非常智能地判断文件何时被移动(如果您删除该文件并将其添加到同一提交的新位置,Git 将判断该文件已被移动)。

如果您确实希望该文件被视为“新”而不是“已移动”,那么最好的选择可能是在单独的提交中删除该文件并将其添加到其新位置。