子模块

参考:7.11 Git 工具 - 子模块

开发个人网站的过程中需要用到主题仓库,所以会在一个仓库的里面嵌套另一个仓库,如果直接将子仓库加入版本管理,很多文件无法进行版本化,所以想到了子模块的操作

创建子模块

使用git submodule命令添加子模块

$ git submodule add git@github.com:zjZSTU/hexo-theme-next.git blogs/themes/next
Cloning into 'blogs/themes/next'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 5402 (delta 0), reused 0 (delta 0), pack-reused 5401
Receiving objects: 100% (5402/5402), 5.29 MiB | 1.03 MiB/s, done.
Resolving deltas: 100% (3294/3294), done.
Checking connectivity... done.

除了添加子仓库之外,还生成了一个配置文件.gitmodules

$ git status 
On branch dev
Your branch is ahead of 'origin/dev' 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:   blogs/themes/next

.gitmodules里面保存了子模块的地址和远程仓库链接

$ cat .gitmodules 
[submodule "blogs/themes/next"]
    path = blogs/themes/next
    url = git@github.com:zjZSTU/hexo-theme-next.git

管理子模块

主仓库只能提示子模块中的文件修改,必须子模块自己进行添加和上传

比如在next文件夹内新建文件hellogit

# 对于主模块而言
$ git status 
On branch dev
Your branch is up-to-date with 'origin/dev'.
Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
    (commit or discard the untracked or modified content in submodules)

    modified:   next (untracked content)

no changes added to commit (use "git add" and/or "git commit -a")
# 对于子模块而言
$ git status 
HEAD detached at 0c5ed6f
Untracked files:
    (use "git add <file>..." to include in what will be committed)

    hellogit

nothing added to commit but untracked files present (use "git add" to track)

克隆子模块

克隆主仓库后子模块的文件夹在但是没有文件,还需要进一步克隆子仓库

# 初始化本地配置文件
$ git submodule init
# 拉取远程仓库
$ git submodule update

集成代码如下:

$ git submodule update --init --recursive

更新子模块

如果子模块有更新,可以进入子模块路径进行更新

$ git pull

或者在主仓库更新所有子模块

$ git submodule foreach git pull

可能会遇到如下错误:

Entering 'blogs/themes/next'
You are not currently on a branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
    git pull <remote> <branch>
Stopping at 'blogs/themes/next'; script returned non-zero status.
The command "git submodule foreach git pull" failed and exited with 1 during .

需要指定哪个分支,要么修改更新语句如下:

$ git submodule foreach git pull origin master

要么设置远程关联分支

$ git branch --set-upstream-to=origin/remote_branch  your_branch
# 或
git branch --set-upstream your_branch origin/remote_branch

忽略子模块

参考:submodule..ignore

当在子模块执行完成修改提交后,在主模块仍会显示子模块待提交

$ git status 
On branch dev
Your branch is up-to-date with 'origin/dev'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   blogs/themes/next (new commits)

需要修改.gitmoduleignore属性,用于定义何种情况下使用git status或者diff命令会显示子模块的修改状况

4个可选的属性值

  1. all:子模块永远不会被认为是已修改的(但是当它处于暂存阶段时仍旧会在状态和提交命令的输出中)
  2. dirty:子模块工作树上的所有改变都会被忽略,只考虑子模块的HEAD与其在父项目中记录的状态之间的差异
  3. untracked:仅仅子模块未追踪的文件会被忽略。对于已追踪文件的提交差异和修改会显示
  4. none:默认选项。不会忽略所有对于子模块的修改,会显示所有的对于提交差异以及对于已追踪或未追踪的文件修改

所以设置属性ignoreall就能忽略子模块变化

[submodule "blogs/themes/next"]
    path = blogs/themes/next
    url = https://github.com/zjZSTU/hexo-theme-next.git
    ignore = all