我想将多个Git存储库(比如repoA和repoB)合并到一个新存储库中。新的存储库(repoNew)应在单独的子目录中包含每个repoA和repoB。由于我到目前为止只在本地工作,所以我可以对存储库做任何我想做的事情。

在这种情况下,似乎标准方法是使用git filter-branch重写每个repoA和repoB的历史记录,以使其看起来好像一直在子文件夹中,然后将它们合并为repoNew。

第一步是让我感到困扰的事情。我很清楚SO答案,例如How can I rewrite history so that all files, except the ones I already moved, are in a subdirectory?(Dan Moulding的答案),这正是我想要的。

他提出了以下建议:

git filter-branch --prune-empty --tree-filter '
if [[ ! -e repoA ]]; then
    mkdir -p repoA
    git ls-tree --name-only $GIT_COMMIT | xargs -i mv {} repoA
fi'

结果应该是<repoA-GIT-base>下的文件夹结构现在应该在<repoA-GIT-base>/repoA中。然而,这种情况并非如此。上面的命令在不同的提交中随机失败,并显示“mv:无法将'src'移到'repoA/src'这样的消息

如所述重写历史记录时如何避免这些错误的提交?

编辑:

您应该考虑从移动中排除.gitignore,如下所示:
git filter-branch --prune-empty --tree-filter '
if [[ ! -e repoA ]]; then
    mkdir -p repoA;
    git ls-tree --name-only $GIT_COMMIT |
    grep -ve '^.gitignore$' |
    xargs -i mv {} repoA;
fi'

该命令似乎仍然是随机失败的。我尝试了几次,每次都在不同的提交中发生了“无法移动”失败。我观察到,当我排除.gitignore时,通过所有提交使其成功的机会似乎增加了。我能够在三个不同的存储库中连续执行迁移,而不会失败。当我再次尝试在另一个存储库的一次性废弃副本上进行娱乐时,它再次失败。

由于有时由于使用某些文件的过程而导致我有时也无法删除废弃的副本,因此该问题可能与Windows 7文件访问处理有关,但我无法在此处进行认真的假设。

一直尝试直到成功为止都是荒谬的,并且可能无法在具有大量提交的存储库上工作(我的数据库只有大约30个)。

信息:我在Windows 7 64位企业版上使用git-bash和git版本1.7.10.msysgit.1。

最佳答案

我怀疑您在寻找类似于git subhistory的东西。这是一个很小的项目,似乎没有得到很好的维护,但它的目的也几乎是您所描述的。试一试!

08-27 12:05