cd mySubmodule
git checkout -b aNewBranch
# work
git add .
git commit -m "new commits"
git push -u origin aNewBranch
# record the new submodule state in the parent repo:
cd ..
git add mySubmodule
git commit -m "new state of mySubmodule"
git push
[submodule "bash/plugins/dircolors-solarized"]
path = bash/plugins/dircolors-solarized
url = https://github.com/seebi/dircolors-solarized.git
update = merge # <-- this is what you need to add
5条答案
按热度按时间eni9jsuy1#
子模块 * 总是 * 作为分离的HEAD checkout (参见“Why did git detach my head?“),因为父存储库的索引只包含SHA1作为special entryin its index,如Gary Fixler的answer所解释的。
即使您使用configure your submodule to follow a branch(或convert an existing submodule to follow a branch),
git submodule update --remote
也会检出该远程分支的最新SHA1,但结果 * 默认情况下 * 是一个分离的HEAD。只有在该命令(
git submodule update --remote (--merge/--rebase)
)中添加--merge
或--rebase
,才能获得非分离的HEAD,如Simba的answer所示:默认情况下为master
分支。如果你不那样更新(
git submodule update --remote (--merge/--rebase)
),那么你需要进入那个子模块,自己在那里做一个分支。如果你想为上述子模块做贡献(在其中进行新的提交),创建一个新的分支是个好主意。
Git 2.16(2018年第一季度)注意事项:“
git checkout --recursive
“可能会覆盖和回退碰巧在子模块储存库中检出的分支的历史,这可能是不希望的。在这种情况下,分离
HEAD
,但仍允许递归检出成功。参见commit 57f22bf(2017年7月28日)和Stefan Beller (
stefanbeller
)的commit 3ef2538(2017年7月24日)。(由Junio C Hamano --
gitster
--合并至commit 0b75572,2017年12月6日)递归子模块:从新状态中分离HEAD
当子模块位于分支上并且在其超级项目中运行递归 checkout 时,子模块的分支将更新为超级项目 checkout 的内容。
这在当前的Git模型中是非常出乎意料的,例如'
submodule update
'总是分离子模块HEAD。尽管有计划在未来不分离子模块HEADS,但当前的行为确实很糟糕,因为它不符合用户预期,并且没有检查提交丢失(只能通过reflog恢复)。
更新HEAD时,无条件地在子模块中分离HEAD。
jvidinwx2#
git目录的内容存储在简单的文本文件清单(即目录列表)中,称为“树”,如下所示,其中blob是文件的内容,而trees则是更多的树:
然而,如果bar是一个子模块,而不仅仅是一个目录,那么包含它的树将如下所示:
注意,bar不是一棵树,而是一个提交(在一个子模块中)。这些都是git在树/提交层存储的关于一个子模块的信息,所以它不知道提交发生在哪个分支上。事实上,存储分支名是行不通的,分支名是可以改变的。另外,如果你在仓库中 checkout 了一个旧的提交,并且需要回滚该子模块,分支应该移回到子模块中吗?这会将新分支位置之后的提交强制转换到未引用的区域中。
分支是供人类使用的,用来理解DAG,以及特定的思路在哪里。Git不在乎我们如何引用提交。它需要一个具体的位置,这样你就可以安全地移动包含的repo,并知道子模块总是会被 checkout 到它当时的位置。唯一的真相是哈希。
1mrurvl13#
对于Sourcetree的用户--你会看到同样的行为--克隆会给你一个分离状态的子模块,正如VonC提到的in his answer,如果你想为子模块做贡献,你需要执行一些额外的步骤。
除了从子模块SHA-1创建一个新的分支之外,在大多数情况下,你只需要 checkout 现有分支的头。除非子模块被配置为跟随一个特定的分支,否则这将是master。
您可以打开每个子模块并手动 checkout 其对应的分支,也可以创建一个自定义操作来为您执行此操作(递归!):
这将检查项目中的任何子模块,并 checkout 它们指向的分支(如果没有指定分支,则 checkout master)。这是递归的,因此任何包含子模块的子模块也将被处理。
正如我在an earlier post中所发现的,末尾的额外引号对是必需的。
jv4diomz4#
在
.gitmodule
中添加**branch
选项与子模块的分离行为完全无关**。在
git submodule --help
中,HEAD分离是git submodule update --remote
的默认行为。首先,不需要指定要跟踪的分支。
origin/master
是要跟踪的默认分支。--很少
使用子模块的远程跟踪分支的状态来更新子模块,而不是使用超级项目记录的SHA-1。使用的远程是分支的远程(
branch.<name>.remote
),默认为origin
。使用的远程分支默认为master
。为什么
那么为什么HEAD在
update
之后被分离呢?因为submodule.$name.update
的默认行为是checkout
。--结帐
checkout 子模块中detached HEAD上的超级项目中记录的提交。这是默认行为,此选项的主要用途是在设置为
checkout
以外的值时覆盖submodule.$name.update
。如何
如果希望子模块自动与远程分支合并,请使用
--merge
或--rebase
。--合并
此选项仅对update命令有效。将记录在超级项目中的提交合并到子模块的当前分支中。如果给定此选项,子模块的HEAD将不分离。
--重定基
将当前分支重定基到超项目中记录的提交上。如果提供了这个选项,子模块的HEAD将不被分离。
你只需要,
还有一个选项可以将
--merge
或--rebase
设置为git submodule update
的默认行为,方法是将submodule.$name.update
设置为merge
或rebase
。下面是一个关于如何在
.gitmodule
中配置子模块更新的默认更新行为的示例。我的整个答案是基于手册。
git submodule --help
。xt0899hw5#
遗憾的是,之前发布的答案没有一个对我有用,因此,我创建了一个简单的脚本:
这实际上检查出记录在超级项目中的子模块提交,而没有分离的头部。