代码之家  ›  专栏  ›  技术社区  ›  Mike Samuel

从shell脚本中,如何筛选出与.gitignore匹配的文件?

  •  0
  • Mike Samuel  · 技术社区  · 8 年前

    我正在维护一些git预提交挂钩,我一直想为所有受或应该受修订控制的文件做点什么。 了解项目结构可以让我做得很好,但是关于构建系统输出目录、测试日志文件和编辑器拖放的所有信息都已经在 .gitignore .

    是否有一种简单的方法根据文件路径是否匹配 吉蒂格诺 .

    听着,我能替代什么 WHAT GOES HERE 在里面

    find "$(git rev-parse --show-toplevel)" --my --filters | WHAT GOES HERE
    

    这样我就只得到所有与我的过滤器匹配的未被gitignored的文件。

    我想我可以用一个阴性的过滤器 comm 通过做

    ... | xargs git ls-files -X .gitignore -i
    

    但我只希望有一步。

    1 回复  |  直到 8 年前
        1
  •  2
  •   Mark Adelsberger    7 年前

    更新 -正如在就这一答复交换意见时指出的那样, check-ignore 命令 它列出了被忽略的文件,但是如果忽略规则包含异常(以 ! ),也会打印与这些模式匹配的文件,即使该文件未被忽略。虽然有些文档可以理解为描述了这种行为,但同一文档的其他部分强烈地暗示,这并不是我们想要的——所以我认为这是一个bug,但不管这些解释如何,都是软件的工作方式。

    所以…如果你不使用 ! 模式,下面的工作广告。如果你 使用 ! 模式,然后您可以使用 --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>
    

    自从你开始使用 找到 ,我假设您在任何情况下都只关心当前工作树中的文件。

    您可能还希望排除 .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 . 你可以抓住 反向解析 运行前将结果转换为环境变量 找到 ,但这可能与你的“一步”偏好相冲突。另一个选择,如果你可以安全地忽略 任何 名为的目录 Git

    find "$(git rev-parse --show-toplevel)" -path */.git -prune -o <filters> -not -exec git check-ignore -q -no-index {} \; <actions>
    
    推荐文章