[英]Git: Rebase a complete project including branch structure
在要从Mercurial转移到git的项目中,需要重写Mercurial特定的文件(历史上很早的时候)(下图中的X
)。 在此步骤之后,应该传输整个历史记录,就好像该文件始终处于新状态一样,幸运的是,这不应该导致任何合并冲突。
A---B---X
\
\--C---D---G---H master
\ /
E---F---I feature_branch
应该导致
A---B---X---C'---D'---G'---H' master
\ /
E'----F'---I' feature_branch
我能得到的最接近的是使用-p
选项将master
重命名为X
,但是仍然会为G'
产生合并冲突,尽管可以毫无问题地应用从D
到G
的差异。
Rebase不是复杂历史重写的正确工具。 filter-branch是正确的工具。 最简单的方法可能是将您的文件放在某个文件夹中而不是在您的仓库中,并运行树过滤器--all --not A
将该文件复制到您的工作目录中。
根据Chronial的回答,这是我使用的命令(在做备份之后):
B=abcd
X=1234
git filter-branch --parent-filter "sed -e s/$B/$X/g" --tree-filter \
"git checkout X $(git diff-tree --no-commit-id --name-only -r $X | tr '\n' ' ')" \
-- --all --not X
这里,首先将所有对B
父引用替换为对X
的引用,然后将通过此提交更改的文件插入到树中。 此操作适用于不是X
本身的祖先的所有修订。
然后,在检查一切是否按预期工作并进行另一次备份之后(如果我将来需要它以供参考):
git for-each-ref --format='%(refname)' refs/original | xargs -n1 git update-ref -d
这将删除由git filter-branch
自动为备份目的创建的所有refs/original/...
refs。
如果想要不可撤销地删除以前历史记录的所有痕迹并节省磁盘空间,现在可能是收集垃圾的好时机:
git gc --prune=now
而不是写一个详细的解决方案,其他人很容易做出回答。 这是一个视觉(交互式教程),将向您解释您需要做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.