将现有 git 仓库中的子目录分离为独立仓库并保留其提交历史

1. 需求分析

我为什么会有如本文标题所述这样的需求呢?这是因为在写的一个项目,新建里多个分支分,但有部份dll是每个分支共的代码,如果的A分支修改dll1 ,并而当前不想同步到其他的分支,后期其他的分支或者工程需要用到。此时,如果把整个dll代码复制过去,当然可以实现功能,但是,会缺失部份dll修改时的log,而且这样操作也麻烦,也不能保证代码统一性。

所以后面考虑使用此方法,思路如下:

1. 将现有 git 仓库中的子目录分离为独立仓库并保留其提交历史

2. 在现在库新建子模块,子模块内容为新的dll仓库

现有项目布局:

big-repo
├── .git
├── avatar-api
├── config-generator
├── register-email-validation
│   ├── bootstrap.php
│   ├── package.json
│   └── src
├── report-texture
└── name-of-folder  <---【我想把这个独立为一个新 repo】
    ├── bootstrap.php
    ├── package.json
    ├── routes.php
    └── src

2. 文章描述约定

为了方便描述后续操作,这里稍微约定一下文章中各占位符的含义。

  • 原来的仓库: <big-repo>
  • 想要分离出来的子文件夹名称: <name-of-folder>
  • 该子文件夹形成的新仓库: <new-repo>

3. 方法一

# 进入父目录
cd big-repo 
#为模块name-of-folder的目录创建一个新的分支名为 name-of-folder-branch
git subtree split -P name-of-folder name-of-folder-branch 
#退到和父目录同级的目录
cd ..
#为name-of-folder新建一个和父目录同级的目录name-of-folder-dir
mkdir name-of-folder-dir 
#进入新建的目录
cd name-of-folder-dir
#初始化git
git init
# 将分离出来的分支pull到新建的文件目录下
git pull ../big-repo big-repo -branch 

git remote add origin XXXXXXXXX.git
git push -u origin master

4. 方法二

4.1. 实现子目录分离为独立仓库,使用 git filter-branch

除了使用新添加的 subtree 命令,你也可以使用 git 传统的所谓核弹级大杀器命令 —— filter-branch 解决上述问题。

首先,clone 一份原仓库并删掉原来的 remote:

git clone big-repo <new-repo>
cd <new-repo>
git remote rm origin

然后运行如下命令(这是重点): 

git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter <name-of-folder> -- --all

这条命令同样会过滤所有历史提交,只保留所有对指定子目录有影响的提交,并将该子目录设为该仓库的根目录。这里说明各下个参数的作用:

  • --tag-name-filter 该参数控制我们要如何处理旧的 tag,cat 即表示原样输出;
  • --prune-empty 删除空的(对子目录没有影响的)提交;
  • --subdirectory-filter 指定子目录路径;
  • -- --all 该参数必须跟在 -- 后面,表示对所有分支进行操作。如果你只想保存当前分支,也可以不添加此参数。

该命令执行完毕后就可以看到新仓库中已经变成子目录的内容了,且保留了关于该子目录所有的提交历史。不过只是这样的话新仓库中的 .git 目录里还是保存有不少无用的 object,我们需要将其清除掉以减小新仓库的体积(如果你用上面 subtree 的方法的话是不需要执行这一步的)。

以下git 指令一条一条执行就行,不需要修改

git reset --hard
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
git reflog expire --expire=now --all
git gc --aggressive --prune=now

 4.2. 关联新仓库和上传

git commit -m "first commit"
git remote add origin XXXX.git
git push -u origin master

5.  完成

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值