And*_*Ray 20 git bash command-prompt git-submodules
有没有办法在git中知道你是否在子模块中?您可以git submodule foreach在父目录中进行思考,但是如果您在子模块中的任何子目录中,或者在子模块内的任何子目录中,我似乎无法想出一个通用的方法来显示您在子模块中.
我想你可以找到repo root git rev-parse --show-toplevel,然后cd一个级别,然后再次查找该repo的根,然后将子模块列表与当前目录进行比较,但这看起来很粘...
Von*_*onC 22
(2017年4月更新为Git 2.13,2017年第2季)
现在有一个官方命令来确定repo是否是父repo的子模块:
cd /path/to/potential/submodule/repo
git rev-parse --show-superproject-working-tree
Run Code Online (Sandbox Code Playgroud)
请参阅Stefan Beller的承诺bf0231c(2017年3月8日)(stefanbeller).
(由Junio C gitsterHamano合并- -在提交3edcc04,2017年3月17日)
rev-parse:添加--show-superproject-working-tree在某些情况下,了解给定的存储库是否是另一个存储库的子模块很有用.
添加标记
--show-superproject-working-tree以便git-rev-parse于查找是否存在超级项目.
如果不存在超级项目,则输出将为空.
获取超级项目路径,无论子模块内部/外部:
Run Code Online (Sandbox Code Playgroud)git rev-parse --show-superproject-working-tree --show-toplevel | head -1
(2014年更新)正如Quentin Pradet所指出的,更新的Git子模块repos显示的是一个简单的.git 文件而不是.git文件夹.
该.git文件引用存储在父 repo .git/modules子文件夹中的实际子模块git repo的路径.
(原答案:2011年9月)
子模块的本质是用于作为子模块的git repo不知道它被父repo用作子模块.
一个肮脏的伎俩是:
git status --ignore-submodules=none"如果在结果中看到该文件,则git status您的repo应该是子模块.
如果它只是一个嵌套的repo,那么git status应该完全忽略你的嵌套repo.
这是一个shell函数,您可以使用它来检测:
function is_submodule()
{
(cd "$(git rev-parse --show-toplevel)/.." &&
git rev-parse --is-inside-work-tree) | grep -q true
}
Run Code Online (Sandbox Code Playgroud)
编辑响应您提议的脚本:
看起来不错.
有一个错误
for line in $submodules; do cd "$parent_git/$line"; \
if [[ `pwd` = $_git_dir ]]; then return 0; fi; \
done
Run Code Online (Sandbox Code Playgroud)因为它不会回来(所以它只有在第一个子模块匹配时才有效).我的版本检查而不更改目录; 这可以通过cd在子shell中完成来完成,但是返回exitcode会变得那么复杂
我不知道你从哪里来$_git_dir- 我用basename(1)来获取这些信息(见下文).
子模块在名称中包含空格也存在问题.在我的版本中,子模块名称中的换行仍然存在问题,但我并不在意解决这个问题.(注意'惯用'方法避免while read在子shell中使用而不需要新的bash-isms之类的readarray)
最后声明所有vars本地修复了在其他脚本中使用它时的潜在问题(例如,当外部脚本使用$path变量时...)
我改名_git_dir为top_level(这不太混乱,因为GIT_DIR意味着别的东西)
我不知道git是否支持它(我不这么认为)但是如果子模块目录是一个符号链接,这个脚本可能会失败(因为"$ top_level/.."可能在包含的存储库之外解析)
具有换行符的子模块名称将无法正确识别
我还建议您捕获错误(使用'set -e','trap'返回1"ERR"或类似) - 不在我的脚本/练习中为读者
#!/bin/bash
function is_submodule() {
local top_level parent_git module_name path
# Find the root of this git repo, then check if its parent dir is also a repo
top_level="$(git rev-parse --show-toplevel)"
module_name="$(basename "$top_level")"
parent_git="$(cd "$top_level/.." && git rev-parse --show-toplevel 2> /dev/null)"
if [[ -n $parent_git ]]; then
# List all the submodule paths for the parent repo
while read path
do
if [[ "$path" != "$module_name" ]]; then continue; fi
if [[ -d "$top_level/../$path" ]]; then return 0; fi
done < <(cd $parent_git && git submodule --quiet foreach 'echo $path' 2> /dev/null)
#return 1
fi
return 1
}
Run Code Online (Sandbox Code Playgroud)
if is_submodule; then
echo "In a submodule!"
else
echo "Not in a submodule"
fi
Run Code Online (Sandbox Code Playgroud)
当且仅当从项目根调用时尝试git rev-parse --git-dir才会返回:".git"
if `git rev-parse --git-dir` == ".git"
// in root directory
else
// in submodule directory
Run Code Online (Sandbox Code Playgroud)
除非您设置了$GIT_DIR在这种情况下返回的值(请参阅rev-parse):
--git-dir
如果已定义,则显示 $GIT_DIR。否则显示 .git 目录的路径。显示的路径(相对路径)是相对于当前工作目录的。
如果未定义 $GIT_DIR 并且未检测到当前目录位于 Git 存储库或工作树中,则将消息打印到 stderr 并以非零状态退出。