blog icon indicating copy to clipboard operation
blog copied to clipboard

Git 子模块

Open Hancoson opened this issue 5 years ago • 0 comments

为什么要用子模块

痛点

在我们开发项目的时候可能会遇到下面这个问题:在你的项目中使用另外一个项目,也许这个是一个第三方开发的库或者是你独立开发和并在多个父项目中使用的。简单的说就是A同学开发的一个模块,被B、C…同学共同调用(使用),可能就形成了如下的这种关系。

模块调用关系

这个场景下一个常见的问题产生了:你想将两个项目单独处理但是又需要在其中一个中使用另外一个。

解决方案

这种问题,Git 已经帮我们有了处理方案——子模块。

  • 子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。 它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。
  • 子模块关键字:git submodule

如何使用子模块

假如目前我们有两个仓库,module(目标仓库)和 submodule(子模块仓库)。

在现有的仓库中加入子模块

git submodule add https://gitee.com/Hancoson/submodule.git submodule
  • 现在你就在项目 module 里的子目录下有了一个 submodule 项目。如果你在加入子模块后立刻运行 git status,你会看到下面两项:

    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
        new file:   .gitmodules
        new file:   submodule
    
  • 查看 .gitmodules 文件

    [submodule "submodule"]
      path = submodule
      url = https://gitee.com/Hancoson/submodule.git
    

如果你有多个子模块,这个文件里会有多个条目。很重要的一点是这个文件跟其他文件一样也是处于版本控制之下的,就像你的 .gitignore 文件一样。它跟项目里的其他文件一样可以被推送和拉取。这是其他克隆此项目的人获知子模块项目来源的途径。

  • 提交增加的子模块到现有仓库的远程仓库

commit 方式和普通提交的方式相同。然后,module 仓库是这样的: 仓库

修改子模块

  • 切换到要修改代码的子模块分支,修改对应代码,push(和普通仓库方式相同)

  • 拉取服务器代码,并且合并到本地 module (目标仓库分支)

    git submodule update --remote --merge
    
  • 修改目标仓库,推送

克隆一个带子模块的项目

这里你将克隆一个带子模块的项目。当你接收到这样一个项目,你将得到了包含子项目的目录,但里面没有文件,如下:

submodule 目录存在了,但是是空的。你必须到 module (目标仓库分支)根目录下运行两个命令:git submodule init 来初始化你的本地配置文件,git submodule update 来从那个项目拉取所有数据并检出你上层项目里所列的合适的提交:

$ git submodule init
Submodule 'submodule' (https://gitee.com/Hancoson/submodule.git) registered for path 'submodule'
$ git submodule update
Submodule path 'submodule': checked out '471741e958c2ef0096ad5971c264041a9295ce3b'

现在你的 submodule 子目录就处于你先前提交的确切状态了。每次你从主项目中拉取一个子模块的变更都必须这样做 git submodule update

后续

子模块使用过程还需要大家自己多练习一下,主要的命令 git submodule *.

Hancoson avatar Aug 14 '18 09:08 Hancoson