我想将多个 Git 存储库(比如说 repoA 和 repoB)合并到一个新的存储库中。新存储库 (repoNew) 应在单独的子目录中包含每个 repoA 和 repoB。由于到目前为止我只在本地工作,所以我可以对存储库做任何我想做的事情。
在这种情况下,标准方法似乎是使用git filter-branch
重写每个 repoA 和 repoB 的历史记录,使其看起来好像它们一直在子文件夹中,然后将它们合并到 repoNew 中。
第一步是困扰我的事情。我很清楚这样的答案,例如如何重写历史记录,以便所有文件,除了我已经移动的文件,都在子目录中?(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: cannot move 'src' into '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。