我在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项目),我们需要创建一个新版本的代码,以便我们的客户能够在运行时有2个不同的版本,第一个版本将最终在对齐时被删除。 当然,我们可以使用maven版本,我只是Git的新手,对Git在这里能提供什么很好奇。


当前回答

我在这里稍微修改了Peter的回答,创建了一个可重用的、非交互式的shell脚本git-split.sh:

#!/bin/sh

if [[ $# -ne 2 ]] ; then
  echo "Usage: git-split.sh original copy"
  exit 0
fi

git mv "$1" "$2"
git commit -n -m "Split history $1 to $2 - rename file to target-name"
REV=`git rev-parse HEAD`
git reset --hard HEAD^
git mv "$1" temp
git commit -n -m "Split history $1 to $2 - rename source-file to temp"
git merge $REV
git commit -a -n -m "Split history $1 to $2 - resolve conflict and keep both files"
git mv temp "$1"
git commit -n -m "Split history $1 to $2 - restore name of source-file"

其他回答

在我的例子中,我在我的硬盘驱动器上进行了更改(从我的工作副本中的一个路径剪切/粘贴大约200个文件夹/文件到我的工作副本中的另一个路径),并使用SourceTree(2.0.20.1)来执行检测到的更改(一个添加,一个删除),只要我同时执行添加和删除,它就会自动合并为带有粉红色R图标的单个更改(我假设是重命名)。

我确实注意到,因为我一次有这么多更改,SourceTree检测所有更改的速度有点慢,所以我的一些阶段性文件看起来只是添加(绿色加)或删除(红色减),但我不断刷新文件状态,并在最终出现新的更改时持续呈现,几分钟后,整个列表完美无缺,可以提交了。

我验证了历史记录是存在的,只要当我寻找历史记录时,我检查了“跟踪重命名文件”选项。

我在这里稍微修改了Peter的回答,创建了一个可重用的、非交互式的shell脚本git-split.sh:

#!/bin/sh

if [[ $# -ne 2 ]] ; then
  echo "Usage: git-split.sh original copy"
  exit 0
fi

git mv "$1" "$2"
git commit -n -m "Split history $1 to $2 - rename file to target-name"
REV=`git rev-parse HEAD`
git reset --hard HEAD^
git mv "$1" temp
git commit -n -m "Split history $1 to $2 - rename source-file to temp"
git merge $REV
git commit -a -n -m "Split history $1 to $2 - resolve conflict and keep both files"
git mv temp "$1"
git commit -n -m "Split history $1 to $2 - restore name of source-file"

为了完整起见,我想补充一点,如果你想复制一个充满受控和不受控文件的整个目录,你可以使用以下方法:

git mv old new
git checkout HEAD old

不受控制的文件将被复制,所以你应该清理它们:

git clean -fdx new

这个过程保存了历史,但没有什么变通办法:

# make branchs to new files
$: git mv arquivos && git commit

# in original branch, remove original files
$: git rm arquivos && git commit

# do merge and fix conflicts
$: git merge branch-copia-arquivos

# back to original branch and revert commit removing files
$: git revert commit

简单地复制文件,添加并提交:

cp dir1/A.txt dir2/A.txt
git add dir2/A.txt
git commit -m "Duplicated file from dir1/ to dir2/"

然后,下面的命令将显示完整的预拷贝历史记录:

git log --follow dir2/A.txt

要查看从原始文件继承的逐行注释,请使用以下命令:

git blame -C -C -C dir2/A.txt

Git不会在提交时跟踪副本,而是在检查历史记录时进行检测,例如Git blame和Git log。

大部分信息来自这里的答案:用Git记录文件复制操作