列出Git存储库中的子模块

tpg*_*114 215 git git-submodules

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

git submodule foreach命令可以回显子模块的名称,但只有在检出后才能使用,这在init步骤之后没有发生.链中有更多的步骤需要在签出之前发生,我不希望将子模块的名称硬连接到脚本中.

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

Ikk*_*kke 146

您可以使用与git submodule init使用本身相同的机制,即查看.gitmodules.此文件枚举每个子模块路径及其引用的URL.

例如,从存储库的根目录,cat .gitmodules将内容打印到屏幕(假设您有cat).

因为.gitmodule文件具有Git配置格式,所以您可以使用git config来解析这些文件:

git config --file .gitmodules --name-only --get-regexp path
Run Code Online (Sandbox Code Playgroud)

会显示所有子模块条目,并显示

git config --file .gitmodules --get-regexp path | awk '{ print $2 }'
Run Code Online (Sandbox Code Playgroud)

你只能获得子模块路径.

  • **警告:对于带空格的子模块,`awk`失败!**命令应该是**`git config -z --file .gitmodules --get-regexp'\.path $'| sed -nz的/ ^ [^ \n]*\n // p'| tr'\ 0''\n'`**(你需要一个带有`-z`的现代`sed`).对于其中包含Newlines的**路径**(它们可以使用`git mv`创建)失败.如果你想要安全抵御这些,请忘掉`| tr'\ 0''\n'`并使用类似`... |的东西 而IFS =''读-d''路径; 做...用bash进一步处理.这需要一个现代的bash,它理解`read -d''`(不要忘记`-d`和`''`之间的空格). (8认同)
  • @IgorGanapolsky - 你可以在控制台上打印,如果你在存储库根目录中执行`cat .gitmodules` ... (2认同)

Jon*_*ops 88

如果要显示嵌套的子模块,可以使用git submodule status或可选git submodule status --recursive.

来自GIT SCM文档:

显示子模块的状态.这将打印SHA-1的当前签出的承诺每个子模块,与子模块路径沿和git的输出描述为SHA-1.每个SHA-1将与前缀 - 如果子模块没有初始化,+如果当前已签出子模块承诺不符,SHA-1在含仓库和U如果子模块具有合并冲突的索引中找到.

  • 这绝对应该被标记为_best answer_,在没有任何bash帮助的情况下使用简单的本地`git`命令.并且这种解决方案在工作副本的任何一点都运行良好的方式是优雅的(当然,子模块本身,结果直接适用于它们自己). (6认同)
  • 只需运行git submodule update --init --recursive即可初始化所有子模块。 (2认同)
  • @IgorGanapolsky刚刚读了Stefaan的评论:如果尚未初始化子模块,这种命令将不起作用。无输出=无子模块(空列表)。 (2认同)

mho*_*815 58

要仅返回已注册子模块的名称,可以使用以下命令:

grep path .gitmodules | sed 's/.*= //'
Run Code Online (Sandbox Code Playgroud)

把它想象成git submodule --list不存在的东西.

  • 开机令人难忘! (6认同)
  • 请注意,这仅适用于存储库根目录. (3认同)
  • 相反,使用`perl -ne'/ ^\s*path =\s*(.*)/和push(@submods,$ 1); END {print(join("\n",sort(@submods)));}'"$(git rev-parse --show-toplevel)/.gitmodules"`与这个答案(1)相比,可以在任何地方使用子目录(虽然不在子模块中); (2)按名称对子模块进行排序; (3)忽略.gitmodules中的注释行. (3认同)
  • 请注意,这是一种非常草率的方法,因为子模块名称中可能存在“path”(“git submodule add https://github.com/commercialhaskell/path.git”)。但你之前可能已经知道了。如果您想从工作树中的任何位置访问“.gitconfig”或需要在“--bare”存储库中运行它,您可以使用“git cat-file -p HEAD:.gitmodules |”之类的东西。...`。如果需要引用“暂存”文件,可以执行`git cat-file -p :.gitmodules | ...`,但是这需要一个 git `index` 存在。 (2认同)

A.T*_*.T. 51

以下命令将列出子模块:

git submodule--helper list
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

<mode> <sha1> <stage> <location>
Run Code Online (Sandbox Code Playgroud)

注意:需要git 2.7.0或更高版本.

  • 伟大的!。这个命令记录在哪里。适用于 Windwos 的 Git,但在 https://git-scm.com/ 上找不到任何文档 (3认同)
  • `git ls-files --stage | git ls-files --stage | git ls-files --stage grep ^160000`(来自答案 /sf/answers/2052765361/)似乎产生相同的结果,所以如果您需要与旧版 git 兼容,也许这是一个很好的替代品。 (3认同)
  • 注意`submodule--helper`中的`--`双破折号 (2认同)
  • 这个不是递归的。 (2认同)

小智 22

我可以看到已经选择了答案,但对于到达此页面的任何其他人:

$ git submodule
Run Code Online (Sandbox Code Playgroud)

将列出指定git仓库中的所有子模块.

