事实证明,如果您只是尝试将两个存储库粘合在一起并使其看起来一直都是这样,而不是管理外部依赖项,那么答案会简单得多。您只需将遥控器添加到旧存储库,将它们合并到新主库,将文件和文件夹移动到子目录,提交移动,然后重复所有其他存储库。子模块、子树合并和花哨的变基旨在解决稍微不同的问题,并不适合我想要做的事情。
这是一个将两个存储库粘合在一起的示例 Powershell 脚本:
# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init
# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"
# Add a remote for and fetch the old repo
# (the '--fetch' (or '-f') option will make git immediately fetch commits to the local repo after adding the remote)
git remote add --fetch old_a <OldA repo URL>
# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories
# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}
# Commit the move
git commit -m "Move old_a files into subdir"
# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"
显然,如果您愿意,您可以将 old_b 合并到 old_a 中(这将成为新的组合存储库)——修改脚本以适应。
如果您还想引入正在进行的功能分支,请使用以下命令:
# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress
这是该过程中唯一不明显的部分——这不是子树合并,而是正常递归合并的一个参数,它告诉 Git 我们重命名了目标并帮助 Git 正确排列所有内容。
我在这里写了一个更详细的解释。