此问题在此处已有答案:
Record file copy operation with Git(3个答案)
三年前关闭。
我在Git中有一个有点令人困惑的问题,比如说,我提交了一个文件dir1/A.txt
,而git保留了提交的历史记录。
现在我需要将文件复制到dir2/A.txt
中(不是移动,而是复制)。我知道有一个git mv
命令,但我需要dir2/A.txt
具有与dir1/A.txt
相同的提交历史,并且dir1/A.txt
仍然保留在那里。
一旦创建了副本,我就不打算更新A.txt
了,以后所有的工作都将在dir2/A.txt
上完成
我知道这听起来很令人困惑,我会补充说,这种情况是基于java的模块(mavenized项目),我们需要创建一个新版本的代码,这样我们的客户将有能力在运行时有两个不同的版本,第一个版本将最终被删除时,对齐将完成。我们可以使用maven版本当然,我只是新手Git和好奇Git可以提供什么在这里。
7条答案
按热度按时间p3rjfoxz1#
你要做的就是:
1.将文件移动到两个不同的位置,
1.合并完成上述任务的两个提交,
1.将一个副本移回原始位置。
您将能够看到这两个文件的历史属性(使用
git blame
)和完整的更改历史(使用git log
)。假设你想创建一个名为
bar
的文件foo
的副本。在这种情况下,你使用的工作流程如下所示:字符串
为什么会这样
执行上述命令后,最终会得到一个类似于以下内容的修订历史记录:
型
当你向Git询问
foo
的历史时,它会:1.在合并和恢复之间检测
copy
的重命名,1.检测到
copy
来自MERGED的ALTERNATE父代,以及1.在ORIG_HEAD和ALTERNATE之间检测
foo
的重命名。从那里,它将深入了解
foo
的历史。当你向Git询问
bar
的历史时,它会:1.注意合并和恢复之间没有变化,
1.检测到
bar
来自MERGED的SAVED父节点,并且1.在ORIG_HEAD和SAVED之间检测
foo
的重命名。从那里,它将深入了解
foo
的历史。就这么简单:)
你只需要强制Git进入一个合并的状态,在那里你可以接受文件的两个可跟踪的副本,我们通过并行移动原始文件来完成这一点(我们很快就会恢复)。
liwlm1x92#
与Subversion不同的是,git没有每个文件的历史记录。如果你查看提交的数据结构,它只指向以前的提交和这次提交的新树对象。提交对象中没有存储明确的信息,也没有存储这些提交改变了哪些文件,以及这些改变的性质。
检查更改的工具可以基于语法来检测重命名。例如,
git diff
具有打开重命名检测的选项-M
。因此,在重命名的情况下,git diff
可能会显示一个文件已被删除,另一个文件已被创建,而git diff -M
实际上会检测移动并相应地显示更改(有关详细信息,请参阅man git diff
)。所以在git中,这不是你如何提交更改的问题,而是你以后如何看待提交的更改。
qxsslcnc3#
只需复制文件,添加并提交它:
字符串
然后,以下命令将显示完整的复制前历史记录:
型
要查看从原始文件继承的逐行注解,请使用以下命令:
型
Git不会在提交时跟踪副本,而是在使用
git blame
和git log
检查历史时 * 检测 * 副本。大部分信息来自这里的答案:Record file copy operation with Git
huwehgph4#
我稍微修改了Peter's answer here,创建了一个可重用的、非交互式的shell脚本
git-split.sh
:字符串
z4iuyo4d5#
为了完整起见,我想补充一点,如果你想复制一个充满受控和不受控文件的整个目录,你可以使用以下方法:
字符串
不受控制的文件将被复制,所以你应该清理它们:
型
tp5buhyn6#
在我的情况下,我在我的硬盘上进行了更改(剪切/粘贴大约200个文件夹/文件从一个路径在我的工作副本到另一个路径在我的工作副本),并使用SourceTree(2.0.20.1)对检测到的变化进行分级(一个添加,一个删除),只要我把添加和删除放在一起,它自动组合成一个粉红色的R图标(重命名我假设)的单一变化。
我确实注意到,因为我一次有这么多的更改,SourceTree检测所有更改的速度有点慢,所以我的一些暂存文件看起来像只是添加(绿色加号)或只是删除(红色减号),但我不断刷新文件状态,并不断暂存新的更改,因为它们最终弹出,几分钟后,整个列表都很完美,可以提交了。
我验证了历史是存在的,只要当我寻找历史,我检查“跟随重命名的文件”选项。
tct7dpnv7#
这个过程保留了历史,但几乎没有变通方法:
字符串