干杯

  • 这实际上是提到`git submodule [status]`的另外两个答案的重复答案(请注意,如果省略则表示`status`,所以这是相同的). (2认同)
  • 最佳答案 (•̀ ω•́ )✧ (2认同)
  • 请注意,如果您想使用 `--recursive` 标志,则必须显式添加 `status` 命令: `git submodule status --recursive` 有效,但 `git submodule --recursive` 无效。 (2认同)

Rob*_*ahl 16

我用这个:

git config --list|egrep ^submodule
Run Code Online (Sandbox Code Playgroud)

  • 如果子模块尚未初始化,则不起作用 (4认同)

Max*_*tor 16

我注意到在这个问题的答案中提供的命令给了我正在寻找的信息:

.gitmodule中没有为非子模块的路径找到子模块映射

git ls-files --stage | grep 160000
Run Code Online (Sandbox Code Playgroud)

  • 它正在使用裸存储库。与 .gitmodules 解决方案不同。 (2认同)

ben*_*sch 11

如果您不介意仅对初始化的子模块进行操作,则可以使用它git submodule foreach来避免文本解析.

git submodule foreach --quiet 'echo $name'
Run Code Online (Sandbox Code Playgroud)

  • 这个答案的独特之处在于它仅适用于已初始化的子模块。根据您的需要,这可能是期望的行为(但也可能是意外和不期望的。) (2认同)

Pol*_*lot 10

使用内置 git 函数显示有关每个子模块的所有信息:

git submodule foreach -q git config -l
Run Code Online (Sandbox Code Playgroud)

或者只是 URL-s:

git submodule foreach -q git config remote.origin.url
Run Code Online (Sandbox Code Playgroud)

这里偷来的。


Fab*_*lin 9

您可以使用:

git submodule | awk '{ print $2 }'
Run Code Online (Sandbox Code Playgroud)


Ska*_*rab 8

我用这个:

git submodule status | cut -d' ' -f3-4 
Run Code Online (Sandbox Code Playgroud)

输出(路径+版本):

tools/deploy_utils (0.2.4)
Run Code Online (Sandbox Code Playgroud)


小智 7

这对我有用:

git ls-files --stage | grep ^160000
Run Code Online (Sandbox Code Playgroud)

基于这篇伟大的文章:http://www.speirs.org/blog/2009/5/11/understanding-git-submodules.html

编辑:必读 grep ^160000

  • `git ls-files --stage | git ls-files --stage | git ls-files --stage grep ^160000` 似乎产生与答案 /sf/answers/2861416561/ 中的 `git submodule--helper list` 相同的输出 (3认同)

bGo*_*rle 7

要按名称列出所有子模块:

git submodule --quiet foreach --recursive 'echo $name'


Cai*_*ida 6

只是子模块的直接列表:

git submodule--helper list | cut -d$'\t' -f 2
Run Code Online (Sandbox Code Playgroud)


Ale*_*ray 5

只是子模块路径讨好,夫人...

git config --list | grep \^submodule | cut -f 2 -d .
Run Code Online (Sandbox Code Playgroud)
Vendor/BaseModel
Vendor/ObjectMatcher
Vendor/OrderedDictionary
Vendor/_ObjC
Vendor/XCodeHelpers
Run Code Online (Sandbox Code Playgroud)

  • 尽管这可能是该问题的完全有效答案,但以下是一些警告:仅适用于名称中不包含点的子模块。点名在模块名称中完全有效。它不限于`.url`键,因此也可能会显示其他条目(通常没有,但是会发生)。您应该在此处使用“ --local”,因为您不想看到“ --global”和“ --system”设置。最后要注意的是,由于它可能会被忽略,因此它仅适用于.git / config中已经存在的子模块(例如在git submodule init之后,请参见问题)。 (4认同)

Von*_*onC 5

git config允许指定配置文件。
并且.gitmodules 一个配置文件。

因此,借助“ 使用cut命令将空间用作定界符 ”:

git config --file=.gitmodules --get-regexp ^^submodule.*\.path$ | cut -d " " -f 2
Run Code Online (Sandbox Code Playgroud)

那只会列出路径,每个声明的子模块一个。

正如蒂诺在评论中指出的那样:

  • 对于其中有空格的子模块,此操作将失败。
  • 子模块路径可能包含换行符,如

    git submodule add https://github.com/hilbix/bashy.git "sub module"
      git mv 'sub module' $'sub\nmodule'
    
    Run Code Online (Sandbox Code Playgroud)

作为更可靠的选择,Tino建议:

git config -z --file .gitmodules --get-regexp '\.path$' | \
  sed -nz 's/^[^\n]*\n//p' | \
  tr '\0' '\n' 
Run Code Online (Sandbox Code Playgroud)

对于其中包含换行符的路径(可以使用创建git mv),请不要| tr '\0' '\n'使用,并使用类似的方式... | while IFS='' read -d '' path; do ...对bash进行进一步处理。
这需要现代的bash能够理解read -d ''(不要忘记之间的空格-d and '')。