组件化之仓库迁移
Tags
Git
Date
Apr 23, 2021
组件化的其中一个常见场景,是在一个已经本地组件化(至少已经按文件夹划分)的大仓库里,将其中一个本地组件改为远程组件独立仓库,便于组件复用、版本管理、权限管理等。
 
这里有个问题,远程组件独立的Git仓库,能否保留原来的所有历史记录?
 
答案是可以的,使用git subtree split命令。以下按不同情况说明。
 

从已存在的仓库A拆分一个文件夹到新的仓库中

现在有一个仓库A,如下
.
├── Components
│   ├── Login
│   │   ├── Login.h
│   │   ├── Login.m
│   ├── Pay
│   │   ├── Pay.h
│   │   └── Pay.m
│   └── User
└── Host
准备将其中的Components/LoginComponents/Pay拆分到不同的新的独立仓库,效果如下
A仓库
.
├── Components
│   └── User
└── Host
 
Login仓库
.
├── Login.h
├── Login.m
 
Pay仓库
.
├── Pay.h
└── Pay.m
则步骤如下
  1. A仓库所在目录,运行以下命令。在A仓库的当前分支,遍历所有历史提交,将其中包含路径前缀为Components/Login的文件的提交合并放到名为temp_branch_login(名字无所谓)的临时分支中。注意,由于是遍历,如果A仓库提交数量比较多的话,需要运行较长时间。
git subtree split --prefix Components/Login -b temp_branch_login
2. 等待过程中可以打开你的Git网站创建一个空白的远程仓库,注意不要勾选以下任意选项。
Github
notion image
Gitlab
notion image
3. 在A仓库外的另一个位置,运行以下命令。初始化新的仓库,并将刚刚的临时分支提交复制过来。
mkdir Login
cd Login
git init
git pull A仓库所在路径 temp_branch_login
git remote add origin https://github.com/xxx/xxx.git
git push --set-upstream origin master
这时已经完成了。Login仓库的效果如上述所示。Pay仓库可如法炮制。

从已存在的仓库A拆分一个文件夹到已存在的仓库B中

💡
如果上面的例子里不小心勾选了Initialize repository的选项,就可参考这部分内容。
先使用上述的git subtree split命令,然后在B仓库所在目录里,运行以下命令
git pull A仓库所在路径 temp_branch_login 
如果报错fatal: refusing to merge unrelated histories,则改为运行以下命令
git pull A仓库所在路径 temp_branch_login --allow-unrelated-histories
会产生一个merge,提交即可。完成。

将已存在的仓库B整个迁移合并到已存在的仓库C中

这种情况其实是最简单的,在C仓库所在目录中,运行以下命令
git pull B仓库所在路径 B仓库的某个分支

补充说明

  1. 所谓的保留提交历史,包括提交时间、作者、消息等,但不同仓库同一提交的commithash是不一样的。
  1. 如果迁移后的文件夹组织不符合预期,则按需移动文件然后提交即可,还会保留原有提交历史的。
  1. 通过上述三种情况的组合,加上文件移动,基本上可以任意在不同仓库之间复制和移动文件并保留提交历史。
  1. 这种迁移的本质其实是一个分支与另一个分支(跨仓库)的合并。所以不能同步所有分支。
  1. 迁移之后,原仓库的相关文件,可以自行按需选择删除。
  1. 迁移之后,原仓库的相关文件,如果未删除而且有新的提交,理论上通过同样步骤可以继续迁移新的提交到另一个仓库。
 

Loading Comments...