且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将两个git repos合并成一个,不用重命名文件

更新时间:2023-11-23 19:42:46

我已经能够合并建立在Michael建议的博文上。原始帖子只负责合并主分支 - 我已经扩展了它以从合并回购仓库中提取所有分支,所以没有任何历史记录丢失。

重申,我发现了许多其他建议的方法来进行这种合并,但没有一个既保存历史记录又不重命名路径(导致Xcode无法显示历史记录)。

 #初始化一个git仓库,它将包含两个仓库的合并,每个仓库都在它自己的子目录中
cd〜/ dev
mkdir合并
cd合并
git init
$ b $#虚拟初始提交创建主分支
git commit --allow-empty -m初始提交

#克隆首先回购
cd ..
git克隆< RepoA url>
cd RepoA

#签出所有分支
用于远程`git branch -r | grep -v master`;做git checkout --track $ remote;完成

#在所有分支中的所有提交文件路径上加上子目录
git filter-branch -f --prune-empty --tree-filter'mkdir -p .sub;
找到。 -mindepth 1 -exec mv {} .sub;
mv .sub RepoA
' - --glob = refs / heads / *

#垃圾清理
git gc --aggressive

#第二次回购的步骤相同
cd ..
git clone< RepoB URL>
cd RepoB

#签出所有分支
用于远程`git branch -r | grep -v master`;做git checkout --track $ remote;完成

#在所有分支中的所有提交文件路径上加上子目录
git filter-branch -f --prune-empty --tree-filter'mkdir -p .sub;
找到。 -mindepth 1 -exec mv {} .sub;
mv .sub RepoB
' - --glob = refs / heads / *

#垃圾清理
git gc --aggressive

#将修改过的回购合并到统一回购中
cd ../Merged
git remote add回购../RepoA
git远程添加回购../RepoB
git fetch - 所有
在`git branch -r`中用于远程;做git checkout -b $ remote --track $ remote;完成

#将每个原始回购合并的通缉分支(通常为主)合并到统一回购的主分支中
git checkout master
git merge RepoA / master
git合并RepoB / master

#删除远程
git remote rm RepoA
git remote rm RepoB

#垃圾清理
git gc - 积极的

#全部完成

#可选地推入一个新的空的远程仓库
git remote add RepoMerged< Merged Repo URL>
git push --all RepoMerged


I'd like to merge two repos A and B into a common repo C. A and B both have a lot of files at the root folder level, So I'd like to create folders A and B in the root folder of repo C, and put the content of each original repo in its matching folder.

Is there do this without using git mv in the process? The problem is that I'm using Xcode which unfortunately doesn't follow the history of renamed files, so I'd like to avoid moves if possible. In effect, I'd like to merge each repo directly into its subfolder.

I've been able to do the merge by building on the blog post suggested by Michael. The original post only takes care of merging the master branch - I've expanded it to pull all branches from the merged repos so no history is lost.

To reiterate, I've found many other suggested methods of doing this sort of merge, but none which both save the history and don't rename paths (causing Xcode to fail showing history).

# 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