首页 > 解决方案 > Git:列出子目录中根目录的过滤路径

问题描述

git diff可以列出两个修订版之间的所有文件差异:

$ git diff --name-only master
foo.txt
bar/bar.txt
bar/baz.qux

它接受<path>一个 glob 模式形式的可选过滤器,该过滤器命名要包含的路径:

$ git diff --name-only master -- '*.txt'
foo.txt
bar/bar.txt

<path>相对于工作目录:

$ cd bar/
$ git diff --name-only master --    '*.txt' # no output
$ git diff --name-only master -- '../*.txt'
foo.txt
bar/bar.txt

有没有办法调用git diff来达到效果

$ cd bar/
$ git diff --name-only master | grep '\.txt$'
foo.txt
bar/bar.txt

不依赖外部工具?<path>带有前缀的A/似乎不起作用。

标签: git

解决方案


的参数git diff是 Git 所说的pathspec,它在gitglossary中定义。这是(相当长的)描述中的一个片段:

以冒号开头的路径规范:具有特殊含义。在简短的形式中,前导冒号:后跟零个或多个“魔术签名”字母(可选地以另一个冒号结尾:),其余部分是与路径匹配的模式。“魔术签名”由既不是字母数字、glob、正则表达式特殊字符也不是冒号的 ASCII 符号组成。如果模式以不属于“魔术签名”符号集且不是冒号的字符开头,则可以省略终止“魔术签名”的可选冒号。

在长格式中,前导冒号:后跟一个左括号(,一个逗号分隔的零个或多个“魔术词”列表,以及一个右括号),其余部分是匹配路径的模式。...

最佳

    魔术字top(魔术签名:)/使模式从工作树的根开始匹配,即使您从子目录中运行命令也是如此。

因此我们可以使用:(top)or :/:。这是与您的示例相同的设置:

$ git diff --name-only
bar/bar.txt
bar/baz.qux
foo.txt

(这些都是修改过的)

$ cd bar
$ git diff --name-only
bar/bar.txt
bar/baz.qux
foo.txt

(当没有路径规范时,所有仍然列出,即使在子目录中)

$ git diff --name-only -- '*.txt'
bar/bar.txt

(由于位于子目录和路径规范中,仅列出了一个)。现在我们使用路径说明符:

$ git diff --name-only -- ':(top)*.txt'
bar/bar.txt
foo.txt
$ git diff --name-only -- ':/:*.txt'
bar/bar.txt
foo.txt

:(top):/:作为前缀列出所有内容)

其余单词请参见文档,它们是相当强大的工具。


推荐阅读