2

我想将两个 repos A 和 B 合并到一个公共 repo C 中。A 和 B 在根文件夹级别都有很多文件,所以我想在 repo C 的根文件夹中创建文件夹 A 和 B ,并将每个原始 repo 的内容放在其匹配的文件夹中。

有没有git mv在过程中不使用的情况下这样做?问题是我正在使用 Xcode,不幸的是它没有遵循重命名文件的历史记录,所以我想尽可能避免移动。实际上,我想将每个 repo 直接合并到它的子文件夹中。

4

3 回答 3

1

有很多方法可以实现这一点,并且该问题的博客文章和 SO 答案的数量是其两倍。最简单的解决方案可能是使用git-stitch-repo工具。

另一种选择(我没有尝试过)是关注这篇博文。但它非常血腥,如果您有想要移动到子目录的点文件,则需要进行一些调整。

于 2013-03-18T13:15:44.170 回答
1
  • 子树合并——一个简单的解决方案。只会合并一组文件,同时在不同的前缀(目录)下重新定位它们。不会对这些文件的过去历史做任何事情。
  • 带有命令的git-subtree脚本。add将创建合成历史,就好像原始代码始终位于指定目录中一样。
于 2013-03-18T13:52:03.240 回答
1

通过建立在迈克尔建议的博客文章上,我已经能够进行合并。原始帖子只负责合并主分支 - 我已将其扩展为从合并的存储库中提取所有分支,因此不会丢失任何历史记录。

重申一下,我发现了许多其他建议的方法来进行这种合并,但没有一个既保存历史又不重命名路径(导致 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
于 2013-03-20T07:43:40.527 回答