【问题标题】:Exclude a directory from git diff从 git diff 中排除目录
【发布时间】:2010-12-07 19:51:25
【问题描述】:

我想知道如何从我的 Git 差异中排除整个目录。 (在这种情况下 /spec)。我正在使用 git diff 命令为我们的整个软件版本创建一个差异。然而,对规范的更改与此过程无关,只会让人头疼。现在我知道我能做到

git diff previous_release..current_release app/

这将为 app 目录中的所有更改创建一个差异,但不是例如在 lib/ 目录中。有谁知道如何完成这项任务?谢谢!

编辑:我只想说清楚,我知道我可以在最后将所有目录的参数串起来,减去 /spec。我希望有一种方法可以真正排除命令中的单个目录。

【问题讨论】:

  • 我发现了这个惊人的问题,因为我的目标是忽略 子模块。在这种情况下,如果你和我一样天真,this question 会更有帮助。
  • 奇怪的是,我们在 2016 年 9 月仍然没有本地 Git 开关来执行此操作

标签: git


【解决方案1】:

基于this answer你也可以使用:

git diff previous_release..current_release -- . ':!spec'

这是一个新的 git 功能,允许排除某些路径。它应该比各种shell oneliners更可靠。

我在这里发布这个问题是因为这个问题仍然是“git diff exclude path”的第一名。

从 Git 2.13(2017 年第二季度)开始,您可以将 ! 替换为 ^。后者不需要引号。所以你可以写成:

git diff previous_release..current_release -- . :^spec

【讨论】:

  • 喜欢这个答案。如果添加选项,则在双破折号之前执行此操作。例如:git diff previous_release current_release --name-status -- . ':!spec'
  • 没有意识到我可以为 current_releaseprevious_release 使用分支名称 - 当我弄清楚时让我笑了。
  • 什么对我有用git diff --stat dev -- . ':!/Mopy/Docs/*'没有对我有用git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')' 和变体
  • 也可以像这样排除多个项目:git diff previous_release current_release -- . ':!file_a' ':!file_b'
  • 手册页是gitglossary
【解决方案2】:

假设您使用 bash,并且您启用了扩展通配符 (shopt -s extglob),您可以从 shell 端处理它:

git diff previous_release current_release !(spec)

让您不必列出所有其他内容。

或者,与外壳无关:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

您可以将其封装在一个单行 shell 脚本中,这样您就不必重新输入参数。

【讨论】:

  • P.S. globbing 不匹配隐藏文件,所以如果你很着迷,你可能想要添加 .!(.|) 以匹配除 ... 之外的以 . 开头的所有内容。
  • 这似乎不适用于全新或跨分支删除的文件。我收到停止执行脚本的错误,说它无法与它进行比较。
  • @Graham:我相信我刚刚添加的-- 应该可以解决这个问题。
  • 很棒的答案。我只想显示名称(不是实际的差异),所以我还必须在最后添加 --name-only
  • 玩过之后,只想补充一点,如果你更改文件名,它会抛出一个错误,但你需要做的就是添加-- path/of/new/file,它会解决的: )
【解决方案3】:

如果您想在 git diff 中指定多个要排除的路径,您只需在末尾添加额外的排除参数,例如从统计信息中排除 vendorbin 目录中的所有内容:-

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'

【讨论】:

    【解决方案4】:

    您可以尝试取消设置 lib 目录中任何文件的 diff 属性。
    .gitattributes:

    lib/* -diff
    

    racl101 添加in the comments

    再补充一点,对于那些想要在特定目录及其子目录中限制特定类型文件的 git diff 输出的人,就像 Webpack 捆绑您的 .js 生成的所有 JavaScript 一样文件,例如,您可以将其添加到.gitattributes

    dist/js/**/*.js -diff
    

    然后您在 git diff 输出中看不到所有噪音,它只显示为:Binary files ... differ,这更有帮助。

    【讨论】:

    • 这会从我所有的差异中删除规范。我仍然想在规范文件夹中正常查看我的差异,而不是在我运行这个“发布”差异时
    • @Mystr:您可以将 .gitattributes 文件设置在仅用于这种“发布”差异的特殊分支中;) 将该特殊分支重新设置在 current_release 之上,然后从在那里。
    • 这似乎也不适用于跨分支删除的文件。被删除的文件仍然显示完整的差异。
    • 对我不起作用。 _ 路径是特殊的吗? _site/* -diff
    • @MariusAndreiana 不,'_' 并不特殊。您能否检查哪个 gitattributes 规则适用于该文件夹的文件:git-scm.com/docs/git-check-attr
    【解决方案5】:

    Git diff 现在接受自定义排除格式:git diff -- ':(exclude)lib/*'

    如果您有很多重复的文件夹名称(“/app”、“/lib”等),请小心,因为这将排除与当前工作目录和 git 根目录相关的文件。

    【讨论】:

    • 你是不是少了一个点,不应该是git diff -- . ':(exclude)lib/*'吗?
    • @NicolasDermine 不,虽然你写的是等价的。路径的“包含”部分也是可选的。这就是为什么您可以为与当前路径相关的所有内容执行 git diff,而不需要 git diff -- .
    • 注意:在windows机器上,使用双引号,如git diff -- ":(exclude)lib/*"
    • 不知道为什么,但对我来说,它只适用于点,正如@NicolasDermine 所建议的那样。我在win10上使用Cmder。
    • 当要排除的文件夹不是 diff 根文件夹的直接子文件夹时,我也必须在它前面加上 */。前任。 git diff -- . ":!*/lib/*" 使用 !(exclude) 的简写
    【解决方案6】:

    相对于git根目录

    git diff 接受可选的排除

    git diff -- ":(exclude)thingToExclude"
    

    您可能想要添加一些通配符

    git diff -- ":(exclude)*/thingToExclude/*"
    

    针对特定文件类型

    git diff -- ":(exclude)*/$1/*.png"
    

    应用了一些语法糖

    git diff -- ":!/\$1/"
    

    或者为您的点文件添加一个小脚本

    .bash_profile.zshrc

    gde() {
        : '
            git diff exclude files or folders
            usage:
            gde fileOrFolderNameToExclude
        '
        git diff -- ":!/\$1/"
    }
    

    【讨论】:

      【解决方案7】:
      git diff app lib
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-04
        • 2020-02-15
        • 1970-01-01
        相关资源
        最近更新 更多