【问题标题】:Want to exclude file from "git diff"想要从“git diff”中排除文件
【发布时间】:2012-05-12 00:10:18
【问题描述】:

我正在尝试从 Git 差异中排除文件 (db/irrelevant.php)。我尝试将文件放在名为.gitattributesdb 子目录中,并带有irrelevant.php -diff 行 我还尝试创建一个名为.git/info/attributes 的文件,其中包含db/irrelevant.php

在所有情况下,db/irrelevant.php 文件都作为 Git 二进制补丁包含在 diff 中。我想要的是 diff 命令忽略对该文件的更改。我做错了什么?

【问题讨论】:

    标签: git diff git-diff


    【解决方案1】:

    您还可以使用patchutils 程序集合的filterdiff 程序来排除差异的某些部分。例如:

    git diff | filterdiff -p 1 -x db/irrelevant.php
    

    【讨论】:

    • 请注意,manpage(1) 中的 -p 是“-p n, --strip-match=n 匹配时,忽略路径名的前 n 个组件。”我花了一段时间才发现 -p 1 正在从 OP 的路径中删除 db 部分。如果您只想指定一个文件名并忽略所有可能的路径/目录,您可以使用-p 99
    【解决方案2】:

    您可以使用 no op 命令设置自定义差异驱动程序,并将其分配给那些应该被忽略的文件。

    使用此命令创建存储库特定的差异驱动程序

    git config diff.nodiff.command /bin/true
    

    或使用--global 为您的所有回购。

    (如果 /bin/true 在 MacOS 中不存在,则可以使用 /usr/bin/trueecho)。

    然后,将新的差异驱动程序分配给.git/info/attributes 文件中您希望忽略的那些文件

    irrelevant.php    diff=nodiff
    

    如果此状态应该与其他开发人员共享,您可以使用 .gitattributes 而不是 .git/info/attributes 并与您的同行共享 git config 命令(通过文档文件或其他方式)。

    【讨论】:

    • 这正是我想要的——正如kerneltrap.org/mailarchive/git/2008/10/17/3711254 中所述,我编辑了 ~/.gitconfig 添加:[diff "nodiff"] `command = /bin/true` 然后我创建了一个名为 .我添加的 git/info/attributes:irrelevant.php diff=nodiff
    • 这个答案对我来说效果更好:stackoverflow.com/questions/1016798/…
    • 有趣的是,这种方法不适用于git diff --stat。在这种情况下,可以使用git diff ... | diffstat 作为一种解决方法。
    • @Michael 那个链接好像失效了,还有别的吗?
    • 只是一个补充:如果你想强制 git diff 显示它,使用--no-ext-diff
    【解决方案3】:

    这种单线解决方案不需要其他工具/下载:

    git diff `git status -s |grep -v ^\ D |grep -v file/to/exclude.txt |cut -b4-`
    

    当然,file/to/exclude.txt 是您要排除的文件的名称。

    编辑:感谢 ksenzee 修复了破坏差异的已删除文件。

    【讨论】:

    • 我正在尝试将您的一个班轮调整为git diff --stat master,但没有取得多大成功-您能帮忙吗?
    【解决方案4】:

    类似于Ben Roux's 解决方案,但无论如何都要分享:

    git status --porcelain | grep -v $PATTERN_TO_EXCLUDE | awk '{print $2}' | xargs git diff
    

    或者,如果更改已在本地提交:

    git diff --name-only origin/master | grep -v $PATTERN_TO_EXCLUDE | xargs git diff origin/master
    

    例子:

    git status --porcelain | grep -v docs | awk '{print $2}' | xargs git diff origin/master
    
    git diff --name-only origin/master | grep -v docs | xargs git diff origin/master
    

    【讨论】:

      【解决方案5】:

      天哪,驱动程序和 awk 要排除一个糟糕的文件吗?由于git 1.9 something,您可以:

      git diff -- . ':(exclude)db/irrelevant.php' ':(exclude)db/irrelevant2.php'
      

      (在 Winodws 上,将单引号 ' 替换为双引号 "。)

      啊,优雅!请参阅@torek 引用的答案和详细信息this answer

      【讨论】:

      • 注意:如果要排除特定文件名,则必须以星号作为前缀,这与 .gitignore 文件语法不同。例如。 :!*shrinkwrap.yaml 而不是 :!shrinkwrap.yaml
      • 排除更多文件,例如我有 *.min.css 和 *.min.js 文件来避免 git diff。所以,我使用命令git diff -- . ':(exclude)*.min.js' ':(exclude)*.min.css'
      • windows 语法git diff -- . ":(exclude)db/irrelevant.php"(双引号代替单引号)
      • 谢谢!这么深奥的语法。。我每次都要查。
      • git diff -- . ':(exclude)package-lock.json' -- 对于(可能)非常常见的情况,这里是复制粘贴的命令行。
      【解决方案6】:

      此方法比接受的答案短。

      git diff 987200fbfb 878cee40ba -- ':!*.cs'
      

      有关不同包含/排除可能性的更多信息,请阅读this other post

      【讨论】:

      • 请注意,过滤器仅适用于当前目录下的所有文件。
      • 这是最好的答案。我可以简化一点:stackoverflow.com/a/58845608/3886183
      • 我会删除 --stat 部分,或者至少解释一下它的作用,因为其他答案都不包括它。
      • stat 标志向您显示文件及其差异总数,这使您可以轻松检查过滤器是否按照您的预期工作。
      • @mix3d 已删除 --stat,因为它与答案无关(并且可能具有误导性)。
      【解决方案7】:

      如果您只想直观地检查差异,可视化差异工具(如Meld)可以让您使用易于记忆的简短命令完成此操作。

      首先,如果您还没有设置差异工具。

      $ git config --global diff.tool = meld
      

      然后,您可以运行目录差异。

      $ git difftool --dir-diff
      

      您将能够在 Meld(或您选择的工具)中浏览差异(按文件)。只是不要打开你想忽略的文件。

      【讨论】:

        【解决方案8】:

        KurzedMetal 对我需要做的事情给出了非常好的回答,即能够看到文件已更改,但不能生成差异,就我而言,差异可能很大。

        但我的一位同事提出了一种更简单且对我有用的方法:

        git diff要忽略的文件所在目录添加.gitattributes文件,内容如下:

        file-not-to-diff.bin -diff

        这仍然让git status“查看”文件是否更改。 git diff 也会“看到”文件已更改,但不会生成 diff

        示例中文件的 .bin 扩展名是故意的。我确实意识到这是 git 对二进制文件的默认行为,它不需要对.gitattributes 进行特殊处理。但在我的情况下,这些文件被 git 和“文件”实用程序识别为文本文件,这就成功了。

        【讨论】:

        • 是的!这很整洁,它不会隐藏任何更改,但不会向您显示丑陋的*.min.js 文件等。这很好,最好的答案恕我直言。
        • 很棒的答案。简洁明了.. 赞
        • 正是我想要的!默认情况下,Windows 上的 Git 扩展会自动显示 .pdf 文件的差异,这通常非常耗时。这使我可以专门为 .pdf 禁用差异,但仍然可以轻松提交最新版本。
        【解决方案9】:

        很简单,你可以使用标准的unix命令排除你想要的东西,这些命令在git bash下甚至在windows环境下都可以使用。 下面的示例显示了如何排除 pom.xml 文件的差异,首先检查 diff to master 仅针对文件名,然后使用 'grep -v' 排除您不想要的文件,然后再次运行 diff to master 并使用准备好的列表:

        git diff master `git diff --name-only master | grep -v pom.xml`
        

        【讨论】:

          【解决方案10】:

          我执行以下操作:

          git add *pattern_to_exclude*
          git diff
          git reset HEAD .
          

          我知道这不是一个优雅的解决方案,并且有时无法使用(例如,如果您已经准备好东西),但它可以解决问题而无需输入复杂的命令

          【讨论】:

            【解决方案11】:

            相对于git根目录

            git diff 接受可选的排除

            git diff -- ":(exclude)thingToExclude"
            

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

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

            针对特定文件类型

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

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

            .bash_profile.zshrc

            gde() {
                # git diff exclude files or folders 
                # usage: 
                # gde fileOrFolderNameToExclude
                git diff -- ":(exclude)*/$1/*"
            }
            

            【讨论】:

            • 这对我不起作用,我完全没有差异,两种语法都使用(排除)或!。我有 git 2.21.0
            • 您可以 git diff 未暂存或暂存文件。如果你有 git 添加它们,它们就会上演。如果他们上演你可以做git diff --staged希望这对你有帮助。
            • 从语法上讲,冒号是做什么的?
            【解决方案12】:

            最简单的答案

            git diff ':!db/irrelevant.php'
            

            在你的 diff 命令之后只是':!<path to file>'。 diff 命令可以任意复杂,如果需要,您可以使用*.min.js 之类的通配符或添加多个排除项(用空格分隔引用的块)。

            【讨论】:

            • 谢谢!也适用于git log -p。如:git log -p ':!package-lock.json'
            【解决方案13】:

            在现有答案的基础上,如果您想排除文件模式,无论它在目录中的什么位置,请使用对应的 git pathspec**

            git diff -- ':!**/yarn.lock'
            

            【讨论】:

              【解决方案14】:
              git diff remote/master..master --name-only -- ':!README.rst'
              

              给我(git 版本 2.11.0)

              fatal: There is nothing to exclude from by :(exclude) patterns.
              Perhaps you forgot to add either ':/' or '.' ?
              
              git diff remote/master..master --name-only -- './*' ':!README.rst'
              

              工作得很好,来源:https://stackoverflow.com/a/30084612/5155484

              【讨论】:

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