Git:重新建立一个完整的项目,包括分支结构

时间:2013-04-11 18:26:17

标签: git version-control rebase

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

我最接近的是使用master选项将X重新绑定到-p,但仍然会为G'产生合并冲突,尽管来自{{可以毫无问题地应用{1}}到D

3 个答案:

答案 0 :(得分:1)

Rebase不适合进行如此复杂的历史重写。 filter-branch是正确的工具。最简单的方法可能是将您的文件放在某个文件夹中而不是在您的仓库中,并在--all --not A上运行一个树形过滤器,将该文件复制到您的工作目录中。

答案 1 :(得分: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/...自动为备份目的创建的所有git filter-branch引用。

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

git gc --prune=now

答案 2 :(得分:0)

而不是写一个详细的解决方案,其他人很容易做出回答。 这是一个视觉(交互式教程),将向您解释您需要做什么。

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