当前位置:   article > 正文

git子模块简单了解_git 子模块push

git 子模块push

git子模块

背景

最近将博客部署在了github.io上,因为这新建了一个仓库专门放编译后的网页,导致我从vuepress编译后将编译后的文件夹上传到仓库比较麻烦,以前知道git的submodule,但是没有研究过,可以趁这个机会了解一下。

git submodule

根据官网,git submodule允许你将另外一个仓库B作为你自己仓库A的一个文件夹,实现模块化或者复用。
在我的场景下我希望将vuepress打包后的文件夹作为我部署github.io的仓库,这样我只需要build完在这个文件夹下面commit和push就可以了,而且不影响主仓库,这些有一个特性就是submodule下的commit是互不影响的。

try

这是我的主仓库文件夹tree

我希望将dist文件夹作为子模块

添加子模块

# 添加子模块,如果不指定路径,会看到其实类似于中执行了git clone,在当前目录下会有相当于仓库名的文件夹出现
git submodule add git@github.com:Ikarosx/ikarosx.github.io.git
# 进入目录查看
cd ikarosx.github.io
# remote -v查看远程仓库地址
# origin  git@github.com:Ikarosx/ikarosx.github.io.git (push)
git remote -v
# 可以看到该目录的仓库地址指向了github.io,确实添加成功

# .gitmodules文件,表明这个路径已经作为子模块添加进来了
[submodule "ikarosx.github.io"]
	path = ikarosx.github.io
	url = git@github.com:Ikarosx/ikarosx.github.io.git
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

删除子模块

# 因为前面没有指定路径,所以先删除
# (use --cached to keep the file, or -f to force removal)
# -f可以改成--cached,区别是否保留文件
git rm -r '.\ikarosx.github.io\' -f
# 删除.git/config && .git/modules文件下有关配置

# 重新添加指定路径的子模块,将路径放在结尾即可
git submodule add git@github.com:Ikarosx/ikarosx.github.io.git ./vuepress/dist

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

验证

子模块添加成功后,按我的想法就是编译后在子模块add/commit/push就可以看到效果

# deploy.sh
yarn run build
cd .vuepress/dist
git add .
git commit -m "deploy"
git push
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

但是后来我发现这样子行不通,原因是build后会先删除,类似执行了rm -rf的效果,导致子模块无法正常运行
所以新的想法是换一个目录,build后将文件复制到新目录上 (也可以从研究build不删除目录只删除文件入手)
此时期间遇到了一个报错

# 执行git submodule add git@github.com:Ikarosx/ikarosx.github.io.git ./deploy 报错
# 我在添加模块的时候,提示我已经将deploy文件夹配置了,问我是不是要复用原有的文件夹,还是强制clone
# 这个原因是我们删除的时候没有删除完全,需要在主仓库下.git/config && .git/modules文件下删除相关的配置
fatal: A git directory for 'deploy' is found locally with remote(s):
  origin        git@github.com:Ikarosx/ikarosx.github.io.git
If you want to reuse this local git directory instead of cloning again from
  git@github.com:Ikarosx/ikarosx.github.io.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

最后尝试

# 在已经有了子模块的基础上,尝试build后复制编译后的文件到子模块上
# 脚本如下
yarn run build
cp -Force -R .vuepress/dist ./deploy
cd ./deploy
git add .
git commit -m "deploy"
git push
# 查看github io效果,可以看到可以成功
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

可不可以不使用子模块而只是手动添加remote

为什么不能直接在文件夹下面remote add自己的子仓库呢?
如果我在一个文件夹下面手动remote add,然后当我在主仓库下add .的时候,git会提示我有嵌套的git仓库,让我使用submodule,或者删除

如何更新子模块的内容

这里需要先了解git是怎么处理子模块的
根据前面的操作,我们可以知道
当我在子模块里面修改了内容/commit以后,在主仓库里git status可以看到会将整个deploy标记为modified,而不是具体将其中的内容哪里修改了列出
因此如果我们想将子模块的变动同步给其他使用者,需要先在本地处理好模块的变动(可能是从远端拉取最新的子模块仓库的代码,也可能是你本地修改了),再将这个变动推送给远端

# git status
On branch v2
Your branch is up to date with 'origin/v2'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   deploy (new commits)

no changes added to commit (use "git add" and/or "git commit -a")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
实操一下

假设现在有AB在维护主仓库,C在维护子模块里的仓库
C今天更新了子模块的内容并add/commit/push之后
我们想要在主仓库里更新一下子模块的代码

# ------ A -------
# A首先进入主仓库,如何拉取子模块的代码呢
# 先拉取代码
git pull 
# 将子模块拉取最新的代码
git submodule update --remote
# 查看此时状态,可以看到子模块有了变动
git status
# A提交变动
git add . && git commit -m "xx" && git push
# ------ A -------

# ------ B -------
# 同事A已经更新了代码,此时同事B也想要拉取最新的代码
# 此时pull可以看到子模块有变动
# Updating 9ff31de..ecfc65b
# Fast-forward
#  deploy | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)
git pull
# 但是需要注意,git pull会把子模块的变更拉取到本地,但是不会实际更新,更新需要执行新的命令git submodule update
# 执行子模块更新, 
git submodule update
# Submodule path 'deploy': checked out 'd6993c5f64edca75dbdf3d21802f11b03357ff10'
# 可以看到update以后才实际会check out更新代码
# ------ B -------


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

这里需要解释一下git submodule update加不加–remote的区别
–remote指的是从远端拉取最新的代码
不加表示只依据pull拉取到的去更新

总结

submodule可以很好的使我们在一个repository内添加其他的repository,利用好这个特性可以更加规范,运维更加清楚,而我则是用来方便部署github.io,从需求出发。
但也相对的增加了复杂性,需要开发人员学习新的概念以及技能,可能会导致新的问题产生。

引用

  1. https://git-scm.com/book/en/v2/Git-Tools-Submodules
  2. https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/705072
推荐阅读
相关标签
  

闽ICP备14008679号