前情提要
因业务变动,有一个旧服务代码需要作为一个子模块(子文件夹)合并进一个新的大项目来维护,并希望保留之前的commit记录。对应的Git操作在中文网上并未直接搜到,遂将Google到的一片教程翻译在此,以便后来查阅。
原文地址:Moving One Git Repository Into Another As A Subdirectory
译文
时间有限,目前一半内容是Google翻译
我最近不得不将许多独立项目合并为一个更大的项目,以实现长期项目的重组工作。因为我们使用Git管理所有项目,这应该很容易,但是仍然需要一些研究才能弄清楚改如何去做。
所以假设如果你有两个项目:old-project
和new-project
,你想最终得到一个名为old-project
的新项目中的子目录,并带有旧项目的所有代码,并且要保留该项目的历史记录。
这是我们为此要做的事情的概述:
- 获取包含正在拉入的项目的存储库的本地副本
- 修改本地副本以将所有文件移动到子目录中
- 将本地副本作为伪造的“远程”添加到我们更大的项目中
- 把当地的“远程”拉进来,从而把整个历史也拉进来
出于本演示的目的,old-project
被克隆在/home/machete/old-project
,new-project
被克隆在/home/machete/new-project
。
最后,我们希望有一个/home/machete/new-project/old-project
,并完整带着old-project
所有提交。
我们将要做的是,将old-project
完全覆盖在new-project
之上,所以首先我们需要调整old-project
里面的目录:
$ cd /home/machete/old-project
$ mkdir old-project
$ mv !(old-project) old-project
$ git commit -a -m "Preparing old project for move"
我们所做的就是将old-project
项目代码库中的每个文件移动到同名的子目录中。所以你现在有了/home/machete/old-project/old-project
。然后提交,您应该在提交中看到每个文件更改都是重命名。
这只是将old-project
下所有文件移动到与我们想要在new-project
其中包含的内容匹配的子目录结构中,然后进行提交。
接下来,我们需要将此存储库的历史记录复制到new-project
。所以我们不必在任何地方推送我们的临时移动,我们将添加我们的本地目录作为远程 git 存储库,然后将其更改拉入。
$ cd /home/machete/new-project
$ git remote add temp /home/machete/old-project
$ git fetch temp
$ git merge temp/master
$ git remote rm temp
注:
合并本地分支时,请注意你目前所在的new_project
分支是否正确,且你不一定非要合并temp/master
分支,这要依据你的实际情况。
另外,如果在执行分支合并时报错:fatal: refusing to merge unrelated histories
,请添加参数:--allow-unrelated-histories
这会将旧项目的全部历史记录拉入其中。此历史记录包括一个提交,其中所有文件都被移动到名为old-project
的子目录中,因此您在new-project
中留下了一个子目录old-project
。
由于我们进行了合并,我们将在 HEAD 有一个新的提交,它有两个父级,一个用于常规代码行old-project
,一个用于旧代码行new-project
。
就是这样,你可以new-project
在任何地方推送,下一次获取将拉下所有old-project
的历史记录。
回到您的old-project
并进行删除整个旧项目子目录的提交也是一个好主意,编写一个自述文件表明该项目已被拉入new-project
并提交并推送它。