tldr;如何确定我当前的工作目录在子模块目录中?
如果在子模块内部或外部进行工作,则工作过程有所不同。一次又一次,我感到困惑,因为我不知道自己在子模块中。
最佳__git_ps1
会告诉我我在子模块中,但是显然它没有任何规定。
我想修补__git_ps1
以向我展示我在子模块中的事实,但是我找不到一种优雅的方式来查询git以了解该事实。
理想情况下,我希望具有这样的shell函数:
function current_working_directory_is_in_a_submodule() {
if some_magic; then
echo "( $submodule_name )"
else
false
fi
}
some_magic
是什么?
可能您可以查看.git
目录。如果它实际上是not目录,则可以确定您在子模块中。至少在最新版本的git中,.git
条目实际上是一个看起来像以下文件的文件:
gitdir: ../../../.git/modules/path/to/submodule
取决于子模块的添加方式,它可能仍然具有.git
目录。可以在父存储库中运行git submodule absorbgitdirs
命令来解决此问题;从git submodule
手册页:
如果子模块的git目录位于子模块内部,请将子模块的git目录移至其超级项目$ GIT_DIR / modules路径,然后通过设置core.worktree并添加.git来连接git目录及其工作目录指向嵌入在superprojects git目录中的git目录的文件。
被独立克隆并随后添加为子模块或旧设置的存储库在子模块内部具有子模块git目录,而不是嵌入到superprojects git目录中。
此命令默认是递归的。
...但是这仍然是有问题的,因为虽然在子模块的根目录中测试很容易,但是在深度嵌套的目录中则更困难(因为这样一来,您就必须迭代搜索父目录直到找到.git
目录或到达/
)。
我在上面引用的手册页条目为我们提供了另一个更好的选择:
在子模块中,设置了core.worktree
值(设置为从子模块的根到其自身的相对路径)。这意味着您可以(a)检查core.worktree
设置是否具有确定您是否在子模块中的值,以及(b)您可以使用core.worktree
的值确定子模块名称。这使我们得到类似的东西:
function current_working_directory_is_in_a_submodule() {
submodule=$(git config core.worktree)
if [ "$?" -eq 0 ]; then
echo "( ${submodule##*/} )"
else
false
fi
}
我不知道是否还有其他情况会自动设置core.worktree
,但这在我有限的测试中似乎可行。
git rev-parse --show-superproject-working-tree
如果任何项目未将当前存储库用作子模块,则不输出任何内容。
[submodule-ness只是一个问题,如何使用存储库,当前结帐是否是其他结帐所认为的。
您可以看到工作树是否在另一个认为应该在此处结帐的工作树中:
git rev-parse --show-superproject-working-tree