markdown,git等辅助工具iOS Developer程序员

Git Subtree的使用

2017-03-05  本文已影响3053人  Archerlly

背景

项目A与项目B存在公用模块,在项目A中修改Bug或增加新功能需要同步到项目B中,由于存在区别所以还不能完全copy

需求分析


双向同步的栗子:A项目中依赖了子项目B,最方便的方式自然是直接在A项目里改B子项目对应的目录里的代码,然后测试通过后,直接提交代码,这个更改也提交到B子项目的 Git仓库里。同时子项目B也可以单独提交到 Git 仓库,再在A项目里把子项目B的代码update。

现有方案


虽然 npm,composer,maven 等更侧重于包的依赖管理,以上几个方案都是能够做到在不同项目中同步同一块代码的,但没法双向同步,更适用于子项目代码比较稳定的情形。Git Submodule 和 Git Subtree 都是官方支持的功能,不具有依赖管理的功能,但能满足我们的要求。Git Subtree相对来说会更好一些 。

submodule 与 subtree对比

实施步骤


假设P1项目、P2项目共用S项目
1. 关联Subtree
'' cd P1项目的路径
'' git subtree add --prefix=<S项目的相对路径> <S项目git地址> <分支> --squash

解释:--squash意思是把subtree的改动合并成一次commit,这样就不用拉取子项目完整的历史记录。--prefix之后的=等号也可以用空格。

2. 更新代码
P1、P2项目里各种提交commit,其中有些commit会涉及到S目录的更改,但是没关系

3. 提交更改到子项目
'' cd P1项目的路径
'' git subtree push --prefix=<S项目的相对路径> <S项目git地址> <分支>
Git 会遍历步骤2中所有的commit,从中找出针对S目录的更改,然后把这些更改记录提交到S项目的Git服务器上,并保留步骤2中的相关S的提交记录到S仓库中

4. 更新子目录
''cd P2项目的路径
''git subtree pull --prefix=<S项目的相对路径> <S项目git地址> <分支> --squash

拆分已有项目


需要从现有项目中抽取公共模块单独进行git管理
假设已有项目P抽取项目S
1. 提交日志分离
''cd P项目的路径
''git subtree split -P <S项目的相对路径> -b <临时branch>
Git 会遍历所有的commit,分离出与S项目的相对路径相关的commit,并存入临时branch中

2. 创建子repo
''mkdir <S项目新路径>
''cd S项目新路径
''git init
''git pull <P项目的路径> <临时branch>
''git remote add origin <S项目的git仓库>
''git push origin -u master

3. 清理数据
''cd P项目的路径
''git rm -rf <S项目的相对路径>
''git commit -m '移除相应模块' # 提交删除申请
''git branch -D <临时branch> # 删除临时分支

4. 添加subtree
''git subtree add --prefix=<S项目的相对路径> <S项目git地址> <分支> --squash
''git push origin master
执行完第2步时,对应的目录已经剥离出来形成独立的项目了。第3,4步主要是把当前项目的对应的文件给删除,重新在P项目建立Subtree

Tips

参考

上一篇下一篇

猜你喜欢

热点阅读