33

I'm trying to adapt the answers from Exclude file from "git diff" for the --stat flag and failing. The accepted answer (create a driver) seems Unix-only (redirect to /bin/true, whatever this means), plus it creates a driver and assigns it to the file kind of permanently; while I am looking for a switch to temporarily disable the diff for a file (or rather some files).

The scripting solution:

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

actually calls git status and edits its output—while what I want is to instruct git diff itself to ignore some files while calculating the simple --stat (just lines changed). I went through the git-diff docs, but can't seem to find such an option. Anyone give me a hand ?

$ git --version
git version 2.6.1.windows.1
Michael
  • 8,362
  • 6
  • 61
  • 88
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361

1 Answers1

71

The exclude pathspec trick, described in Making 'git log' ignore changes for certain paths, works here:

git diff --stat -- . ':(exclude)file/to/exclude.txt'

or, if you are in a subdirectory:

git diff --stat -- :/ ':(exclude,top)file/to/exclude.txt'

The latter can be spelled in various ways. For instance, this also works:

git diff --stat ':(top)' :!/file/to/exclude.txt

as does:

git diff --stat :/: :!/:file/to/exclude.txt

These are described in the gitglossary documentation under the "pathspec" section. Note that the exclude feature is new in Git version 1.9 (and slightly broken until 1.9.2). The leading / is an alias for top and the ! is an alias for exclude, with the long forms requiring the parentheses. The trailing colon before the actual pathname is optional when using the single-character aliases but forbidden when using the parentheses (this rule trips me up every time—I keep wanting to use :(exclude):... rather than :(exclude)...). The single quotes around the (top) and (exclude) pathspec components above are to protect the parentheses from being interpreted by the (Unix/Linux) shells; the Windows shell may have different ideas about which characters need protection.

torek
  • 448,244
  • 59
  • 642
  • 775
  • You are my git hero! Worked for me in git bash shell (not the cmd or power shell, just the vanilla shell that comes with msysgit, based on mingwin methinks): `git diff --stat 307-first-commit -- :/ ':(exclude,top)Mopy/Docs' ':(exclude,top)Mopy/bash/images'`, with "307-first-commit " being a tag. This: `git diff --stat 307-first-commit :/: :!/Mopy/Docs` does not (prints "bash: !/Mopy/Docs: event not found"). This ` git diff --stat 307-first-commit :/: :!/:Mopy/Docs` also fails with "bash: !/: event not found" – Mr_and_Mrs_D Oct 09 '16 at 12:28
  • 3
    The `event not found` is because bash is trying to eat the `!` for its own purposes. Single quotes or a prefix backslash (but not double quotes) will protect the `!` from the shell. Note that shells in general also like to munch on quotes (which protect other characters), asterisks, question-marks, angle brackets, and square brackets, and some shells eat curly brackets as well. Single quotes are the "most powerful" quotes, quoting everything except single quotes. Double quotes are the "least powerful" but can quote single quotes. So `'!?<'"'"` passes four characters through! – torek Oct 09 '16 at 23:37
  • 1
    On windows, use double quotes instead of single quotes : `git diff --status -- . ":(exclude)file/to/exclude.txt"` – cnlevy Apr 12 '18 at 20:04
  • 1
    @misolo: yes, pathspecs are generic to `git diff`. – torek Nov 23 '20 at 14:09