繁体   English   中英

列出当前 git 分支历史记录中任意位置的子目录中的文件

[英]List the files in a sub-directory present at any point in the current git branch's history

要在特定提交中列出子目录中存在的所有文件,我可以签出该提交并查看文件。 有没有办法列出在任何时候(即在当前提交的祖先中的任何提交中)存在于子目录中的所有文件?

是: git ls-tree接受所谓的“tree-ish”和可选路径(如果未指定,则默认为存储库根目录)。

树形是可以解析为树的任何东西——一个 object,它将有关单个“目录”的信息存储在记录的提交中。

提交总是指精确的单个树 object,而树 object 可能引用零个或多个其他树对象 - 表示“子目录”。

因此,提交始终是一个空洞的“树状”。

TL;博士

要获取/foo/bar前缀下的文件列表,三个提交回调调用

git ls-tree HEAD~2 foo/bar

更新以反映对原始问题的澄清

但我想要所有提交中的文件,即 HEAD、HEAD~、HEAD~2、HEAD~3、HEAD~4,…… 回到整个历史记录。 也许我的问题不清楚?

可以使用一点 shell 脚本来滚动:

git rev-list HEAD | while read sha; do
  git ls-tree -r "$sha" prefix/of/interest;
done

…它基本上遍历从HEAD可访问的 DAG 中的所有提交,并为每个提交调用git ls-tree并带有提交的名称和感兴趣的前缀(目录名称)。

请注意,如果特定提交中不存在前缀树 object ,则git ls-tree以非零退出代码退出,因此如果要在set -e下运行此代码,则应确认并补偿.

这种方法可能会以许多有趣的方式进行升级。
例如,可能不只是获取文件列表或调用诸如git show --name-status $sha之类的东西。

Ionică Bizău 对另一个问题的回答(“如何使用 git 日志仅获取带有路径的文件名?”)给了我一些可以使用的东西。 这似乎可以在导致当前 state 的所有提交中获取/foo/bar目录下曾经存在的所有文件:

git log --name-status -- /foo/bar | grep -E '^[A-Z]\b' | sed -e 's/^\w\t*\ *//' | sort | uniq
  • git log --name-status给出了所有提交中更改的所有文件的名称和状态( 文档)。
  • -- /foo/bar将日志限制到感兴趣的目录(这里
  • | bash 管道( 文档
  • grep -E '^[AZ]\b'获取以 ( ^ ) 大写字母 ( [AZ] ) 后跟分词符 ( \b ) 开头的行,即以 M、D、A、.. 开头的行..( grep 文档差异过滤器文档
  • sed -e 's/^\w\t*\ *//'s/regexp/replacement/上运行 stream 编辑器/ 在这种情况下^\w\t*\ *查找以 ( ^ ) 开头的带有单词 ( \w )后跟零个或多个制表符( \t* ),然后是零个或多个空格( \ * )并将这些匹配项替换为空字符串( sed 文档
  • sort文档
  • uniq ( 文档)

(注意此解决方案不包括添加到工作树或阶段但尚未提交的文件,因此请先添加并提交。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM