我想find
在我的项目目录中查找,但我只想查找由 Git 跟踪的文件。是否有一个命令可以用作输出过滤器find
(或任何其他方式)来将结果限制为仅 Git 正在跟踪的文件?
例子:
find . -name '*.postinst' | git-no-untracked
上面的我有什么用git-no-untracked
?
答案1
如果zsh
可以选择切换到,您可以获得以下列表跟踪文件在数组中:
tracked_files=(${(0)"$(git ls-files -z)"})
然后对您感兴趣的文件列表进行交集,例如:
postinst_files=(**/*.postinst)
tracked_postinst_files=(${postinst_files:*tracked_files})
您可以使用 zsh glob 完成大部分可以使用find
.例如,如果您只需要最近 2 小时内最后修改的常规文件:
postinst_files=(**/*.postinst(.mh-2))
或者您可以直接在跟踪文件列表中搜索您的模式:
tracked_postinst_files=(${(M)tracked_files:#*.postinst})
或者定义一个 glob 限定符函数来检查文件是否在跟踪文件列表中:
istracked() ((${tracked_files[(Ie)${1-$REPLY}]}))
tracked_postinst_files=(**/*.postinst(+istracked))
答案2
按照使用提示git ls-files
,我创建了一个简短的脚本来运行命令并使用 过滤其输出comm
。微妙之处在于comm
需要排序的输入,并且行必须是精确的文本匹配(因此没有诸如./
典型find
命令可能产生的前缀)。
#!/bin/bash
set -eu
usage()
{
cat <<EOF
Usage:
$0 cmd [args... ]
Runs _cmd_ (with arguments, if provided) and filter the output to
files currently tracked by Git.
Example:
$0 find . -name README -mmin -60
EOF
}
trap 'usage >&2' ERR
case "${1:-}" in
-h|--help|'-?')
usage
exit 0
;;
'')
usage >&2
exit 1
;;
esac
exec comm -12 \
<("$@" | xargs -d '\n' -n 1 realpath -s --relative-to=. | sort) \
<(git ls-files | sort)
答案3
这个如何 :
find . -name '*.postinst' | xargs -I something bash -c 'git ls-files | grep $(basename something)'