Git-subtree&submodule拆分与管理

Android

随着业务需求越来越庞大,Git仓库包含很多可以独立拆分的Module,因此拆分出独立的模块出来,将子目录作为一个新的仓库,并且保留Log记录,同时方便其他工程调用

仓库拆分

手动强拆

直接copy一份目标目录代码,非常简单,但是会导致Log记录缺失。

git filter-branch

  • clone一份原仓库,并且删除remote

    1
    2
    3
    > git clone <big-repo>  <new-repo>
    > cd <new-repo>
    > git remote rm origin
  • 拆分

    1
    2
    3
    4
    // 会带着tag记录
    > git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter <name-of-folder> -- --all
    // 没有带tag
    > git filter-branch -f --prune-empty --subdirectory-filter <name-of-folder>

参数说明:

1
2
3
4
5
这条命令同样会过滤所有历史提交,只保留所有对指定子目录有影响的提交,并将该子目录设为该仓库的根目录。这里说明各下个参数的作用:
--tag-name-filter 该参数控制我们要如何处理旧的 tagcat 即表示原样输出;
--prune-empty 删除空的(对子目录没有影响的)提交;
--subdirectory-filter 指定子目录路径;
-- --all 该参数必须跟在 -- 后面,表示对所有分支进行操作。如果你只想保存当前分支,也可以不添加此参数。

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

    1
    2
    3
    4
    > 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
  • 推送新仓库到远端

    1
    2
    3
    4
    5
    cd到<new-repo>
    // 添加远端地址:
    > git remote add origin <new-git-url>
    // 推送到远端:
    > git push -u origin master

git subtree

git subtree比上面的方法都简单,需要高版本的git支持,1.8

  • 进入 所在的目录,创建一个的临时分支
    1
    > git subtree split -P <name-of-folder> -b <name-of-new-branch>

说明:分离目录,把它作为一个名字是的branch
注意:有时候偶尔会没有拆分,会拉取原仓库所有的log,这个时候就要注意一下,拆分的目录的Log会少一些;不成功多尝试几次

  • 创建一个新的 git 仓库,用于分离的目录

    1
    2
    3
    > mkdir <new-repo>
    > cd ../<new-repo>
    > git init
  • 拉取原仓库</path/to/big-repo>的临时分支到新的仓库中 master 分支

    1
    > git pull </path/to/big-repo> <name-of-new-branch>
  • 推送到远程

    1
    2
    3
    4
    5
    cd到<new-repo>
    // 添加远端地址:
    > git remote add origin <new-git-url>
    // 推送到远端:
    > git push -u origin master

subtree

谢谢老板,请尽情用红包来蹂躏我吧!!!
0%