git subtree

此文已由作者张磊授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

前言

目前对 git 仓库拆分的已有实现之一。这里 git subtree 并不是 subtree merge strategy,这两个不是一个东西。

准备工作

  1. 首先创建主仓库 subrepo-master,随意提交一次文本,接着拉取到本地
  2. 建立子仓库 subrepo,随意提交一次文本,同时准备多个分支进行任意提交备用。

操作

  1. 运行 git remote add subtree1 <url> 添加子仓库链接
  2. 添加子仓库 git subtree add --prefix=subtree/subtree1 subtree1 master,这里的 prefix 指向的是本地存放子仓库的目录, subtree1 是第一步添加的远端链接 ,master 是远端分支。添加完成后,就得到了第一个子仓库。
  3. 运行 git status 会发现没有本地修改,接着运行 git log,会发现多了一次提交信息,看起来 git subtree 在添加的时候会自动提交一次,现在可以选择把提交推送到远端。
     commit 6cd935426f68cd670d50a7fb02065af9a0cded19 Merge: fbc33ec afdc5bf     Add ‘subtree/subtree1/‘ from commit ‘afdc5bf559beacb08032e23d22a2beaa65d3ca9c‘
    
         git-subtree-dir: subtree/subtree1
         git-subtree-mainline: fbc33ec2739057789595c13d2313b87848bf25c0
         git-subtree-split: afdc5bf559beacb08032e23d22a2beaa65d3ca9c
  4. 接着会做一些操作,模拟各种情况,如主仓库子仓库修改推送、子仓库远端拉取合并等。
  5. 主仓库子仓库修改推送到远端

    首先对主仓库子仓库的文件做一些修改并本地提交(记住提交的 message),接着可以直接推送到远端。观察远端主仓库会发现修改顺利提交,subrepo 没有发生改变,这时候就可以体会出一点 subtree 的设计了。如果想推送子仓库,需要使用命令 git subtree push --prefix=subtree/subtree1 subtree1 master。再次观察远端,会发现修改被推送上去了,而且 message 一致。当然你可以选择不推送到 master 分支,随意找一个 git subtree push --prefix=subtree/subtree1 subtree1 master2 也是可以的。观察远端会发现多出一个 master2 分支。

  6. 远端子仓库有修改

    对远端子仓库修改。然后拉取此次提交合并到主仓库。运行此命令拉取即可 git subtree pull --prefix=subtree/subtree1 subtree1 master2,这时候如果有冲突,就需要解决冲突,分别推送主仓库子仓库。然后观察远端仓库,会发现主仓库、子仓库都有了提交以及解决冲突的操作。

  7. 远端子仓库做了大量提交

    希望从远端拉取合并到主仓库 git subtree pull --prefix=subtree/subtree1 subtree1 master2,再运行 git log 然后会发现主仓库的提交日志多了很多,是子仓库的提交日志 + 1 条,如果不希望子仓库污染主仓库的提交日志,可以使用 --squash 这个命令。git subtree pull --prefix=subtree/subtree1 subtree1 master2 --squash,就得到干净了日志了(一次是 squash 整理的提交,一次是合并),但是合并的时候有冲突需要解决。

  8. 本地子仓库合并远端子仓库 branch、tag、commitid

    如果分支没有在本地拉取,则需要先 git fetch subtree1,接着再

     git subtree merge --prefix=subtree/subtree1 subtree1/a
     // or
     git subtree merge --prefix=subtree/subtree1 v2.0
     // or
     git subtree merge --prefix=subtree/subtree1 e1e9aef94c0ce5ede4716d3c1e48cc58c15b7ffe
  9. 本地子仓库改变分支

    可以通过 git subtree pull --prefix=subtree/subtree1 subtree1 b 的方式,但是方式的缺点显而易见,需要手工再次合并代码等等。还有另一种方案,先删去目录,然后重新添加进来。

技巧

  1. 命令表

     git subtree add   -P <prefix> <commit>
     git subtree add   -P <prefix> <repository> <ref>
     git subtree pull  -P <prefix> <repository> <ref>
     git subtree push  -P <prefix> <repository> <ref>
     git subtree merge -P <prefix> <commit>
     git subtree split -P <prefix> [OPTIONS] [<commit>]
  2. 如果想要历史记录干净一点,可以使用 --squash,可用于 add, merge, push, pull 命令。但是加了 --squash 也有自己的问题,上面已做描述,这个最好一开始就统一使用一种。当然有人也有解决方案 https://stackoverflow.com/questions/9777564/git-subtree-pull-complications

缺点

  1. 合并策略的学习成本
  2. 返回历史版本稍显复杂
  3. 不要混合提交主仓库、子仓库代码
  4. 将子仓库推送到远端很慢,相当于对主仓库下某个子仓库的目录的提交记录进行分割,以找出子仓库的修改,这个过程有点慢,如果推送周期比较长倒是可以尝试。
  5. 需要添加多个远端,子仓库和远端没有地方存储映射关系。由命令 git subtree pull --prefix=subtree/subtree1 subtree1 master2 可以看出来,可以推送子仓库的代码到任意能推送的地方。
  6. 改子仓库的分支略坑

