我尝试将目录及其所有历史记录从存储库移动到另一个存储库。
提取目录的完整历史记录很容易git subtree split
.
这将创建一个新分支,可以轻松地将其提取到其他存储库。
现在我用了git subtree add
将目录粘贴回第二个存储库。
如果我看gitk
or git log --decorate --graph
一切看起来都很好。所有提交均按预期出现。此外,所有文件都按预期存在。
但是当我尝试使用查看移植文件的历史记录时git log -- transplanted_dir/somefile
,我只看到一个“合并”提交,这是由git subtree add
.
为什么我在上面的 gitk 中看到提交,但在单个文件的日志中看不到?
如果我做一个简单的git merge
,我可以看到每个文件的历史记录,但这些文件当然不会存在于子文件夹中。
将移动的提交集成到其他存储库的正确方法是什么?
重现情况的详细示例命令:
#create two repositories:
git init a
git init b
# create directory dir with some history
cd a
mkdir dir
echo 1 > dir/file
git add .
git commit -am 1
echo 2 > dir/file
git commit -am 2
echo 3 > dir/file
echo 3 > otherfile
git add .
git commit -am 3
#split subtree
git subtree split --prefix dir -b split
#create a commit on repo b
cd ../b
mkdir otherdir
touch otherdir/file
git add .
git commit -am init
#fetch split branch of repo a
git fetch ../a split
git co -b split FETCH_HEAD
git log --decorate --graph --name-status
git co master
# add commits to repo b
git subtree add --prefix somedir split
# this looks fine:
git log --decorate --graph --name-status
# no history here - Why?
git log --decorate --graph --name-status somedir/file
git log --decorate --graph --name-status --follow somedir/file
好吧,阅读源代码就清楚了。
git subtree add
相当丑陋:它首先使用git read-tree
添加current版本without给定目录中的任何历史记录。之后它使用git commit-tree
创建一个假合并提交来附加包含无前缀文件的旧历史记录。
另一方面,现在 HEAD 中的带前缀文件和 HEAD^2 中的无前缀文件应该完全相同,并且应该被识别为移动--follow
.
不幸的是,它并没有得到这样的认可。不知道为什么。
最好的解决方案可能是添加显式提交,将文件移动到新目录并进行正常合并。 - 另一种方法是重写移植目录的历史记录,如中所述如何重写历史记录,以便除已移动的文件之外的所有文件都位于子目录中? https://stackoverflow.com/questions/4042816/how-can-i-rewrite-history-so-that-all-files-are-in-a-subdirectory.
对于我的情况git subtree add
不好,正常git merge
使用正确准备的子树似乎是完全正确的事情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)