第9章:邪恶的submodule
基础知识
在worktree内部创建新的repo/worktree是坏的,因为一个文件受两个repo管辖。 一个workaround是将这个小的repo/worktree变成大repo的一个submodule。
一个submodule的信息可以分为静态与动态两大部分,总共分散在5个位置:
.gitmodules文件中包含一部分静态信息:submodule (name):名字
path:应该放在worktree的哪个路径里面
url:在哪里能够找到包含该commit的repo
branch:没有什么卵用
update:如何处理下级repo的更改
index中包含另一部分静态信息:
commit:上级repo期待哪个commit
.git/config文件中包含一部分动态信息:submodule (name)
active:启用/禁用
url
update
.git/modules/<name>/是下级repo,包含一部分动态信息<path>是下级repo的worktree,包含一部分动态信息
添加/更新submodule的静态部分(.gitmodules/index)
.gitmodules/index)非常简单,直接修改.gitmodules和index:
Lv1
Lv2
非常遗憾的是,没有Lv3的方法能够做到这一点。
用.gitmodules来更新.git/config
.gitmodules来更新.git/configLv2
Lv3
用.git/config和index来更新repo和worktree
.git/config和index来更新repo和worktreegit submodule update是实现这个功能的Lv3命令。 其基本语法是 git submodule update [--checkout|--rebase|--merge] -- <path> 若未指定那三个选项,其功能根据git config submodule.<name>.update而定,共有5种:
checkout(此为默认情况)
rebase
merge
none
!...
下面将分别介绍。
git submodule update --checkout == git clone
git submodule update --checkout == git cloneLv2
由于其中有git fetch,巨量无关数据一并被下载了下来。
Lv3
这里面依然有git fetch。 为了解决这个问题,可以使用git-get:
Lv5: git-get
git submodule update --checkout [-f] == git switch [-f] <commit>
git submodule update --checkout [-f] == git switch [-f] <commit>假设index发生了变动:
Lv2
Lv3
git submodule update --rebase == git rebase <commit>
git submodule update --rebase == git rebase <commit>(先回到原来的HEAD位置)
假设repo中HEAD发生了变动:
然后index又发生了变动:
现在希望能够把下级repo中新的改动rebase到e973上:
Lv2
Lv3
git submodule update --merge == git merge <commit>
git submodule update --merge == git merge <commit>(先回到原来的HEAD位置)
假设repo中HEAD发生了变动:
然后index又发生了变动:
现在希望能够在下级repo中merge上级以为的新的改动:
Lv2
Lv3
其他两种git config submodule.<name>.update
git config submodule.<name>.update用.gitmodules和index来创建repo和worktree
.gitmodules和index来创建repo和worktree分两步:用.gitmodules来更新.git/config;再用.git/config和index来更新repo和worktree。 Lv2不再赘述。
Lv3
用repo来更新index
(先回到原来的HEAD位置)
假设repo中HEAD发生了变动:
现在希望index也跟着变动:
Lv1
Lv2
Lv3
用.gitmodules来更新.git/config和repo的URL
.gitmodules来更新.git/config和repo的URLLv2
Lv3
一次性添加.gitmodules、.git/config、index、repo、worktree
.gitmodules、.git/config、index、repo、worktreeLv2
先添加.gitmodules和index,然后用.gitmodules更新.git/config, 然后用.git/config和index创建repo和worktree。
Lv3
注意:只能指定一个branch,不能指定某个commit。 包括git fetch,可能造成大量资源浪费。
删除.git/config和worktree
.git/config和worktreeLv2
Lv3
删除.gitmodules和index
.gitmodules和indexLv2
Lv3
非常遗憾的是,repo必须手工rm -rf。
由repo和worktree创建.gitmodules和index
.gitmodules和index假设如此创建repo和worktree:
现在欲将parent/whatever/path纳入parent当成submodule管理。
Lv2
Lv3
总结
一次性添加submodule的五个部分:
git submodule add [-b <branch>] [--name <name>] -- <url> <path>
分别修改submodule的五个部分:
.gitmodulesLv0:
vim .gitmodulesLv2:
git config --file=.gitmodules submodule.<name>.<key> <value>
$GIT_DIR/configLv0:
vim .git/configLv2:
git config submodule.<name>.<key> <value>
index
Lv2:
git update-index [--add|--force-remove] --cacheinfo 160000,<sha1>,<path>
repo (
$GIT_DIR/modules/<name>)git -C <path> ...
worktree (
$GIT_WORK_TREE/<path>)git -C <path> ...
用静态更新动态:
git submodule init -- <path>用
.gitmodules来更新.git/config
git submodule update --init [--recursive] --checkout -- <path>用
.gitmodules和index来创建repo和worktree
git submodule sync -- <path>用
.gitmodules来更新.git/config和repo的URL
git gets -- <path>快速下载指定commit
用静态和动态更新动态:
git submodule update [--recursive] [--checkout|--rebase|--merge] -- <path>用
.git/config和index来更新repo和worktree,共5种选项
用动态更新静态:
git update-index -- <path>- 用repo来更新indexgit add <path>- 用repo来更新indexgit submodule absorbgitdirs -- <path>有repo、worktree、
.gitmodules和index之后,用该命令创建.git/config并将repo移动到正确位置
删除:
git submodule deinit -f -- <path>删除
.git/config和worktree
其他部分需要逐一删除
最后更新于
这有帮助吗?