我有一个Git存储库,里面有几个子模块。如何在git submodule init
运行后列出所有子模块的名称?
git submodule foreach
命令可以回显子模块的名称,但只有在检出后才能使用,这在init步骤之后没有发生。链中有更多的步骤需要在签出之前发生,我不希望将子模块的名称硬连接到脚本中。
那么是否有一个Git命令来获取所有当前已注册但尚未检出的子模块的名称?
答案 0 :(得分:126)
您可以使用与git submodule init
使用相同的机制,即查看.gitmodules
。此文件枚举每个子模块路径及其引用的URL。
例如,从存储库的根目录,cat .gitmodules
会将内容打印到屏幕上(假设您有cat
)。
因为.gitmodule文件具有Git配置格式,所以您可以使用git config来解析这些文件:
git config --file .gitmodules --name-only --get-regexp path
将显示所有子模块条目,并显示
git config --file .gitmodules --get-regexp path | awk '{ print $2 }'
你只能获得子模块路径。
答案 1 :(得分:73)
如果要显示嵌套的子模块,可以使用git submodule status
或可选git submodule status --recursive
。
来自GIT SCM文档:
显示子模块的状态。这将打印出的SHA-1 目前检查每个子模块的提交,以及 子模块路径和用于SHA-1的git描述输出。每 如果子模块未初始化,则SHA-1将以 - 为前缀 如果当前检出的子模块提交与SHA-1不匹配 在包含存储库的索引中找到,如果是子模块,则找到U. 合并冲突。
答案 2 :(得分:58)
要仅返回已注册子模块的名称,可以使用以下命令:
grep path .gitmodules | sed 's/.*= //'
将其视为不存在的git submodule --list
。
答案 3 :(得分:47)
以下命令将列出子模块:
<?php
$html = file_get_contents('test.html');
$dom = new DOMDocument;
@$dom->loadHTML($html);
//Some code needs to go here!
$tags = $dom->getElementsByTagName('strong');
?>
输出是这样的:
git submodule--helper list
注意:需要git 2.7.0或更高版本。
答案 4 :(得分:18)
我可以看到已经选择了答案,但对于到达此页面的任何其他人:
$ git submodule
将列出指定git仓库中的所有子模块。
干杯
答案 5 :(得分:16)
我用这个:
git config --list|egrep ^submodule
答案 6 :(得分:16)
我注意到在这个问题的答案中提供的命令给了我正在寻找的信息:
No submodule mapping found in .gitmodule for a path that's not a submodule
git ls-files --stage | grep 160000
答案 7 :(得分:9)
您可以使用:
git submodule | awk '{ print $2 }'
答案 8 :(得分:9)
如果您不介意只对初始化的子模块进行操作,则可以使用git submodule foreach
来避免文本解析。
git submodule foreach --quiet 'echo $name'
答案 9 :(得分:8)
我用这个:
git submodule status | cut -d' ' -f3-4
输出(路径+版本):
tools/deploy_utils (0.2.4)
答案 10 :(得分:7)
这对我有用:
git ls-files --stage | grep ^160000
基于这篇伟大的文章:http://www.speirs.org/blog/2009/5/11/understanding-git-submodules.html
编辑:必须阅读grep ^160000
答案 11 :(得分:7)
按名称列出所有子模块:
git submodule --quiet foreach --recursive 'echo $name'
答案 12 :(得分:5)
子模块路径请,马上...
git config --list | grep \^submodule | cut -f 2 -d .
Vendor/BaseModel Vendor/ObjectMatcher Vendor/OrderedDictionary Vendor/_ObjC Vendor/XCodeHelpers
答案 13 :(得分:5)
git config
允许指定配置文件
.gitmodules
是配置文件。
所以,在&#34; use space as a delimiter with cut command&#34;:
的帮助下git config --file=.gitmodules --get-regexp ^^submodule.*\.path$ | cut -d " " -f 2
这将仅列出路径,每个声明的子模块一个。
由于Tino指出in the comments:
- 对于包含空格的子模块,此操作失败。
子模块路径可能包含换行符,如
git submodule add https://github.com/hilbix/bashy.git "sub module" git mv 'sub module' $'sub\nmodule'
作为一个更强大的替代方案,蒂诺建议:
git config -z --file .gitmodules --get-regexp '\.path$' | \ sed -nz 's/^[^\n]*\n//p' | \ tr '\0' '\n'
对于包含换行符的路径(可以使用
git mv
创建),请不要使用| tr '\0' '\n'
并使用类似... | while IFS='' read -d '' path; do ...
的内容进行进一步处理bash。
这需要一个理解read -d ''
的现代bash(不要忘记-d and ''
之间的空格。)
答案 14 :(得分:2)
使用内置的 git 函数显示每个子模块的所有信息:
#[derive(Eq, PartialEq, Debug)]
struct StructA {
f: StructB
}
#[derive(Eq, PartialEq, Debug)]
struct StructB {
g: i32
}
impl From<i32> for StructB {
fn from(v: i32) -> Self {
Self {
g: v
}
}
}
impl<T> From<T> for StructA
where
T: Into<StructB>
{
fn from(t: T) -> StructA {
let structb = t.into();
StructA {
f: structb
}
}
}
fn main() {
let a1: StructA = StructB { g: 12 }.into();
let a2: StructA = 12.into();
assert_eq!(a1, a2);
}
或者只是 URL-s:
git submodule foreach -q git config -l
从here窃取。
答案 15 :(得分:1)
在我的git
[1] 版本中,每个git子模块都有一个name
和一个path
。它们不一定必须是相同的 [2] 。以可靠的方式获取这两者,而无需先检出子模块(git update --init
),这是Shell向导中的棘手问题。
names
的列表我找不到使用git config
或任何其他git
命令来实现此目标的方法。因此,我们回到.gitmodules
上的正则表达式(非常难看)。但这似乎有点安全,因为git
限制了子模块names
允许的代码空间。另外,由于您可能希望将此列表用于进一步的Shell处理,因此下面的解决方案将NULL
字节(\0
)字节的条目分开。
$ sed -nre \
's/^\[submodule \"(.*)\"]$/\1\x0/p' \
"$(git rev-parse --show-toplevel)/.gitmodules" \
| tr -d '\n' \
| xargs -0 -n1 printf "%b\0"
在您的脚本中:
#!/usr/bin/env bash
while IFS= read -rd '' submodule_name; do
echo submodule name: "${submodule_name}"
done < <(
sed -nre \
's/^\[submodule \"(.*)\"]$/\1\x0/p' \
"$(git rev-parse --show-toplevel)/.gitmodules" \
| tr -d '\n' \
| xargs -0 -n1 printf "%b\0"
)
注意:read -rd ''
需要bash
,并且不能与sh
paths
的列表在我的方法中,我尝试不用git config --get-regexp
,awk
,tr
等来处理sed
的输出,但是...将零字节传回git config --get
。这是为了避免子模块paths
中的换行符,空格和其他特殊字符(例如unicode)出现问题。另外,由于您可能希望将此列表用于进一步的Shell处理,因此下面的解决方案将NULL
字节(\0
)字节的条目分开。
$ git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
| xargs -0 -n1 git config --null --file .gitmodules --get
例如,在bash
脚本中,您可以:
#!/usr/bin/env bash
while IFS= read -rd '' submodule_path; do
echo submodule path: "${submodule_path}"
done < <(
git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
| xargs -0 -n1 git config --null --file .gitmodules --get
)
注意:read -rd ''
需要bash
,并且不能与sh
git
版本$ git --version
git version 2.22.0
name
和path
发散了设置测试库:
$ git init test-name-path
$ cd test-name-path/
$ git checkout -b master
$ git commit --allow-empty -m 'test'
$ git submodule add ./ submodule-name
Cloning into '/tmp/test-name-path/submodule-name'...
done.
$ ls
submodule-name
$ cat .gitmodules
[submodule "submodule-name"]
path = submodule-name
url = ./
移动子模块以使name
和path
分叉:
$ git mv submodule-name/ submodule-path
$ ls
submodule-path
$ cat .gitmodules
[submodule "submodule-name"]
path = submodule-path
url = ./
$ git config --file .gitmodules --get-regexp '\.path$'
submodule.submodule-name.path submodule-path
设置测试库:
$ git init test
$ cd test/
$ git checkout -b master
$ git commit --allow-empty -m 'test'
$
$ git submodule add ./ simplename
Cloning into '/tmp/test/simplename'...
done.
$
$ git submodule add ./ 'name with spaces'
Cloning into '/tmp/test/name with spaces'...
done.
$
$ git submodule add ./ 'future-name-with-newlines'
Cloning into '/tmp/test/future-name-with-newlines'...
done.
$ git mv future-name-with-newlines/ 'name
> with
> newlines'
$
$ git submodule add ./ 'name-with-unicode-?'
Cloning into '/tmp/test/name-with-unicode-?'...
done.
$
$ git submodule add ./ sub/folder/submodule
Cloning into '/tmp/test/sub/folder/submodule'...
done.
$
$ git submodule add ./ name.with.dots
Cloning into '/tmp/test/name.with.dots'...
done.
$
$ git submodule add ./ 'name"with"double"quotes'
Cloning into '/tmp/test/name"with"double"quotes'...
done.
$
$ git submodule add ./ "name'with'single'quotes"
Cloning into '/tmp/test/name'with'single'quotes''...
done.
$ git submodule add ./ 'name]with[brackets'
Cloning into '/tmp/test/name]with[brackets'...
done.
$ git submodule add ./ 'name-with-.path'
Cloning into '/tmp/test/name-with-.path'...
done.
.gitmodules
:
[submodule "simplename"]
path = simplename
url = ./
[submodule "name with spaces"]
path = name with spaces
url = ./
[submodule "future-name-with-newlines"]
path = name\nwith\nnewlines
url = ./
[submodule "name-with-unicode-?"]
path = name-with-unicode-?
url = ./
[submodule "sub/folder/submodule"]
path = sub/folder/submodule
url = ./
[submodule "name.with.dots"]
path = name.with.dots
url = ./
[submodule "name\"with\"double\"quotes"]
path = name\"with\"double\"quotes
url = ./
[submodule "name'with'single'quotes"]
path = name'with'single'quotes
url = ./
[submodule "name]with[brackets"]
path = name]with[brackets
url = ./
[submodule "name-with-.path"]
path = name-with-.path
url = ./
names
的列表$ sed -nre \
's/^\[submodule \"(.*)\"]$/\1\x0/p' \
"$(git rev-parse --show-toplevel)/.gitmodules" \
| tr -d '\n' \
| xargs -0 -n1 printf "%b\0" \
| xargs -0 -n1 echo submodule name:
submodule name: simplename
submodule name: name with spaces
submodule name: future-name-with-newlines
submodule name: name-with-unicode-?
submodule name: sub/folder/submodule
submodule name: name.with.dots
submodule name: name"with"double"quotes
submodule name: name'with'single'quotes
submodule name: name]with[brackets
submodule name: name-with-.path
paths
的列表$ git config --null --file .gitmodules --name-only --get-regexp '\.path$' \
| xargs -0 -n1 git config --null --file .gitmodules --get \
| xargs -0 -n1 echo submodule path:
submodule path: simplename
submodule path: name with spaces
submodule path: name
with
newlines
submodule path: name-with-unicode-?
submodule path: sub/folder/submodule
submodule path: name.with.dots
submodule path: name"with"double"quotes
submodule path: name'with'single'quotes
submodule path: name]with[brackets
submodule path: name-with-.path
答案 16 :(得分:0)
如果没有.gitmodules,但.git / modules /
中存在子模块配置interface Global {
document: Document;
window: Window;
navigator: Navigator;
}
答案 17 :(得分:0)
这是从.gitmodules解析git子模块名称的另一种方法,而无需sed或精美的IFS设置。 :-)
#!/bin/env bash
function stripStartAndEndQuotes {
temp="${1%\"}"
temp="${temp#\"}"
echo "$temp"
}
function getSubmoduleNames {
line=$1
len=${#line} # get line length
stripStartAndEndQuotes "${line::len-1}" # remove last character
}
while read line; do
getSubmoduleNames "$line"
done < <(cat .gitmodules | grep "\[submodule.*\]" | cut -d ' ' -f 2-)
答案 18 :(得分:0)
获取路径
grep url .gitmodules | sed 's/.*= //'
要像回购中那样获取名称
grep path .gitmodules | sed 's/.*= //'