git在1.8版本后加入了subtree的功能,这个功能比之前的submodule功能强大很多,而且很好用,还是老版本的赶紧升级下吧。
一些使用方法可参见这个页面: http://aoxuis.me/posts/2013/08/07/git-subtree/
当一个项目在开发若干时间后,希望将某个目录单独出一个项目来开发,此时就可以利用这个subtree的功能分离里。
然而直接用git subtree add 的命令会出现 prefix ‘***’ already exists. 这样的错误提示,
这是因为对应的目录已经存在,不能直接添加,需要按下面的方式把对应的目录剥离开然后再加入subtree
具体的操作方式是这样的:
1. 首先cd到需要处理的项目的目录:
pushd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch> # 将需要分离的目录的提交日志分离成一个独立的临时版本
popd
git subtree split -P <name-of-folder> -b <name-of-new-branch> # 将需要分离的目录的提交日志分离成一个独立的临时版本
popd
2. 创建一个新的repo
mkdir <new-repo>
pushd <new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
pushd <new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
3. 连接的github
git remote add origin <git@github.com:my-user/new-repo.git>
git push origin -u master
git push origin -u master
其中第2, 3两步也可以直接clone已有的hub,这样做:
git clone <git@github.com:my-user/new-repo.git> <dir-of-tmp-repo>
git pull </path/to/big-repo> <name-of-new-branch>
git push origin -u master
git pull </path/to/big-repo> <name-of-new-branch>
git push origin -u master
4. 清理数据
popd # get out of <new-repo>
pushd <big-repo>
git rm -rf <name-of-folder>
git commit -m '移除相应模块' # 提交删除申请
git branch -D <name-of-new-branch> # 删除临时分支,也可以不移除,自己看情况
pushd <big-repo>
git rm -rf <name-of-folder>
git commit -m '移除相应模块' # 提交删除申请
git branch -D <name-of-new-branch> # 删除临时分支,也可以不移除,自己看情况
5. 添加subtree
git subtree add -P <name-of-folder> <git@github.com:my-user/new-repo.git> master
git push origin master
git push origin master
执行到第3步时,对应的目录已经剥离出来形成独立的项目了。第4,5步主要是把当前项目的对应的文件给删除,可以不执行,以后可以通过
# 更新
git subtree pull -P <name-of-folder> <git@github.com:my-user/new-repo.git> master
# 提交
git subtree push -P <name-of-folder> <git@github.com:my-user/new-repo.git> master
git subtree pull -P <name-of-folder> <git@github.com:my-user/new-repo.git> master
# 提交
git subtree push -P <name-of-folder> <git@github.com:my-user/new-repo.git> master
来执行相应的subtree操作
git subtree split分拆项目不完美,可能会丢失部分的分支和历史记录。可以用git filter-branch拆分项目。