git submodule 的使用

项目中经常会使用到第三方的 git 库, 将三方库整合到项目中最简单的办法就是复制粘贴, 但是如果这个库升级了一个很酷炫的功能, 你要怎么整合进来呢?(其实就是 git 版的包管理器)

这就是本次要介绍的 git-submodule 操作, 直接把第三方的版本库合并到自己的库中.

添加第三方库

我这里是自己开了两个库做测试, 主库叫 body, 另一个库叫 leg

首先在本地的body库中添加leg

git clone https://git.oschina.net/gaofeifps/body.git
cd body
git submodule add https://git.oschina.net/gaofeifps/leg.git

这时查看下状态会多两个文件

➜  body git:(master) ✗ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

           new file:   .gitmodules
           new file:   leg

这就多了一个 leg的库, 和一个.gitmodules的文件, 现在提交一下

git commit -am "add leg"

在其他地方使用合并后的版本库

本地提交了版本之后可以提交到远程试一下

git push

这时去远程库中看的话库中的内容是这样的
[图片上传失败...(image-78d365-1555555272709)]

这里有个奇怪的 leg @ 6dec2fa, 明明是没有的啊?
点一下原来是一个快捷方式, 直接给连接到了 leg库的地址, 版本库中不会存第三方引入库的实体文件, 而是通过 .gitmodules的方式存储三方的联系方式, 当下载到本地运行的时候才会再拉取文件

而且这个时候在其他的地方安装body这个库的时候直接运行 git clone 是生成不了完整的文件的, 缺少了 leg库的文件
因为这个时候的 body/leg目录是空的需要多走一步, 这时为什么呢? 我们下面会讲到原因

git clone https://git.oschina.net/gaofeifps/body.git
git submodule init && git submodule update

#下面这一句的效果和上面三条命令的效果是一样的,多加了个参数  `--recursive`
git clone https://git.oschina.net/gaofeifps/body.git --recursive

这时才是一个完整的库

将三方库同步到主线

之前的一些步骤其实还不完整, 因为 body/leg 这个目录中的文件并没有和主线在一条线上, 这也是为什么在远程库的 leg 目录是空的, 因为在 master 分支里面它确实是空的, 文件是在另一个分支上, 我们先去看一下

cd path/to/body/leg
➜  leg git:(6dec2fa) git branch
* (HEAD detached at 6dec2fa)
  master

别的文件的分支都是 master 到这个文件的时候就是 6dec2fa分支了, 其实这个值也是 leg库当前的 commitId
而且如果不把第三方的库纳入自己的主线的话会非常的危险, 因为你对项目中的三方库发生的任何改动都不会对主线产生任何影响, 被主线遗忘了, 因此我们还需要接下来的操作

cd path/to/body/leg
git checkout master

更新第三方库

这里有个问题就是如果body/leg发生了更新就首先在这个文件中提交一个commit, 然后在body这个目录下再 commit一次
第一次 commit 是为了更新 leg的版本控制, 第二次更新是更新body的版本控制, 同时更新 leg库在body的指针

如果更新的比较多, 可以运行

批量更新第三方库

假设你的项目当中引入了 100 个第三方的库, 你需要同步的时候难道还要每一个都要执行:

cd module-dir/
git checkout master
git pull

是不是想起了小学被老师罚抄一百遍的恐惧当中了?
少年, 多看看文档准没错的, 这些东西 git 早就帮你想好了
具体操作可以看一下git help submodule有相关的介绍的
不想看文档的就直接告诉你

git submodule foreach <command>
比如:
git submodule foreach git checkout master

这条命令就会按照 .gitmodules会根据path寻找所有的三方模块, 并在每一个模块中都执行 foreach 后的命令,
比如你想批量更新模块到最新的时候就:

git submodule foreach git submodule update

画个重点 (敲黑板!)

如果像让你引入的第三方库leg符合你自己的定制, 你在里面发生了一些修改, 但是这些修改并不能提交到远程去, 因为你的提交会让第三方库的作者产生困扰: 我写的好好的一个轮子你给定制成这样, 还怎么去给其他的人用?

而且这个问题很严重, 如果你本地的legbody都更新了, 但是 第三方的leg不能提交到远程, 而body提交上去了, 那么与你同使用一个版本库的小伙伴就会因为当前项目leg的指针地址找不到而产生报错

所以如果有定制的需要就得去fork这个项目到你自己的 github 上, 然后自己想怎么折腾都随意了, 但是怎么去既有定制, 还能保持和轮子作者的版本同步呢?

怎么保持与作者同步?

首先是自己有一个 fork 的三方项目, 然后在自己本地添加一个三方的源

cd path/to/body/leg
➜  leg git:(master) git remote -v
origin     https://git.oschina.net/gaofeifps/leg.git (fetch)
origin     https://git.oschina.net/gaofeifps/leg.git (push)

#添加第三方包的源地址
➜  leg git:(master) git remote add dist_source https://git.oschina.net/xxxx/leg.git
➜  leg git:(master) git remote -v
dist_source        https://git.oschina.net/xxxx/leg.git (fetch) #这个是三方的源地址
dist_source        https://git.oschina.net/xxxx/leg.git (push)
origin     https://git.oschina.net/gaofeifps/leg.git (fetch)    #这个是你 fork 的项目地址
origin     https://git.oschina.net/gaofeifps/leg.git (push)

这样的话可以拉取源文件到本地并合并本地代码

git pull dist_source master

修复一下版本冲突的文件, 确认没有问题之后提交到自己 fork 的库中

git push origin master

这样其他人就能正常使用了

写了这么多忽然发现: 还是复制粘贴比较省事啊!

那么

怎么删除 submodule?

在当前 git 版本1.7.8之前, 删除指定的 submodule 的命令是

git rm <submodule-name>

在新版的 git 下, 则是运行以下命令

git submodule deinit <submodule-name>

查看本地有哪些三方模块可以查看 .gitmodules

➜  body git:(master) cat .gitmodules
[submodule "leg"]
           path = leg
           url = https://git.oschina.net/gaofeifps/leg.git

原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容

  • 是什么? submodule子模块,简单来讲就是Git仓库中的子仓库。 想一想是不是遇到过这样的情况,有一个模块是...
    长仙人阅读 6,187评论 0 7
  • 写在前面: 1、使用Git Submodule可能遇到的坑(http://blog.devtang.com/201...
    Funnyer阅读 5,747评论 0 0
  • 开发过程中,经常会有一些通用的部分希望抽取出来做成一个公共库来提供给别的工程来使用,而公共代码库的版本管理是个麻烦...
    橙娃阅读 506评论 0 0
  • 昨天在github上clone了DTCoreText这个工程,编译错误,缺少文件,后来发现是缺少了git subm...
    _健健阅读 939评论 0 51
  • 开发过程中,经常会有一些通用的部分希望抽取出来做成一个公共库来提供给别的工程来使用,而公共代码库的版本管理是个麻烦...
    龙在阿里阅读 590评论 0 0