将大型bzr代码库转换为git,需要注意什么?

13

我正在尝试将一些旧的Bazaar存储库转换为Git,虽然似乎一切顺利进行,但我有点不确定它是否像它声称的那样顺利。

我的Bazaar存储库的结构如下:

  • repo
    • trunk
    • prod
    • feature/feature-branchX
    • feature/feature-branchY

我正在使用快速导出/导入方法在和之间进行迁移。

最初,我使用--export-marks迁移“trunk”,如下所示:

bzr fast-export --export-marks=../$1/marks.bzr ../$1/trunk | git fast-import --export-marks=../$1/marks.bzr --export-marks=../$1/marks.git

当$1作为名称时

然后迭代"repo"目录中的所有其他文件夹并调用:

bzr fast-export --marks=../$1/marks.bzr  --git-branch=$nick ../$1/$b/.. | git fast-import --import-marks=../$1/marks.git --export-marks=../$1/marks.git

使用bzr时,$nick是分支的别名,而$1/$b是分支目录的名称。

就像我之前所说,它会处理所有预期的目录,但在完成后,当我执行:

git branch

它只显示20多个分支,而原始的Bazaar存储库有80多个分支。

现在,仅查看git中的“master”,似乎一切都在那里,缺失的60个分支可能很容易就是已经合并到主干的分支。但我不确定fast-export/fast-import工具是否足够聪明,能够说“算了-你不需要这个”,但也许他们是。

有人有这方面的经验吗?

在从bzr迁移到git后,我只剩下“master”和任何具有未合并提交的分支吗?

最后,为了历史记录,是否有办法强制转换所有分支,即使它们在技术上已经停用?


你使用类似于 https://gist.github.com/bloveridge/624941 的脚本是否观察到相同的结果? - VonC
也许我没有理解正确,但是我认为这个脚本只能在一个分支上工作。也就是说,你不能把“仓库”目录传递给它,只能传递一个已经检出的分支。现在,通过一些我不理解的交互,它可能会检出并读取所有其他分支,但是根据我的理解,它实际上并没有这样做。这也是有道理的,如果你要为迁移准备一个项目,你会关闭其他所有内容,并迁移“主干”,但我不能停止所有项目来完成这个任务。 - Soraz
1个回答

15
似乎快速导入/导出工具确实足够聪明,能够说“嘿-你不需要这个”。尽管这并非火箭科学,就像git branch -d知道何时安全地删除分支一样,git fast-import也可以知道传入的分支是副本。但可能您想要真正确定,我同意。我编写了一个简单(如果效率低下)的脚本来查找唯一的bzr分支列表:
#!/bin/sh

paths=$(bzr branches -R)

for path1 in $paths; do
    merged=
    for path2 in $paths; do
        test $path1 = $path2 && continue
        # is path1 part of path2 ?
        if bzr missing -d $path1 $path2 --mine >/dev/null; then
            # is path2 part of path1 ?
            if bzr missing -d $path1 $path2 --other >/dev/null; then
                echo "# $path1 == $path2"
            else
                merged=1
                break
            fi
        fi
    done
    test "$merged" || echo $path1
done

在Bazaar共享库中运行此命令。它会找到所有分支,然后将每个分支与其他分支进行比较。如果A位于B中,则有两种可能性:也许B也是A,这意味着A == B。否则,A真的是多余的。

脚本过滤已完全合并到至少一个其他分支中的分支。但是,如果有多个相同的分支,则它会打印所有这些分支,并带有以#开头的附加行,表示它们是相同的。

您使用的示例命令bzr fast-export ... | git fast-import ...似乎存在一些不必要的选项。请按照bzr fast-export -h的最后给出的示例来执行以下步骤:

  1. Create a brand new Git repo:

    git init /tmp/gitrepo
    
  2. Go inside your Bazaar shared repo:

    cd /path/to/bzr/shared/repo
    
  3. Migrate your main branch (trunk?) to be the master:

    bzr fast-export --export-marks=marks.bzr trunk/ | \
      GIT_DIR=/tmp/gitrepo/.git/ git fast-import --export-marks=marks.git
    
  4. Migrate all branches:

    bzr branches -R | while read path; do
        nick=$(basename $path)
        echo migrating $nick ...
        bzr fast-export --import-marks=marks.bzr -b $nick $path | \
          GIT_DIR=/tmp/gitrepo/.git git fast-import --import-marks=marks.git \
          &>/tmp/migration.log
    done
    
如果您注意到最后一步没有检查已经迁移的主干,也没有关系,因为它不会再次导入。同时请注意,即使branchA完全合并到branchB中,如果branchA先被Git发现,它仍将被创建。如果先发现branchB,则branchA将不会在Git中创建(“bah-你不需要这个”)。
我找不到强制创建相同分支以便导入到Git的方法,我认为这是不可能的。

谢谢,听起来很有前途。我会试一下的。关于fast-export/fast-import的额外参数,我在其他地方找到了一些信息。显然,你必须从你的“主”bzr分支中--export-marks,然后在所有后续的导出中重用这些标记,以确保快速导入不会仅仅因为是相同的blob而创建新的提交。或者类似的东西。这有意义吗? - Soraz
@Soraz 是的,使用标记肯定是个好主意,但你没有按照文档中所写的方式使用它们。我在我的答案中增加了更贴近文档的步骤。 - janos
1
我在第四步遇到了这个错误: 迁移……bzr: 错误: 未知命令“快速导出”。如何修复? - Ionică Bizău
1
在执行sudo apt-get install bzr-fastimport之后,问题已经解决。 - Ionică Bizău
2
使用此答案时保留所有分支的方法是在转换之前对它们进行全部标记。for d in $(bzr branches); do cd $d; bzr tag b_$d; cd -; done 这将为每个分支添加以“b_”为前缀的标记。转换后,您可以使用 while read tag_name; do git branch ${tag_name:2} $tag_name; done < <(git tag -l | grep ^b_) 将这些标记转换为 Git 分支。在从标记重新创建分支时,已经从转换中存在的分支将只显示一个错误(无害地)表明它们已经存在。 - Derek Veit
1
如果您的bzr分支是在您的bzr存储库的子目录中组织的,那么在第4步中,您可能希望将nick=$(basename $path)更改为nick=$path,以保持git分支的结构。 - Derek Veit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接