赞
踩
最近将博客部署在了github.io上,因为这新建了一个仓库专门放编译后的网页,导致我从vuepress编译后将编译后的文件夹上传到仓库比较麻烦,以前知道git的submodule,但是没有研究过,可以趁这个机会了解一下。
根据官网,git submodule
允许你将另外一个仓库B作为你自己仓库A的一个文件夹,实现模块化或者复用。
在我的场景下我希望将vuepress打包后的文件夹作为我部署github.io的仓库,这样我只需要build完在这个文件夹下面commit和push就可以了,而且不影响主仓库,这些有一个特性就是submodule下的commit是互不影响的。
这是我的主仓库文件夹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
# 因为前面没有指定路径,所以先删除
# (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
子模块添加成功后,按我的想法就是编译后在子模块add/commit/push就可以看到效果
# deploy.sh
yarn run build
cd .vuepress/dist
git add .
git commit -m "deploy"
git push
但是后来我发现这样子行不通,原因是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.
# 在已经有了子模块的基础上,尝试build后复制编译后的文件到子模块上
# 脚本如下
yarn run build
cp -Force -R .vuepress/dist ./deploy
cd ./deploy
git add .
git commit -m "deploy"
git push
# 查看github io效果,可以看到可以成功
为什么不能直接在文件夹下面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")
假设现在有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 -------
这里需要解释一下git submodule update
加不加–remote的区别
–remote指的是从远端拉取最新的代码
不加表示只依据pull拉取到的去更新
submodule可以很好的使我们在一个repository内添加其他的repository,利用好这个特性可以更加规范,运维更加清楚,而我则是用来方便部署github.io,从需求出发。
但也相对的增加了复杂性,需要开发人员学习新的概念以及技能,可能会导致新的问题产生。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。