领导说:
“目前各个项目分散在不同的仓库中,不利于管理,需要将多个项目仓库合并到一个工程仓库来进行开发,要求保留各个仓库迁移前的commits 记录,最好还能对命名不规范的项目进行重命名”
恕我直言,可以实现!
Git 多仓库合并
假设要合并ABC 不同的分支到新工程X,ABC 工程作为X工程的子目录
迁移A 工程的5.0分支到新工程X的A1目录
迁移B工程的dev分支 到新工程X的B1目录
迁移C 工程的6.0分支 到新工程X的C1目录
期望:合并后的目录结构
新工程X(master分支)
.
├── A1 (原A工程的某分支)
├── B1 (原B工程的某分支)
├── C1 (原C工程的某分支)
.git
README.md
准备工程合并目录
1.1 新建合并用的目录 combine
1 | mkdir combine && cd combine |
1.2 切换到combine 目录,新建合并后的工程目录;假设新合并工程为 argo
,仓库地址为http://git.analysys.cn/sloong/argo.git
1 | mkdir argo && cd argo |
1.3 准备迁移后的分支
1 | echo "" > _base.txt |
git clone 需要合并的项目分支到本地
在combine空目录,将需要合并的工程(可指定分支)全部clone到本地(后续也可以继续加项目合并,后面的步骤一样)
git 操作指令: git clone -b <分支名> <仓库地址>
1 | 切换到combine 目录 |
这时完成 git clone
操作后目录下结构如下
1 | tree -L 2 |
调整待合并项目的目录结构
我们期望合并过去的项目都是在自己单独的目录下,如果直接合并,实际是工程目录下的文件/文件夹 平铺到合并后的,而且会存在冲突,所以希望合并过去的子项目,都位于合并工程的特定子目录中
假设我需要合并的主工程名称为argo,那么期望的目录结构如下:
1 | ├── argo -- 合并后工程目录 |
所以我们需要对每一个子工程其进行 git mv
操作,在 git mv
同时可以对原工程进行子目录改名。
1 | # 切换到子工程 ark-canary-api |
移动后的当前子工程的目录结构如下
1 | ark-canary-api git:(dev-5.0) tree -L 2 |
对改动进行 git commit
操作,只需要操控本地仓库,所以不要push origin
1 | git add . |
分别对其他两个子工程进行上述操作
给 主工程 添加远程仓库
实际是给argo工程,添加 clone下来本地的三个子工程的仓库地址
涉及的git操作指令为: git remote add <shortname> <子项目本地仓库地址>
1 | cd argo --argo目录 |
添加子工程的辅助分支(要合并子工程的分支)
先fetch all
1 | cd argo --argo目录 |
再checkout -b
创建子项目对应的辅助分支
涉及的git 操作指令:git checkout -b <分支名> <仓库地址/别名>
1 | git checkout -b b_server r_server/dev-5.0 |
切换回主分支,合并辅助分支
将辅助分支合并到主工程的分支上,因为各个子项目都有单独的子目录,所以不会出现冲突。
涉及的git 操作指令:git merge -b <分支名> --allow-unrelated-histories
。因为原本几个仓库不相关,所以合并时,需要加上 --allow-unrelated-histories
1 | cd argo --还是argo目录 |
合并收尾,清除临时分支和remote 仓库
1 | 删除3个远程仓库链接 |
最后push origin
,完成多项目的迁移合并
1 | git push origin master |
效果图
本质来看就两个步骤:
1.将各个子项目git仓库作为远程库拉取到合并库中的一个辅助分支
2.再将此辅助分支合并入当前分支
迁移合并多项目的多分支
领导觉得太简单,又提要求说:
“不仅要将多个项目仓库合并到一个工程仓库,保留commits 记录同时,还要将不同项目的不同分支迁移合并到新工程对应版本分支”
恕我直言,可以实现!
上面所有的步骤最终将多个项目的某个分支合并到了新工程的master分支,但如果又要迁移合并多项目,还要迁移这些项目的几个分支合并到新的指定分支上,所以迁移的工作量成倍增长:重复上述7步骤 * n个项目* m个分支
需求简化:假设要同时
迁移ABC 工程的4.6分支到新工程的4.6分支
迁移ABC 工程的5.0 到新工程的5.0分支
迁移ABC 工程的6.0 到新工程的master分支
期望:合并后的目录结构
新工程X(4.6分支)
.
├── A1 (原A工程的4.6.0分支)
├── B1 (原B工程的4.6.1分支)
├── C1 (原C工程的4.6.0分支)
.git
README.md新工程X(5.0分支)
.
├── A1 (原A工程的5.0分支)
├── B1 (原B工程的5.2分支)
├── C1 (原C工程的5.4分支)
.git
README.md新工程X(master分支) 同理省略……
多项目多分支迁移合并到指定分支方案
关键点:一定在一开始的时候要基于空白分支先把需要的版本分支建出来,然后对应不同的分支 重复做前面的1.5
、1.6
两个步骤。
因为在最初的步骤涉及到关键修改,所以一定要是一个新仓库、从头开始。
合并迁移的步骤大致上面一致,只是部分步骤需要做一些改动,所以就不开篇重写,就将各个步骤的改动写上来:
改动1: 上述1.1.3 步骤基于master分支,多建几个要迁移的分支:
1 | argo 目录 |
改动2: 不算改动,说明下:在步骤1.2 中,不clone -b 下载指定分支了,直接clone 整个仓库操作
1 | cd combine |
改动3:步骤1.5,因为需要用到子工程多个分支,那么git checkout -b <分支别名>
分支时,分支别名带上版本名,一次把要用的分支全部建出来
1 | git checkout -b b_udf_4.6 r_udf/4.6 |
其他子项目或者更多分支, 类似重复。
删除辅助分支 也需要一个个删除
改动4:步骤1.6,merge子项目分支 时,merge 指定的版本分支别名。比如合并后版本分支为5.0,那么前面的merge 也是对应的5.0 的分支别名
迁移合并不同分支,先切换到对应的分支上,例如迁移5.0 分支,那么先切到5.0 空分支,然后执行后续操作。
1 | 做4.6 分支合并时,先要切换主工程分支到4.6,再做git merge |
其他子项目或者更多分支, 类似重复
效果展示
本质上还是同样的思路,只是在最初的时候建立相关的空白分支,clone 下整个仓库,在建辅助分支时,一次性将要用的子项目分支都建成辅助分支,最后 将子项目的辅助分支 merge 到主工程对应的版本分支上