如何在git ls-files列出的所有文件上运行命令?

5
我们有一个 CI 脚本,用于对仓库中所有 Python 文件进行样式检查,代码如下:
#!/usr/bin/env bash
find . -name \*.py -exec pep8 --ignore=E402 --max-line-length=120 {} +
if [ $? -ne 0 ]; then
    >&2 echo "=== PEP8 errors need to be solved ==="
else
    echo "=== PEP8 check ok ==="
fi
pytest

然而,有一些东西没有被检查进去,或者被.gitignore忽略了。所以我想要取出git ls-files的输出,并且只在那些文件上运行命令。我可以循环,但是我不想对开发者选择的shell做出假设。理想情况下,我希望通过git ls-files的集合差异来过滤find的输出。


使用管道符号将 git ls-files 的输出传递给 xargs foo 命令。 - sideshowbarker
pep8 工具可以在命令行上接受目录名称,并支持 --exclude--filename 选项来提供包含和排除的模式。在许多情况下,这已足以选择要检查的文件。 - Sven Marnach
3个回答

10
#!/usr/bin/env bash
git ls-files -z \*.py | xargs -0 pep8 --ignore=E402 --max-line-length=120
if [ $? -ne 0 ]; then
    >&2 echo "=== PEP8 errors need to be solved ==="
else
    echo "=== PEP8 check ok ==="
fi
pytest

应该这样做。

git ls-files -zxargs -0 允许在文件名中包含空格等字符。

来自于 xargs 的说明

-0, --null
输入项以 null 字符而不是空格终止,引号和反斜杠不是特殊字符(每个字符都按字面意义解释)。禁用结束文件字符串,它像任何其他参数一样处理。当输入项可能包含空格、引号或反斜杠时,这个选项非常有用。GNU find 命令的 -print0 选项可生成适合此模式的输入。

来自于 git ls-files 的说明

-z
输出以 \0 作为行终止符。


0

如果你只想要特定的文件扩展名

我很惊讶,因为我的代码行数非常多,结果发现是因为 .png 文件和其他不太重要的文件。

如果你只想要特定的扩展名(在我的情况下是 dart、py 和 c),请使用以下脚本以方便你的操作

git ls-files | grep -e "\.\(dart\|py\|c\)$" | xargs wc -l

所以基本上,如果例如Java是您的主要扩展文件(/触发所有Java讨厌者和爱好者),则将Java放入转义序列中:

git ls-files | grep -e "\.\(java\)$" | xargs wc -l

(复制/粘贴并替换java为您当前的主文件扩展名)

然后添加:

\|file_extension

在第一个扩展名后(在这种情况下,在Java的'a'后),您需要为每个随后要分析的文件扩展名添加代码。

0
在一个存储库中以文件后缀(扩展名)运行命令的简单方法是:
git ls-files -z '*.py' | xargs -0 pep8 --ignore=E402 --max-line-length=120

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接