Git:列出子目录中根目录的过滤路径

时间:2019-06-22 09:11:45

标签: git

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

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

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

$ 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>的{​​{1}}似乎无效。

3 个答案:

答案 0 :(得分:3)

git diff的参数是Git所说的 pathspec ,它在the gitglossary中定义。这是(相当长的)描述中的摘录:

  

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

     

在长格式中,前导冒号:后跟一个开放的括号(,一个逗号分隔的零个或多个“魔术词”列表和一个封闭的括号{{1} },其余为与路径匹配的模式。 ...

     

顶部

    魔术词)(魔术签名:top)使图案与作品的根部匹配树,即使从子目录内部运行命令也是如此。

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

:/:

(这些均已修改)

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

(当没有pathspec时,即使在子目录中,也仍然列出所有内容)

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

(仅列出了一个,因为它位于子目录和pathspec中)。现在我们使用pathspec指示符:

$ 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)作为前缀会列出所有内容)

有关剩余单词的信息,请参阅文档。

答案 1 :(得分:2)

可以说,一种选择是更改为the repository root,这可以在执行基本命令之前在子shell中安全地完成:

/

这没有引入 new 外部工具-外壳提供了子外壳和$ cd bar/ $ ( cd $(git rev-parse --show-toplevel) && git diff --name-only master -- '*.txt' ) foo.txt bar/bar.txt ,并且提供了Git-但从技术上讲,它不能满足 no < / em>外部工具。

答案 2 :(得分:2)

$ cd bar/
$ git diff --name-only master -- $(git rev-parse --show-cdup)/'*.txt'
foo.txt
bar/bar.txt

请参见https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---show-cdup