我想将两个回购A和B合并到一个共同的回购C. A和B都在根文件夹级别有很多文件,所以我想在repo C的根文件夹中创建文件夹A和B,并将每个原始repo的内容放在匹配的文件夹中。
是否在此过程中不使用git mv
而执行此操作?问题是我使用Xcode,遗憾的是它不遵循重命名文件的历史记录,所以我想尽可能避免移动。实际上,我想将每个repo直接合并到其子文件夹中。
答案 0 :(得分:1)
实现这一目标的方法有很多,而且这个问题的博客帖子和SO答案的数量是其两倍。最简单的解决方案可能是使用git-stitch-repo工具。
另一个选项(我没有尝试过)是遵循这个blog post。但它非常血腥,如果您想要移动到子目录中的点文件,则需要进行一些调整。
答案 1 :(得分:1)
git-subtree
脚本及其add
命令。将创建合成历史记录,就像始发代码始终位于指定目录中一样。答案 2 :(得分:1)
我已经能够通过建立迈克尔建议的blog post来进行合并。原始帖子只负责合并主分支 - 我已经扩展它以从合并的存储库中提取所有分支,因此不会丢失历史记录。
重申一下,我发现了许多其他建议的方法来进行这种合并,但没有一种方法可以保存历史记录而不重命名路径(导致Xcode无法显示历史记录)。
# Init a git repo which will contain the merge of the two repos, each in its own subdirectory
cd ~/dev
mkdir Merged
cd Merged
git init
# Dummy initial commit to create a master branch
git commit --allow-empty -m "Initial commit"
# Clone first repo
cd ..
git clone <RepoA url>
cd RepoA
# Checkout all branches
for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done
# Prepend subdirectory to all committed files paths in all branches
git filter-branch -f --prune-empty --tree-filter ' mkdir -p .sub;
find . -mindepth 1 -exec mv {} .sub;
mv .sub RepoA
' -- --glob=refs/heads/*
# Garbage cleanup
git gc --aggressive
# Same steps for second repo
cd ..
git clone <RepoB URL>
cd RepoB
# Checkout all branches
for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done
# Prepend subdirectory to all committed files paths in all branches
git filter-branch -f --prune-empty --tree-filter ' mkdir -p .sub;
find . -mindepth 1 -exec mv {} .sub;
mv .sub RepoB
' -- --glob=refs/heads/*
# Garbage cleanup
git gc --aggressive
# Merge modified repos into unified repo
cd ../Merged
git remote add RepoA ../RepoA
git remote add RepoB ../RepoB
git fetch --all
for remote in `git branch -r`; do git checkout -b $remote --track $remote ; done
# Merge wanted branches (usually master) from each original repo into the master branch of the unified repo
git checkout master
git merge RepoA/master
git merge RepoB/master
# Remove remotes
git remote rm RepoA
git remote rm RepoB
# Garbage cleanup
git gc --aggressive
# All done
# Optionally push into a new empty remote repository
git remote add RepoMerged <Merged Repo URL>
git push --all RepoMerged