更新 - 正如 cmets 在这个答案的交流中所指出的,check-ignore 命令说它列出了被忽略的文件,但如果你的忽略规则包括异常(以! 开头的模式),即使文件未被忽略,匹配这些模式的文件也会被打印。虽然某些文档可以被解读为描述了这种行为,但同一文档的其他部分强烈暗示这不是预期的 - 所以我认为这是一个错误,但不管这样的解释如何,这就是软件的工作方式。
所以...如果您不使用! 模式,则以下内容将按广告宣传。如果您确实使用! 模式,那么您可以通过使用--verbose 输出和后处理来查看匹配模式是包含还是排除来解决此问题。
使用ls-files 获得您想要的确切行为可能并不像看起来那么容易。首先,您可能不是指-i,因为那会仅列出被忽略的文件...
但无论如何,一种不同的(更“一步”)方法是:
在您的find 命令中,您可以使用-exec 操作为与其他过滤器匹配的每个文件调用git check-ignore。
find "$(git rev-parse --show-toplevel)" <filters> -not -exec git check-ignore -q {} \; <actions>
这将正确解释所有来源的忽略规则。
默认情况下,这也意味着如果一个文件在索引中,它确实不显示为“排除”,即使它在.gitignore 中,这反映了如何忽略规则真正行为。
但是,如果您不想处理匹配忽略模式的文件,即使它们在索引中,因此不会被真正忽略,您可以修改命令来做到这一点:
find "$(git rev-parse --show-toplevel)" <filters> -not -exec git check-ignore -q --no-index {} \; <actions>
由于您从使用find 开始,我假设您无论如何只关心当前在您的工作树中的文件。
您可能还想排除.git 目录。如果.git 是您的顶级目录中唯一的“点文件”,您可以说
find "$(git rev-parse --show-toplevel)"/* <filters> -not -exec git check-ignore -q --no-index {} \; <actions>
如果你不能做出这样的假设,那么你可以
find "$(git rev-parse --show-toplevel)" -path "$(git rev-parse --show-toplevel)"/.git -prune -o <filters> -not -exec git check-ignore -q -no-index {} \; <actions>
由于对rev-parse 的两次调用,这有点难看。您可以在运行find 之前将rev-parse 结果捕获到环境变量中,但这可能会与您的“一步”偏好相冲突。另一种选择,如果您可以放心地忽略名为 .git
的
any 目录
find "$(git rev-parse --show-toplevel)" -path */.git -prune -o <filters> -not -exec git check-ignore -q -no-index {} \; <actions>