我有一个Git存储库,其中有几个子模块。如何在git子模块init运行后列出所有子模块的名称?

git子模块foreach命令可以回显子模块的名称,但这只有在它们被签出后才有效,而在init步骤之后没有发生。在签出之前,链中还有更多的步骤需要执行,我不希望将子模块的名称硬连接到脚本中。

那么是否存在一个Git命令来获取所有当前已注册但尚未签出的子模块的名称?


当前回答

如果你不介意只对初始化的子模块进行操作,你可以使用git子模块foreach来避免文本解析。

git submodule foreach --quiet 'echo $name'

其他回答

下面的命令将列出子模块:

git submodule--helper list

输出如下所示:

<mode> <sha1> <stage> <location>

注意:需要Git 2.7.0或以上版本。

如果你想要显示嵌套的子模块,你可以使用git submodule status或者git submodule status——recursive。

从Git文档中:

显示子模块的状态。的SHA-1 的子模块的当前签出提交 子模块路径和git的输出为SHA-1描述。每一个 如果子模块未初始化,SHA-1将以-作为前缀,+ 如果当前检出的子模块提交不匹配SHA-1 在包含该子模块的存储库的索引中找到U 存在合并冲突。

如果你不介意只对初始化的子模块进行操作,你可以使用git子模块foreach来避免文本解析。

git submodule foreach --quiet 'echo $name'

获取路径

grep url .gitmodules | sed 's/.*= //'

在回购中得到名字

grep path .gitmodules | sed 's/.*= //'

Tino的评论显示了一个很好的替代方案:

git config --null --file .gitmodules --get-regexp "\.path\$" | \
sed -nz "s/^[^\\n]*\n//p" | \
xargs --null rm -v;

但是——null/-z选项不适用于BusyBox上的sed或xargs。然后,这是我能想到的最好的替代方案(xargs不会在空格上中断):

grep "^\s*path\s*=" .gitmodules | \
sed -e "s/.*=\s*\"*//" -e "s/\"*\s*\$//" | \
xargs -n 1 -I mark rm -v "mark";

但它有一个缺点,因为xargs调用时不带——null,而我们使用的是-I标记,它正在吞噬前导空白。要修复它,不要使用xargs并将名称写入文件:

grep "^\s*path\s*=" .gitmodules | \
sed -e "s/.*=\s*\"*//" -e "s/\"*\s*\$//" > tempfilefordanmxargsmotherbroked.txt;
while IFS= read -r line; do
   echo ".$line."
done <"tempfilefordanmxargsmotherbroked.txt"
rm "tempfilefordanmxargsmotherbroked.txt"

更正:BusyBox上的xargs没有删除前导空白,但完整版本可以。