繁体   English   中英

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

[英]Git - Mark file as new instead of moved/copied

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

用例:

  1. 我有一个大文件index.js
  2. 我正在将该文件中的一个小类分解为Helper.js (仅index.js 10%)并将index.js重命名为MyLib.js MyLib.js将有一些与从Helper.js导入符号相关的小改动。
  3. 我需要将index.js重新创建为一个新的 2 行文件,该文件仅从Helper.jsMyLib.js重新导出符号。

我希望提交历史记录将index.js重命名为MyLib.js并将 2 行index.js视为新的,但 git 将MyLib.js视为全新的,而index.js已丢失其 99% 的内容,只有那两行。

简短的回答是:不, 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

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

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


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

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

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

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

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

使用选项 2,一些git命令(例如git rebasegit log --follow )将检测 repo 历史中的重命名步骤,因为它们总是一次检查一次提交的历史。

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

例如:如果您打开一个合并请求(想想githubgitlabAzure Devops ...),合并请求界面仍然会向您显示:

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

我假设您使用git mv移动该文件,这就是 Git 报告它已被移动的原因。 像这样的东西:

git mv file.txt newfolder

但是 Git 不知道它看不到什么,所以如果你从文件系统中移动文件,Git 会看到新位置的文件是新的:

mv file.txt newfolder

你可以git add这个文件将它添加到索引中。 在此之后,您可以选择从 Git 中删除原始文件:

git add newfolder/file.txt
git rm file.txt

请记住,这意味着 Git 将无法使用这种方法跟踪此文件的历史记录。 虽然使用git mv也会使跟踪移动文件的历史变得困难,但它至少在某种程度上使它成为可能。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM