使用Git记录文件复制操作

Hex*_*oll 131 git copy file

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

当我复制文件时,原始文件有一些我想与新副本关联的历史记录.

我试过移动文件,然后尝试在原始位置重新结账 - 一旦移动git将不允许我签出原始位置.

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

有没有办法让git记录文件复制操作的方式与记录文件重命名/移动的方式类似,历史记录可以追溯到原始文件?

Jak*_*ski 110

Git不会重命名跟踪也不会复制跟踪,这意味着它不会记录重命名或副本.它的作用是重命名和复制检测.您可以使用选项在git diff(和git show)中请求重命名检测-M,您可以使用-C选项(-C隐含-M)请求在已更改的文件中进行额外的副本检测,并且您可以在所有文件中使用--find-copies-harder或请求更昂贵的副本检测-C -C(这意味着-C,这意味着-M).请参阅git-diff联机帮助页.

您还可以将git配置为始终通过设置diff.renames为布尔值true(例如true1)进行重命名检测,并且您可以通过将其设置为copy或来请求git进行复制检测copies.请参阅git-config联机帮助页.

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


请注意,git log <pathspec>在Git 中的工作方式不同:这里<pathspec>是路径分隔符集,其中path可以是(子)目录名.重命名和复制检测发挥作用之前,它会过滤并简化历史记录.如果要关注重命名和副本,请使用git log --follow <filename>(目前有点限制,仅适用于单个文件).

  • @peschü:Git使用内容寻址对象数据库作为存储库存储.文件内容存储在地址内的'blob'内容中,该地址是内容的SHA-1哈希(井,类型+长度+内容).这意味着给定的内容只存储一次.铌.这种自动重复数据删除是使用git pack格式创建"bup"备份系统的原因. (4认同)
  • 与下面的解决方案不同,这不适用于范围内的更改跟踪。Git log 允许一个范围参数(`git log -L123,456:file.xyz`)正确地遵循重命名,但不允许复制,在这种情况下你不能传递 --follow ;另外,AFAICT,这不适用于 git Blame。 (3认同)
  • @allyourcode:你对什么感到困惑?要默认打开复制检测,您可以将 `diff.renames` 设置为 `copies`(例如,'`git config diff.renames 副本`')。我同意这有点违反直觉。 (2认同)

Rob*_*lak 37

您可以强制Git检测复制文件的历史记录:

  • 而不是复制,切换到新分支并将文件移动到那里的新位置.
  • 切换到原始分支并重命名该文件.
  • 将新分支合并到原始分支中,通过保留两个文件来解决琐碎的冲突.
  • 在单独的提交中恢复原始文件名.

(解决方案取自/sf/answers/3082574001/.)

  • 我尝试遵循这个(新)食谱,但没有成功。如果您展示实际命令可能会有所帮助。 (5认同)
  • 简洁,简洁,100%......这个答案是公共服务......在视线中提升一切 (3认同)
  • @RobertPollak我已经尝试过各种版本,但它们不起作用。“移动文件”是指“git mv orig new”吗?“阅读原文”是指“cp new orig &amp;&amp; git add orig”吗? (3认同)
  • 你必须创建一个分支,在那里提交,然后将其合并回来......而最重要的评论是“简单和简洁”......的想法令人难以置信。在 Mercurial 中,您只需执行“hg cp”(或者“hg cp -A”,如果您已经自己复制了它)。真是可惜,git 赢得了 VCS 人气竞赛。 (2认同)
  • 完成这些步骤后,我遇到了同样的问题,就像我刚刚完成“cp oldFile newFile”一样,它显示该文件刚刚被直接添加,与旧文件没有任何关系。有什么想法可能会出现这种情况吗? (2认同)