一.需求描述:
现有一个git仓库,Team A和Team B的人操作同一仓库的不同目录,Team A的dev希望Team B的dev没有权限review属于Team A的代码目录,故现需要先将这个git 库下的子目录进行拆分,为后续单git库权限独有覆盖做准备.
二.操作背景:
Ubuntu shell(终端)
三.迁移(使用filter-branch命令)
由于我需要迁移的子目录包含中文名,因此需要使用filter-branch命令来实现迁移,当然,如果不包含中文的目录也可以使用git1.8版本以后的subtree来实现,该方法稍后说明。
- 首先,clone 一份原仓库并删掉原来的 remote:(依次执行以下命令)
(1)git clone ssh://username@xx.x.xx.xxx:29418/vendor/lenovo
(2)cd lenovo
(3)git remote rm origin - 然后运行如下命令(这是重点):
(1)git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter -- --all
这条命令同样会过滤所有历史提交,只保留所有对指定子目录有影响的提交,并将该子目录设为该仓库的根目录。这里说明各下个参数的作用:
--tag-name-filter 该参数控制我们要如何处理旧的 tag,cat 即表示原样输出;
--prune-empty 删除空的(对子目录没有影响的)提交;
--subdirectory-filter 指定子目录路径;
-- --all 该参数必须跟在 -- 后面,表示对所有分支进行操作。如果你只想保存当前分支,也可以不添加此参数。 - 清理.git的object
当上述命令执行完毕后,就可以看到本地的新仓库已经是原仓库子目录中的内容了,且保留了关于该子目录所有的提交历史。不过只是这样的话新仓库中的
.git 目录里还是保存有不少无用的 object,我们需要将其清除掉以减小新仓库的体积(如果你用subtree 的方法的话是不需要执行这一步的)。
依次执行以下命令:
(1)git reset --hard
(2)git for-each-ref --format="%(refname)" refs/original/ |xargs -n 1 git update-ref -d
(3)git reflog expire --expire=now --all
(4)git gc --aggressive --prune=now
温馨提示:git gc操作耗时比较久,请耐心等待. - 将新的本地仓库推送到远端
cd到
(1)添加远端地址:
git remote add origin
(2)推送到远端:
git push -u origin master或者git push --fore origin master
四.补充subtree方式迁移
要求拆分的目录没有中文名
1.首先,进入 所在的目录,创建一个的临时分支,运行:
git subtree split -P -b
- 然后,我们创建一个新的 git 仓库:
(1)mkdir
(2)git init - 接着把原仓库中的临时分支拉到新仓库中:
git pull
好了,完成。现在看看你的新仓库,是不是已经包含了原子文件夹中的所有文件和你之前在原仓库中的所有提交历史呢?后续步骤就可参照第二章中的3,4,5步了。
参考链接:
https://blog.csdn.net/wang252949/article/details/80003791
https://blessing.studio/splitting-a-subfolder-out-into-a-new-git-repository/