优点

  1. 拷贝主仓库后,可以直接使用
  2. 使用者可以不关注子树依赖,对使用者无感知,不需要子仓库权限
  3. 子树不像子模块会添加多余的文件,对仓库无污染
  4. 对子仓库的同步可交由单独的维护者

参考

  1. https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt
  2. https://developer.atlassian.com/blog/2015/05/the-power-of-git-subtree/
  3. https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree
  4. https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 聊聊空状态设计
【推荐】 大数据在政府中的应用案例

原文地址:https://www.cnblogs.com/163yun/p/9920852.html

时间: 2024-10-18 07:46:23

git subtree的相关文章

git subtree:无缝管理通用子项目

移动互联网的爆发以及响应式页面的尴尬症,开发web和mobile项目成为了标配,当然实际情况下,会有更多的项目. 多项目开发对于前端来说是个很大的挑战? 重复,重复的前端架构,重复的前端依赖,重复的工具函数等? 局限,不同后台有不同的规则,"因地制宜"真难受,刚伺候好rails又突然来个php? 最优,后台工程做前端构建,总是显得不够"最优". 所以,我们需要单独抽离出前端开发项目,按照前端的方式来组织代码,通过构建工具来对前端资源文件做最优处理那么新问题来了,如何

使用GIT SUBTREE集成项目到子目录(转)

原文:http://aoxuis.me/post/2013-08-06-git-subtree 使用场景 例如,在项目Game中有一个子目录AI.Game和AI分别是一个独立的git项目,可以分开维护.为了避免直接复制粘贴代码,我们希望Game中的AI子目录与AI的git项目关联,有3层意思: AI子目录使用AI的git项目来填充,内容保持一致. 当AI的git项目代码有更新,可以拉取更新到Game项目的AI子目录来. 反过来,当Game项目的AI子目录有变更,还可以推送这些变更到AI的git项

git subtree 使用

这个是备忘录.原网页(https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec , http://cncc.bingj.com/cache.aspx?q=master+git+subtree&d=5034897297048421&mkt=zh-CN&setlang=en-US&w=LLr-ePxnq8vxmyPDrHjzRWkbxVPwbcO4)被gfw墙,从cache中复制过来的,以备忘. Mas

Git subtree和Git submodule

git submodule允许其他的仓库指定以一个commit嵌入仓库的子目录. git subtree替代git submodule命令,合并子仓库到项目中的子目录.不用像submodule那样每次子项目修改了后要init和update.万一哪次没update就直接"commit -a" 或者 "add ." 全commit上去就悲剧了. git subtree虽然比git submodule更好用,但也不是特别完美的解决方案,使用时一定要特别注意. git-su

git subtree有效管理公共第三方lib

如果你的项目中有很多第三方的lib,你希望使用它,并且也希望可能对该lib做修改并且贡献到原始的项目中去,或者你的项目希望模块化,分为几个repo单独维护,那么git subtree就是一个选择. git subtree是附属于git的附加工具,默认情况下并不会安装.https://github.com/git/git/tree/master/contrib/subtree. # git clone https://github.com/git# cd git # make prefix=/us

[Git] 使用 Git SubTree 来共享函示库源代码

采用 GitSubtree 的方式来共用多个 project 会共用的 sourceCode,不过 subtree 的数据似乎不多,查到的数据都没有顺利的让我完成我的 subtree 情境,所以自己参考数据并且尝试成功后,就写一篇 blog 来记录一下,希望 subtree 以后会更方便用 写在前面的前面 (2017/05/06更新) 经过了大概几个月的使用,近日决定放弃用 Subtree 改回用 SubModule,因为遇到了一些问题,最严重的是两个使用同一个 Subtree 会莫名的不同步,

git subtree submodule

https://blog.csdn.net/weixin_33860737/article/details/88940185 https://blog.csdn.net/weiwei9363/article/details/88128730 https://blog.csdn.net/liusf1993/article/details/72765131 原文地址:https://www.cnblogs.com/little-ab/p/12163225.html

git submodule subtree常用指令

submodule 官方文档 添加 git submodule add -b master [email protected]:xxx/xxx.git src/xxx 删除 git submodule deinit -f src/xxx // 取消注册 git rm -rf src/xxx // git 工作树和索引中删除文件 rm -rf .git/modules/src/xxx subtree 带着提交记录来拷贝仓库的话就用subtree git subtree add --prefix=s

GIT 如何合并另一个远程Git仓库的文件到本地仓库里某个指定子文件夹并不丢失远程提交记录?

问题背景: 最近在重新整理手中的一个项目,目前该项目分为PC项目,手机项目,某第三方接口项目,第三方接口服务项目和手机项目 因为之前规划的原因,原来的四个项目是分两个解决方案来管理的 PC解决方案: #PC解决方案,2015年从Vss迁移到Git 一共三个项目 #F:\WWW\F.COM\WWW Flight.sln Flight.suo Web #PC项目 Qr #第三方接口项目 2015年新增项目,也使用PC解决方案但用分支进行管理,维护单独的通用项目,目前已经将通用项目分离到单独的分支进行