0

在要从 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

我能得到的最接近的方法是使用该选项重新定位,但这仍然会产生合并冲突,尽管从to的差异可以毫无问题地应用masterX-pG'DG

4

3 回答 3

1

Rebase 不是这种复杂历史重写的正确工具。filter-branch是正确的工具。最简单的方法可能是将您的文件放在不在您的存储库中的某个文件夹中,然后在该文件夹上运行一个树过滤器--all --not A,将该文件复制到您的工作目录中。

于 2013-04-11T20:19:39.813 回答
1

根据 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

这会删除所有refs/original/...为备份目的自动创建的 refs git filter-branch

如果一个人想要不可撤销地删除以前历史的所有痕迹并节省磁盘空间,现在可能是收集垃圾的好时机:

git gc --prune=now
于 2013-04-12T16:13:58.397 回答
0

其他人没有编写详细的解决方案,而是使任何答案变得非常容易。这是一个可视化(交互式教程),它将向您解释您需要做什么。

http://pcottle.github.io/learnGitBranching/

于 2013-04-11T18:30:36.760 回答