使用 Git 记录文件复制操作

当我使用 git-mv 在 git 中移动一个文件时,状态显示该文件已经被重命名,即使我改变了一些部分,它仍然认为是几乎相同的事情(这很好,因为它让我跟踪它的历史)。

当我复制一个文件的原始文件有一些历史,我想与新的副本关联。

我试过移动文件,然后尝试在原来的位置重新签出-一旦移动 git 不会让我签出原来的位置。

我尝试过做一个文件系统副本,然后添加 file-git 将其列为一个新文件。

有没有什么方法可以让 git 记录一个文件复制操作,就像它记录一个文件重命名/移动一样,这样历史可以追溯到原始文件?

52246 次浏览

Git 不进行重命名跟踪或复制跟踪,这意味着它不进行 记录重命名或复制。相反,它所做的是重命名和复制 侦测。你可以通过使用 -M选项请求在 git diff(和 git show)中进行重命名检测,也可以通过使用 -C选项请求在更改后的文件中进行额外的拷贝检测,还可以使用 -C -C请求在所有文件中进行更昂贵的拷贝检测。请参阅 Git-diff手册。

-C -C代表 -C-C代表 -M

-M--find-renames的快捷键,-C意味着 --find-copies-C -C也可以拼写成 --find-copies-harder

你也可以通过将 diff.renames设置为布尔真值(例如 true1)来配置 git 来进行重命名检测,你也可以通过将 git 设置为 copycopies来请求 git 进行拷贝检测。请参阅 Git-config手册。

还要检查 git diff-l选项和相关的配置变量 diff.renameLimit


请注意,git log <pathspec>在 Git 中的工作方式不同: 这里的 <pathspec>是一组路径分隔符,其中 path 可以是一个(子)目录名。它过滤和简化历史 之前重命名和复制检测发挥作用。如果您希望遵循重命名和复制,请使用 git log --follow <filename>(目前有一点限制,并且只适用于单个文件)。

如果由于某种原因您不能像 Jakub Nar bski 的回答那样打开 拷贝检测,您可以通过 力量 Git 在三次提交中检测复制文件的历史记录:

  • 不要复制,而是切换到一个新的分支,并将文件 让开到其新的位置。
  • 在那里重新添加原始文件。
  • 使用 no-fast-forward 选项 --no-ff将新分支合并到原始分支。

学分到 Raymond Chen。接下来是他的手术。假设文件名为 orig,并且希望复制的文件名为 apple:

git checkout -b dup # create and switch to branch


git mv orig apple # make the duplicate
git commit -m "duplicate orig to apple"


git checkout HEAD~ orig # bring back the original
git commit -m "restore orig"


git checkout - # switch back to source branch
git merge --no-ff dup # merge dup into source branch

2020-05-19: 上述解决方案的优点是不会更改原始文件的日志,不会产生合并冲突,并且更短。前一种解决办法有四项承诺:

  • 不要复制,而是切换到一个新的分支,并将文件 让开到其新的位置。
  • 切换到原始分支并重命名文件。
  • 将新的分支合并到原来的分支中,通过保留这两个文件来解决琐碎的冲突。
  • 在单独的提交中还原原始文件名。

(取自 https://stackoverflow.com/a/44036771/1389680.的解决方案)