如何获取包含子模块的Git存储库中所有文件的绝对路径?

问题描述 投票:0回答:2

我试图以递归方式列出所有子模块中所有未跟踪的文件:

git submodule foreach --recursive git ls-files --others --exclude-standard --full-name

但这并未列出绝对路径,它给出了子模块文件夹的相对路径。

我该如何修改我的命令?

git path git-submodules absolute-path git-ls-files
2个回答
1
投票

(注意:这是一个“工具”答案,而不是“解决方案”的答案。也就是说,这个答案旨在为您提供构建所需解决方案所需的工具。)

使用git rev-parse --show-toplevel获取当前存储库的绝对路径。当然,在超级项目中这样做。这为您提供了任何路径前缀的第一部分 - 但现在您将需要剩下的部分。

正如the git submodule documentation所说,在foreach中,你可以访问几个变量,包括$path

$path是相对于超级项目的子模块目录的名称...

什么不是很清楚(你必须自己测试)是$path在递归子模块的情况下是否累积。也就是说,如果超级项目A在路径top/subB下有子模块B,那么当你在子模块B中时,$path将是top/subB。但是假设子模块B充当子模块C的超级项目,B的自己的路径是contained/C$path在子模块C内部是top/subB/contained/C,还是只有contained/C?1

在任何情况下,一旦你有了合适的前缀,只需使用像sed这样的东西在前面加上它,例如:

git ls-files --others --exclude-standard --full-name | sed "s,^,$prefix,"

其中$prefix设置为适当的前缀,可能只是$path/。 (这假设你的文件名都没有包含嵌入的换行符;如果有的话,你的原始命令无论如何都会遇到麻烦。如上所述,它也假设你的前缀都没有包含逗号 - 如果有的话,使用,以外的字符,或者让$prefix用反斜杠引用逗号。)


1Logic建议它将是完整的路径;在不知道有多少子模块被递归的情况下,相对路径并不完全可用。但是,相对路径更容易生成。


0
投票

感谢torek的想法。这有效:

git submodule foreach --quiet 'a=$(printf "$(git ls-files --others --exclude-standard --full-name|sed "s~^~$(pwd)/~")"; printf x); a=${a%x}; echo "$a"' | sed '/^\s*$/d'
© www.soinside.com 2019 - 2024. All rights reserved.