我一直在尝试弄清楚如何获取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),但我不确定如何使用这些变量来获得所需的结果。
2条答案
按热度按时间egdjgwm81#
Git 2.11+可以实现另一种方法(Q4 2016)
参见Brandon Williams (
mbrandonw
)的commit 75a6315、commit 07c01b9、commit e77aa33、commit 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
文档现在包括:递归调用存储库中每个子模块上的ls-files。
目前只支持--cached模式。
Git 2.13(Q2 2017)增加了
ls-files --recurse-submodules
的健壮性:参见commit 2cfe66a、commit 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-files
(man)从来没有被教导要遵守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
现在在其手册页中包括:[--配置环境==][]
mf98qq942#
请看一下
git submodule
文档,其中写道:foreach
在每个 checkout 的子模块中计算任意shell命令。该命令可以访问变量
$name
、$path
、$sha1
和$toplevel
:$name
是.gitmodules中相关子模块部分的名称,$path
是相对于超级项目的子模块目录的名称,$sha1
是超级项目中记录的提交,$toplevel
是超级项目顶层的绝对路径。根据上述信息,您可以执行以下操作:
在本例中,我们只是从子模块中的
git ls-files
获取输出,并使用sed
预先挂起$path
的值,该值是子模块相对于父项目顶层目录的路径。