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

时间:2018-09-05 11:01:42

标签: git path git-submodules absolute-path git-ls-files

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

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

但这并未列出绝对路径,而是提供了子模块文件夹的相对路径。

我应该如何修改命令?

2 个答案:

答案 0 :(得分: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。在子模块C中,$pathtop/subB/contained/C还是仅仅是contained/C 1

在任何情况下,一旦有了适当的前缀,只需使用诸如sed之类的前缀,例如:

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

其中$prefix设置为适当的前缀,可能只是$path/。 (这假定您的文件名都不包含嵌入的换行符;如果包含,则原始命令仍然有问题。按照书面说明,它还假定您的前缀均不包含逗号;如果包含,请使用{{ 1}},或使,用反斜杠引号。)


1 逻辑表明这将是完整的路径。如果不知道已经递归了多少个子模块,则相对路径不能完全使用。但是,相对路径更容易产生。

答案 1 :(得分: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'