GIT:查找包含子模块的文件列表(例如使用git ls文件)

bvk5enib  于 2023-01-07  发布在  Git
关注(0)|答案(2)|浏览(118)

我一直在尝试弄清楚如何获取git repo中所有文件的列表,包括子模块中包含的文件。目前,git ls-files只提供子模块的顶层目录,而不提供子模块中包含的文件。经过进一步研究,我发现使用git submodule,你可以递归地找到所有子模块,然后使用git ls-files

git submodule --quiet foreach --recursive "git ls-files"

这样做的唯一问题是,结果是子模块的路径,但我需要repo的完整路径。
例如/some/path/to/gitrepo/源/子模块/[文件1,文件2]
我看到的是:

file1
file2

我希望看到的是:

source/submodule/file1
source/submodule/file2

有什么方法可以做到这一点吗?在文档中,有一些预定义的变量($name,$path,$sha1和$toplevel),但我不确定如何使用这些变量来获得所需的结果。

egdjgwm8

egdjgwm81#

Git 2.11+可以实现另一种方法(Q4 2016)

git ls-files --recurse-submodules

参见Brandon Williams ( mbrandonw )commit 75a6315commit 07c01b9commit e77aa33commit 74866d7(2016年10月7日)。
(由Junio C Hamano -- gitster --合并到commit 1c2b1f7,2016年10月26日)

ls-files:任选递归成子模块

"git ls-files"学习了"--recurse-submodules"选项,该选项可用于跨子模块获取跟踪文件列表(即,此选项仅适用于"--cached"选项,不适用于列出未跟踪或忽略的文件)。
这将是一个非常有用的工具,可以放在管道的上游端,使用xargs读取管道以处理顶级超级项目中的所有工作树文件。
如本测试所示,输出将包括文件的完整路径,从主要的父存储库开始。
git ls-files文档现在包括:

--recurse-submodules

递归调用存储库中每个子模块上的ls-files。
目前只支持--cached模式。
Git 2.13(Q2 2017)增加了ls-files --recurse-submodules的健壮性:
参见commit 2cfe66acommit 2e5d650(2017年4月13日)和Jacob Keller ( jacob-keller )
(由Junio C Hamano -- gitster --合并至commit 2d646e3,2017年4月24日)

ls-files:修复具有嵌套子模块的recurse-submodules

自提交e77aa33("ls文件:可选地递归到子模块",2016 - 10 - 07,git 2.11)ls-files已经知道如何在显示文件时递归到子模块。
不幸的是,这在某些情况下会失败,包括嵌套多个子模块、从本身具有子模块的子模块中调用,或者设置了GIT_DIR环境变量。
在提交b58a68c("setup:允许将前缀传递给git命令",2017 - 03 - 17,git 2.13-rc0)这会导致一个错误,指示--prefix--super-prefix不兼容。
相反,在提交之后,进程将永远循环,GIT_DIR设置为父模块,并不断读取父模块文件,永远递归。
通过在设置子进程时为子模块正确准备环境来解决此问题。这与其他命令(如grep)的行为类似。
正如Git 2.29(2020年第四季度)所指出的,配置submodule.recurse无法正常工作。
参见Philippe Blain ( phil-blain )commit 7d15fdb(2020年10月4日)。
(由Junio C Hamano -- gitster --合并至commit 9d19e17,2020年10月5日)

gitsubmodules doc:用"--recurse-submodules"调用"ls-files"

签署人:菲利普·布莱恩
git ls-filesman)从来没有被教导要遵守submodule.recurse配置变量,现在要改变已经太晚了,但是命令仍然在'gitsubmodules(7)'中提到,好像它确实遵守了那个配置。
通过使用"--recurse-submodules"选项调用"ls-files"来调整"gitsubmodules(7)"中的调用。
gitsubmodules现在在其手册页中包括:
git ls-files --recurse-submodules
【注】
git ls-files还需要其自己的--recurse-submodules标志。
也支持With Git 2.36 (Q2 2022)git ls-files --stage --recurse-submodule
在Git 2.40(2023年第一季度)中,停止使用git --super-prefix,并将其使用范围缩小到子模块--helper。
参见第一年第二十二次、第一年第二十三次、第一年第二十四次、第一年第二十五次、第一年第二十六次、第一年第二十七次、第一年第二十八次、第一年第二十九次(2022年12月20日)和第一年第三十次。
参见commit 0d1806e(2022年12月20日),作者:Glen Choo ( chooglen )
(由Junio C Hamano -- gitster --合并至commit d4c5400,2023年1月5日)

read-tree:添加"--super-prefix"选项,消除全局

签署人:埃瓦尔·阿恩菲约德·比亚尔马森
"git"的"--super-prefix"选项最初是在commit 74866d7中添加的("git:创建超级前缀选项",2016年10月7日,Git v2.11.0-rc0--merge列在batch #11中)用于:

  • 与"ls-files"(commit e77aa33)("ls-files:可选地递归到子模块",2016 - 10 - 07,Git v2.11.0-rc0--merge列在batch #11)),之后不久
  • "submodule--helper"(commit 89c8626("子模块助手:支持超级前缀",2016年12月8日,Git v2.12.0-rc0--merge列在batch #5中))和
  • "grep"(0281e48("grep:可选地递归到子模块",2016 - 12 - 16,Git v2.12.0-rc0--merge列于batch #6中)).

直到commit 3d41542("unpack-trees:支持超级前缀选项",2017年1月17日,Git v2.12.0-rc0--merge)," read-tree "使用了它。
在当时,这是有意义的,但从那时起,我们在commit 188dce1中使"ls-files"递归进程内("ls-files:使用存储库对象",2017年6月22日,Git v2.14.0-rc0--batch #14中列出的merge),commit f9ee2fc中列出的" grep "(" grep:使用'结构库'进行进程内递归",2017年8月2日,Git v2.15.0-rc0--batch #2中列出的merge),最后是前面提交中的" submodule--helper "。
我们还可以从"read-tree"中删除它,这样我们就可以删除"git"本身的选项。
我们可以这样做,因为它唯一剩下的用户是子模块API,它现在将使用其新的"--super-prefix"选项调用"read-tree"。
只有在调用"submodule_move_head()"函数时,它才会这样做。
该"submodule_move_head()"函数随后仅由"read-tree"本身调用,但是现在我们不设置环境变量以在cmd_read_tree()之间传递"--super-prefix",而是:- 在"结构unpack_trees_options""中设置一个新的"super_prefix"
git现在在其手册页中包括:
[--配置环境==][]

mf98qq94

mf98qq942#

请看一下git submodule文档,其中写道:
foreach
在每个 checkout 的子模块中计算任意shell命令。该命令可以访问变量$name$path$sha1$toplevel$name是.gitmodules中相关子模块部分的名称,$path是相对于超级项目的子模块目录的名称,$sha1是超级项目中记录的提交,$toplevel是超级项目顶层的绝对路径。
根据上述信息,您可以执行以下操作:

git submodule foreach 'git ls-files | sed "s|^|$path/|"'

在本例中,我们只是从子模块中的git ls-files获取输出,并使用sed预先挂起$path的值,该值是子模块相对于父项目顶层目录的路径。

相关问题